Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
Comparing source compatibility of opentelemetry-sdk-trace-1.57.0-SNAPSHOT.jar against opentelemetry-sdk-trace-1.56.0.jar
No changes.
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setInternalTelemetryVersion(io.opentelemetry.sdk.common.InternalTelemetryVersion)
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) STATIC(+) io.opentelemetry.sdk.trace.export.SpanProcessorMetrics$LongCallable (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) long get()
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
import java.time.Duration;
Expand Down Expand Up @@ -49,6 +50,7 @@ static void configureTracerProvider(
List<Closeable> closeables) {

tracerProviderBuilder.setSpanLimits(configureSpanLimits(config));
SdkTracerProviderUtil.setMeterProvider(tracerProviderBuilder, meterProvider);

String sampler = config.getString("otel.traces.sampler", PARENTBASED_ALWAYS_ON);
tracerProviderBuilder.setSampler(
Expand Down Expand Up @@ -80,7 +82,10 @@ static List<SpanProcessor> configureSpanProcessors(
for (String simpleProcessorExporterNames : simpleProcessorExporterNames) {
SpanExporter exporter = exportersByNameCopy.remove(simpleProcessorExporterNames);
if (exporter != null) {
SpanProcessor spanProcessor = SimpleSpanProcessor.create(exporter);
SpanProcessor spanProcessor =
SdkTracerProviderUtil.setMeterProvider(
SimpleSpanProcessor.builder(exporter), meterProvider)
.build();
closeables.add(spanProcessor);
spanProcessors.add(spanProcessor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessorBuilder;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil;
import java.time.Duration;
import java.util.Map;

Expand Down Expand Up @@ -62,7 +64,12 @@ public SpanProcessor create(SpanProcessorModel model, DeclarativeConfigContext c
FileConfigUtil.requireNonNull(
simpleModel.getExporter(), "simple span processor exporter");
SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context);
return context.addCloseable(SimpleSpanProcessor.create(spanExporter));
SimpleSpanProcessorBuilder builder = SimpleSpanProcessor.builder(spanExporter);
MeterProvider meterProvider = context.getMeterProvider();
if (meterProvider != null) {
SdkTracerProviderUtil.setMeterProvider(builder, meterProvider);
}
return context.addCloseable(builder.build());
}

Map.Entry<String, Object> keyValue =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,8 @@ void create_Configured() throws NoSuchFieldException, IllegalAccessException {
.extracting("sharedState")
.extracting("activeSpanProcessor")
.extracting("worker")
.extracting("processedSpansCounter")
.extracting("spanProcessorMetrics")
.extracting("processedSpans")
.extracting("sdkMeter")
.extracting("meterProviderSharedState")
.isEqualTo(sharedState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ final class ExtendedSdkSpanBuilder extends SdkSpanBuilder implements ExtendedSpa
String spanName,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerSharedState tracerSharedState,
SpanLimits spanLimits) {
super(spanName, instrumentationScopeInfo, tracerSharedState, spanLimits);
SpanLimits spanLimits,
SdkTracerMetrics tracerProviderMetrics) {
super(spanName, instrumentationScopeInfo, tracerSharedState, spanLimits, tracerProviderMetrics);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ final class ExtendedSdkTracer extends SdkTracer implements ExtendedTracer {
ExtendedSdkTracer(
TracerSharedState sharedState,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerConfig tracerConfig) {
super(sharedState, instrumentationScopeInfo, tracerConfig);
TracerConfig tracerConfig,
SdkTracerMetrics tracerProviderMetrics) {
super(sharedState, instrumentationScopeInfo, tracerConfig, tracerProviderMetrics);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@ private IncubatingUtil() {}
static SdkTracer createExtendedTracer(
TracerSharedState sharedState,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerConfig tracerConfig) {
return new ExtendedSdkTracer(sharedState, instrumentationScopeInfo, tracerConfig);
TracerConfig tracerConfig,
SdkTracerMetrics tracerProviderMetrics) {
return new ExtendedSdkTracer(
sharedState, instrumentationScopeInfo, tracerConfig, tracerProviderMetrics);
}

static SdkSpanBuilder createExtendedSpanBuilder(
String spanName,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerSharedState tracerSharedState,
SpanLimits spanLimits) {
SpanLimits spanLimits,
SdkTracerMetrics tracerProviderMetrics) {
return new ExtendedSdkSpanBuilder(
spanName, instrumentationScopeInfo, tracerSharedState, spanLimits);
spanName, instrumentationScopeInfo, tracerSharedState, spanLimits, tracerProviderMetrics);
}
}
15 changes: 12 additions & 3 deletions sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ final class SdkSpan implements ReadWriteSpan {
private final InstrumentationScopeInfo instrumentationScopeInfo;
// The start time of the span.
private final long startEpochNanos;
// Callback to run when span ends.
private final Runnable onEnd;

// Lock used to internally guard the mutable state of this instance
private final Object lock = new Object();

Expand Down Expand Up @@ -132,7 +135,8 @@ private SdkSpan(
@Nullable AttributesMap attributes,
@Nullable List<LinkData> links,
int totalRecordedLinks,
long startEpochNanos) {
long startEpochNanos,
Runnable onEnd) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name did remind me of span processors, but it seemed we still need this in addition to them since the span metrics aren't tied to any specific processor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree - and it wouldn't be easy to add it to the active processor, as the runnable captures the sampling decision from start span.

Maybe it would be easier to follow when the variable would be named recordMetrics.

this.context = context;
this.instrumentationScopeInfo = instrumentationScopeInfo;
this.parentSpanContext = parentSpanContext;
Expand All @@ -148,6 +152,7 @@ private SdkSpan(
this.startEpochNanos = startEpochNanos;
this.attributes = attributes;
this.spanLimits = spanLimits;
this.onEnd = onEnd;
}

/**
Expand All @@ -163,6 +168,7 @@ private SdkSpan(
* @param resource the resource associated with this span.
* @param attributes the attributes set during span creation.
* @param links the links set during span creation, may be truncated. The list MUST be immutable.
* @param onEnd a {@link Runnable} to run when the span is ended.
* @return a new and started span.
*/
static SdkSpan startSpan(
Expand All @@ -180,7 +186,8 @@ static SdkSpan startSpan(
@Nullable AttributesMap attributes,
@Nullable List<LinkData> links,
int totalRecordedLinks,
long userStartEpochNanos) {
long userStartEpochNanos,
Runnable onEnd) {
boolean createdAnchoredClock;
AnchoredClock clock;
if (parentSpan instanceof SdkSpan) {
Expand Down Expand Up @@ -219,7 +226,8 @@ static SdkSpan startSpan(
attributes,
links,
totalRecordedLinks,
startEpochNanos);
startEpochNanos,
onEnd);
// Call onStart here instead of calling in the constructor to make sure the span is completely
// initialized.
if (spanProcessor.isStartRequired()) {
Expand Down Expand Up @@ -557,6 +565,7 @@ private void endInternal(long endEpochNanos) {
spanEndingThread = Thread.currentThread();
hasEnded = EndState.ENDING;
}
onEnd.run();
if (spanProcessor instanceof ExtendedSpanProcessor) {
ExtendedSpanProcessor extendedSpanProcessor = (ExtendedSpanProcessor) spanProcessor;
if (extendedSpanProcessor.isOnEndingRequired()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class SdkSpanBuilder implements SpanBuilder {
private final InstrumentationScopeInfo instrumentationScopeInfo;
private final TracerSharedState tracerSharedState;
private final SpanLimits spanLimits;
private final SdkTracerMetrics tracerProviderMetrics;

@Nullable private Context parent; // null means: Use current context.
private SpanKind spanKind = SpanKind.INTERNAL;
Expand All @@ -51,11 +52,13 @@ class SdkSpanBuilder implements SpanBuilder {
String spanName,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerSharedState tracerSharedState,
SpanLimits spanLimits) {
SpanLimits spanLimits,
SdkTracerMetrics tracerProviderMetrics) {
this.spanName = spanName;
this.instrumentationScopeInfo = instrumentationScopeInfo;
this.tracerSharedState = tracerSharedState;
this.spanLimits = spanLimits;
this.tracerProviderMetrics = tracerProviderMetrics;
}

@Override
Expand Down Expand Up @@ -204,6 +207,9 @@ public Span startSpan() {
/* remote= */ false,
tracerSharedState.isIdGeneratorSafeToSkipIdValidation());

Runnable recordEndSpanMetrics =
tracerProviderMetrics.startSpan(parentSpanContext, samplingDecision);

if (!isRecording(samplingDecision)) {
return Span.wrap(spanContext);
}
Expand Down Expand Up @@ -232,7 +238,8 @@ public Span startSpan() {
recordedAttributes,
currentLinks,
totalNumberOfLinksAdded,
startEpochNanos);
startEpochNanos,
recordEndSpanMetrics);
}

private AttributesMap attributes() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,30 @@ class SdkTracer implements Tracer {

private final TracerSharedState sharedState;
private final InstrumentationScopeInfo instrumentationScopeInfo;
private final SdkTracerMetrics tracerProviderMetrics;

protected volatile boolean tracerEnabled;

SdkTracer(
TracerSharedState sharedState,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerConfig tracerConfig) {
TracerConfig tracerConfig,
SdkTracerMetrics tracerProviderMetrics) {
this.sharedState = sharedState;
this.instrumentationScopeInfo = instrumentationScopeInfo;
this.tracerEnabled = tracerConfig.isEnabled();
this.tracerProviderMetrics = tracerProviderMetrics;
}

static SdkTracer create(
TracerSharedState sharedState,
InstrumentationScopeInfo instrumentationScopeInfo,
TracerConfig tracerConfig) {
TracerConfig tracerConfig,
SdkTracerMetrics tracerProviderMetrics) {
return INCUBATOR_AVAILABLE
? IncubatingUtil.createExtendedTracer(sharedState, instrumentationScopeInfo, tracerConfig)
: new SdkTracer(sharedState, instrumentationScopeInfo, tracerConfig);
? IncubatingUtil.createExtendedTracer(
sharedState, instrumentationScopeInfo, tracerConfig, tracerProviderMetrics)
: new SdkTracer(sharedState, instrumentationScopeInfo, tracerConfig, tracerProviderMetrics);
}

/**
Expand All @@ -68,9 +73,17 @@ public SpanBuilder spanBuilder(String spanName) {
}
return INCUBATOR_AVAILABLE
? IncubatingUtil.createExtendedSpanBuilder(
spanName, instrumentationScopeInfo, sharedState, sharedState.getSpanLimits())
spanName,
instrumentationScopeInfo,
sharedState,
sharedState.getSpanLimits(),
tracerProviderMetrics)
: new SdkSpanBuilder(
spanName, instrumentationScopeInfo, sharedState, sharedState.getSpanLimits());
spanName,
instrumentationScopeInfo,
sharedState,
sharedState.getSpanLimits(),
tracerProviderMetrics);
}

// Visible for testing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.trace;

import static io.opentelemetry.api.common.AttributeKey.stringKey;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;

/**
* SDK metrics exported for started and ended spans as defined in the <a
* href="https://opentelemetry.io/docs/specs/semconv/otel/sdk-metrics/#span-metrics">semantic
* conventions</a>.
*/
final class SdkTracerMetrics {

// Visible for testing
static final AttributeKey<String> OTEL_SPAN_PARENT_ORIGIN = stringKey("otel.span.parent.origin");
// Visible for testing
static final AttributeKey<String> OTEL_SPAN_SAMPLING_RESULT =
stringKey("otel.span.sampling_result");

private final LongCounter startedSpans;
private final LongUpDownCounter liveSpans;

SdkTracerMetrics(MeterProvider meterProvider) {
Meter meter = meterProvider.get("io.opentelemetry.sdk.trace");

startedSpans =
meter
.counterBuilder("otel.sdk.span.started")
.setUnit("{span}")
.setDescription("The number of created spans.")
.build();
liveSpans =
meter
.upDownCounterBuilder("otel.sdk.span.live")
.setUnit("{span}")
.setDescription(
"The number of created spans with recording=true for which the end operation has not been called yet.")
.build();
}

/**
* Records metrics for when a span starts and returns a {@link Runnable} to execute when ending
* the span.
*/
Runnable startSpan(SpanContext parentSpanContext, SamplingDecision samplingDecision) {
startedSpans.add(
1,
Attributes.of(
OTEL_SPAN_PARENT_ORIGIN,
parentOrigin(parentSpanContext),
OTEL_SPAN_SAMPLING_RESULT,
samplingDecision.name()));

if (samplingDecision == SamplingDecision.DROP) {
return () -> {};
}

Attributes liveSpansAttributes =
Attributes.of(OTEL_SPAN_SAMPLING_RESULT, samplingDecision.name());
liveSpans.add(1, liveSpansAttributes);
return () -> liveSpans.add(-1, liveSpansAttributes);
}

private static String parentOrigin(SpanContext parentSpanContext) {
if (!parentSpanContext.isValid()) {
return "none";
}
if (parentSpanContext.isRemote()) {
return "remote";
}
return "local";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.sdk.trace;

import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.TracerBuilder;
import io.opentelemetry.api.trace.TracerProvider;
Expand Down Expand Up @@ -54,7 +55,9 @@ public static SdkTracerProviderBuilder builder() {
Sampler sampler,
List<SpanProcessor> spanProcessors,
ScopeConfigurator<TracerConfig> tracerConfigurator,
ExceptionAttributeResolver exceptionAttributeResolver) {
ExceptionAttributeResolver exceptionAttributeResolver,
MeterProvider meterProvider) {
SdkTracerMetrics tracerProviderMetrics = new SdkTracerMetrics(meterProvider);
this.sharedState =
new TracerSharedState(
clock,
Expand All @@ -70,7 +73,8 @@ public static SdkTracerProviderBuilder builder() {
SdkTracer.create(
sharedState,
instrumentationScopeInfo,
getTracerConfig(instrumentationScopeInfo)));
getTracerConfig(instrumentationScopeInfo),
tracerProviderMetrics));
this.tracerConfigurator = tracerConfigurator;
}

Expand Down
Loading
Loading