Skip to content

Commit 452506e

Browse files
authored
Implement SDK metrics for trace (#7895)
1 parent 1b5cb49 commit 452506e

File tree

22 files changed

+1657
-75
lines changed

22 files changed

+1657
-75
lines changed
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
11
Comparing source compatibility of opentelemetry-sdk-trace-1.58.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.57.0.jar
2-
No changes.
2+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable)
3+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
4+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setInternalTelemetryVersion(io.opentelemetry.sdk.common.InternalTelemetryVersion)
5+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setMeterProvider(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
6+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder (not serializable)
7+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
8+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder setMeterProvider(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
9+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.SdkTracerProviderBuilder (not serializable)
10+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
11+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.SdkTracerProviderBuilder setMeterProvider(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static void configureTracerProvider(
4949
List<Closeable> closeables) {
5050

5151
tracerProviderBuilder.setSpanLimits(configureSpanLimits(config));
52+
tracerProviderBuilder.setMeterProvider(() -> meterProvider);
5253

5354
String sampler = config.getString("otel.traces.sampler", PARENTBASED_ALWAYS_ON);
5455
tracerProviderBuilder.setSampler(
@@ -80,7 +81,8 @@ static List<SpanProcessor> configureSpanProcessors(
8081
for (String simpleProcessorExporterNames : simpleProcessorExporterNames) {
8182
SpanExporter exporter = exportersByNameCopy.remove(simpleProcessorExporterNames);
8283
if (exporter != null) {
83-
SpanProcessor spanProcessor = SimpleSpanProcessor.create(exporter);
84+
SpanProcessor spanProcessor =
85+
SimpleSpanProcessor.builder(exporter).setMeterProvider(() -> meterProvider).build();
8486
closeables.add(spanProcessor);
8587
spanProcessors.add(spanProcessor);
8688
}
@@ -101,7 +103,7 @@ static List<SpanProcessor> configureSpanProcessors(
101103
static BatchSpanProcessor configureBatchSpanProcessor(
102104
ConfigProperties config, SpanExporter exporter, MeterProvider meterProvider) {
103105
BatchSpanProcessorBuilder builder =
104-
BatchSpanProcessor.builder(exporter).setMeterProvider(meterProvider);
106+
BatchSpanProcessor.builder(exporter).setMeterProvider(() -> meterProvider);
105107

106108
Duration scheduleDelay = config.getDuration("otel.bsp.schedule.delay");
107109
if (scheduleDelay != null) {

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
1515
import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder;
1616
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
17+
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder;
1718
import io.opentelemetry.sdk.trace.export.SpanExporter;
1819
import java.time.Duration;
1920
import java.util.Map;
@@ -50,7 +51,7 @@ public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext c
5051
}
5152
MeterProvider meterProvider = context.getMeterProvider();
5253
if (meterProvider != null) {
53-
builder.setMeterProvider(meterProvider);
54+
builder.setMeterProvider(() -> meterProvider);
5455
}
5556

5657
return context.addCloseable(builder.build());
@@ -62,7 +63,12 @@ public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext c
6263
FileConfigUtil.requireNonNull(
6364
simpleModel.getExporter(), "simple span processor exporter");
6465
SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context);
65-
return context.addCloseable(SimpleSpanProcessor.create(spanExporter));
66+
SimpleSpanProcessorBuilder builder = SimpleSpanProcessor.builder(spanExporter);
67+
MeterProvider meterProvider = context.getMeterProvider();
68+
if (meterProvider != null) {
69+
builder.setMeterProvider(() -> meterProvider);
70+
}
71+
return context.addCloseable(builder.build());
6672
}
6773

6874
Map.Entry<String, Object> keyValue =

sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,15 @@ void create_Configured() throws NoSuchFieldException, IllegalAccessException {
337337
.extracting("meterProviderSharedState")
338338
.isEqualTo(sharedState);
339339

340+
// Lazily initialized
340341
assertThat(sdk)
341342
.extracting("tracerProvider")
342343
.extracting("delegate")
343344
.extracting("sharedState")
344345
.extracting("activeSpanProcessor")
345346
.extracting("worker")
346-
.extracting("processedSpansCounter")
347-
.extracting("sdkMeter")
348-
.extracting("meterProviderSharedState")
349-
.isEqualTo(sharedState);
347+
.extracting("spanProcessorInstrumentation")
348+
.extracting("processedSpans")
349+
.isNull();
350350
}
351351
}

sdk/common/src/main/java/io/opentelemetry/sdk/internal/SemConvAttributes.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ private SemConvAttributes() {}
3333
AttributeKey.longKey("rpc.grpc.status_code");
3434
public static final AttributeKey<Long> HTTP_RESPONSE_STATUS_CODE =
3535
AttributeKey.longKey("http.response.status_code");
36+
37+
public static final AttributeKey<String> OTEL_SPAN_PARENT_ORIGIN =
38+
AttributeKey.stringKey("otel.span.parent.origin");
39+
public static final AttributeKey<String> OTEL_SPAN_SAMPLING_RESULT =
40+
AttributeKey.stringKey("otel.span.sampling_result");
3641
}

sdk/common/src/test/java/io/opentelemetry/sdk/internal/SemConvAttributesTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,10 @@ void testAttributeKeys() {
3131
.isEqualTo(RpcIncubatingAttributes.RPC_GRPC_STATUS_CODE);
3232
assertThat(SemConvAttributes.HTTP_RESPONSE_STATUS_CODE)
3333
.isEqualTo(HttpAttributes.HTTP_RESPONSE_STATUS_CODE);
34+
35+
assertThat(SemConvAttributes.OTEL_SPAN_PARENT_ORIGIN)
36+
.isEqualTo(OtelIncubatingAttributes.OTEL_SPAN_PARENT_ORIGIN);
37+
assertThat(SemConvAttributes.OTEL_SPAN_SAMPLING_RESULT)
38+
.isEqualTo(OtelIncubatingAttributes.OTEL_SPAN_SAMPLING_RESULT);
3439
}
3540
}

sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ final class SdkSpan implements ReadWriteSpan {
6161
private final InstrumentationScopeInfo instrumentationScopeInfo;
6262
// The start time of the span.
6363
private final long startEpochNanos;
64+
// Callback to run when span ends to record metrics.
65+
private final Runnable recordEndMetrics;
66+
6467
// Lock used to internally guard the mutable state of this instance
6568
private final Object lock = new Object();
6669

@@ -132,7 +135,8 @@ private SdkSpan(
132135
@Nullable AttributesMap attributes,
133136
@Nullable List<LinkData> links,
134137
int totalRecordedLinks,
135-
long startEpochNanos) {
138+
long startEpochNanos,
139+
Runnable recordEndMetrics) {
136140
this.context = context;
137141
this.instrumentationScopeInfo = instrumentationScopeInfo;
138142
this.parentSpanContext = parentSpanContext;
@@ -148,6 +152,7 @@ private SdkSpan(
148152
this.startEpochNanos = startEpochNanos;
149153
this.attributes = attributes;
150154
this.spanLimits = spanLimits;
155+
this.recordEndMetrics = recordEndMetrics;
151156
}
152157

153158
/**
@@ -163,6 +168,7 @@ private SdkSpan(
163168
* @param resource the resource associated with this span.
164169
* @param attributes the attributes set during span creation.
165170
* @param links the links set during span creation, may be truncated. The list MUST be immutable.
171+
* @param recordEndMetrics a {@link Runnable} to run when the span is ended to record metrics.
166172
* @return a new and started span.
167173
*/
168174
static SdkSpan startSpan(
@@ -180,7 +186,8 @@ static SdkSpan startSpan(
180186
@Nullable AttributesMap attributes,
181187
@Nullable List<LinkData> links,
182188
int totalRecordedLinks,
183-
long userStartEpochNanos) {
189+
long userStartEpochNanos,
190+
Runnable recordEndMetrics) {
184191
boolean createdAnchoredClock;
185192
AnchoredClock clock;
186193
if (parentSpan instanceof SdkSpan) {
@@ -219,7 +226,8 @@ static SdkSpan startSpan(
219226
attributes,
220227
links,
221228
totalRecordedLinks,
222-
startEpochNanos);
229+
startEpochNanos,
230+
recordEndMetrics);
223231
// Call onStart here instead of calling in the constructor to make sure the span is completely
224232
// initialized.
225233
if (spanProcessor.isStartRequired()) {
@@ -557,6 +565,7 @@ private void endInternal(long endEpochNanos) {
557565
spanEndingThread = Thread.currentThread();
558566
hasEnded = EndState.ENDING;
559567
}
568+
recordEndMetrics.run();
560569
if (spanProcessor instanceof ExtendedSpanProcessor) {
561570
ExtendedSpanProcessor extendedSpanProcessor = (ExtendedSpanProcessor) spanProcessor;
562571
if (extendedSpanProcessor.isOnEndingRequired()) {

sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpanBuilder.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ public Span startSpan() {
204204
/* remote= */ false,
205205
tracerSharedState.isIdGeneratorSafeToSkipIdValidation());
206206

207+
Runnable recordEndSpanMetrics =
208+
tracerSharedState.getTracerMetrics().startSpan(parentSpanContext, samplingDecision);
209+
207210
if (!isRecording(samplingDecision)) {
208211
return Span.wrap(spanContext);
209212
}
@@ -232,7 +235,8 @@ public Span startSpan() {
232235
recordedAttributes,
233236
currentLinks,
234237
totalNumberOfLinksAdded,
235-
startEpochNanos);
238+
startEpochNanos,
239+
recordEndSpanMetrics);
236240
}
237241

238242
private AttributesMap attributes() {

0 commit comments

Comments
 (0)