Skip to content

Commit f883cde

Browse files
committed
Add support for JFR contextual information
Fixes #2057
1 parent 42fea9d commit f883cde

File tree

5 files changed

+51
-4
lines changed

5 files changed

+51
-4
lines changed

jfr-events/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ Create JFR events that can be recorded and viewed in Java Mission Control (JMC).
55
* Creates Open Telemetry Tracing/Span events for spans
66
* The thread and stacktrace will be of the thead ending the span which might be different from the thread creating the span.
77
* Has the fields
8-
* Operation Name
8+
* Operation Name (`@Contextual`)
99
* Trace ID
1010
* Parent Span ID
1111
* Span ID
1212
* Creates Open Telemetry Tracing/Scope events for scopes
1313
* Thread will match the thread the scope was active in and the stacktrace will be when scope was closed
1414
* Multiple scopes might be collected for a single span
1515
* Has the fields
16-
* Trace ID
16+
* Trace ID (`@Contextual`)
1717
* Span ID
1818
* Supports the Open Source version of JFR in Java 11.
1919
* Might support back port to OpenJDK 8, but not tested and classes are built with JDK 11 bytecode.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.jfrevent;
7+
8+
import java.lang.annotation.ElementType;
9+
import java.lang.annotation.Retention;
10+
import java.lang.annotation.RetentionPolicy;
11+
import java.lang.annotation.Target;
12+
import jdk.jfr.Label;
13+
import jdk.jfr.MetadataDefinition;
14+
import jdk.jfr.Name;
15+
16+
/**
17+
* Meta-annotation to support @Contextual without compiling against JDK 25.
18+
*
19+
* @see <a href="https://bugs.openjdk.org/browse/JDK-8356699">JDK-8356699</a>
20+
*/
21+
@MetadataDefinition
22+
@Label("Context")
23+
@Retention(RetentionPolicy.RUNTIME)
24+
@Target({ElementType.FIELD})
25+
@Name("jdk.jfr.Contextual")
26+
@interface Contextual {}

jfr-events/src/main/java/io/opentelemetry/contrib/jfrevent/ScopeEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
+ "in scope/active on this thread.")
2121
class ScopeEvent extends Event {
2222

23-
private final String traceId;
23+
@Contextual private final String traceId;
2424
private final String spanId;
2525

2626
ScopeEvent(SpanContext spanContext) {

jfr-events/src/main/java/io/opentelemetry/contrib/jfrevent/SpanEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
@Description("Open Telemetry trace event corresponding to a span.")
1919
class SpanEvent extends Event {
2020

21-
private final String operationName;
21+
@Contextual private final String operationName;
2222
private final String traceId;
2323
private final String spanId;
2424
private final String parentId;

jfr-events/src/test/java/io/opentelemetry/contrib/jfrevent/JfrSpanProcessorTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import java.nio.file.Files;
1717
import java.nio.file.Path;
1818
import java.util.List;
19+
import java.util.Objects;
20+
import java.util.stream.Collectors;
1921
import jdk.jfr.Recording;
2022
import jdk.jfr.consumer.RecordedEvent;
2123
import jdk.jfr.consumer.RecordingFile;
@@ -77,6 +79,15 @@ void basicSpan() throws IOException {
7779
.extracting(e -> e.getValue("spanId"))
7880
.isEqualTo(span.getSpanContext().getSpanId());
7981
assertThat(events).extracting(e -> e.getValue("operationName")).isEqualTo(OPERATION_NAME);
82+
assertThat(events)
83+
.extracting(
84+
e ->
85+
e.getFields().stream()
86+
.filter(f -> f.getName().equals("operationName"))
87+
.map(d -> d.getAnnotation(Contextual.class))
88+
.filter(Objects::nonNull)
89+
.collect(Collectors.toList()))
90+
.isNotEmpty();
8091
} finally {
8192
Files.delete(output);
8293
}
@@ -119,6 +130,16 @@ void basicSpanWithScope() throws IOException, InterruptedException {
119130
.filteredOn(e -> "Span".equals(e.getEventType().getLabel()))
120131
.extracting(e -> e.getValue("operationName"))
121132
.isEqualTo(OPERATION_NAME);
133+
assertThat(events)
134+
.filteredOn(e -> "Scope".equals(e.getEventType().getLabel()))
135+
.extracting(
136+
e ->
137+
e.getFields().stream()
138+
.filter(f -> f.getName().equals("traceId"))
139+
.map(d -> d.getAnnotation(Contextual.class))
140+
.filter(Objects::nonNull)
141+
.collect(Collectors.toList()))
142+
.isNotEmpty();
122143

123144
} finally {
124145
Files.delete(output);

0 commit comments

Comments
 (0)