From 5c886255671ea4a41aeccba5fea8ba5001dfd40c Mon Sep 17 00:00:00 2001 From: Weian Deng Date: Sun, 16 Mar 2025 19:12:33 -0700 Subject: [PATCH] #13295: Instrumenter.getNanos() returns non-epoch timestamp. --- .../api/instrumenter/Instrumenter.java | 2 +- .../api/instrumenter/InstrumenterTest.java | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java index a51990317067..bbe02ba4d37e 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java @@ -266,7 +266,7 @@ private void doEnd( private static long getNanos(@Nullable Instant time) { if (time == null) { - return System.nanoTime(); + time = Instant.now(); } return TimeUnit.SECONDS.toNanos(time.getEpochSecond()) + time.getNano(); } diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java index fb9ae8622d8d..9b7558a23294 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterTest.java @@ -25,6 +25,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextKey; import io.opentelemetry.context.propagation.TextMapGetter; +import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil; import io.opentelemetry.instrumentation.api.internal.SchemaUrlProvider; import io.opentelemetry.instrumentation.api.internal.SpanKey; import io.opentelemetry.instrumentation.api.internal.SpanKeyProvider; @@ -32,6 +33,7 @@ import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; import io.opentelemetry.sdk.trace.data.LinkData; import io.opentelemetry.sdk.trace.data.StatusData; +import java.time.Instant; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -39,6 +41,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; @@ -581,6 +584,45 @@ void instrumentationVersion_default() { span -> span.hasName("span").hasInstrumentationScopeInfo(expectedLibraryInfo))); } + @Test + void instrumenterGetNanosWithNullArgument() { + AtomicReference endTime = new AtomicReference<>(); + OperationListener operationListener = + new OperationListener() { + @Override + public Context onStart(Context context, Attributes startAttributes, long startNanos) { + return context; + } + + @Override + public void onEnd(Context context, Attributes endAttributes, long endNanos) { + endTime.set(endNanos); + } + }; + + InstrumenterBuilder, Map> builder = + Instrumenter.builder( + otelTesting.getOpenTelemetry(), "test-instrumentation", name -> "span"); + builder.addOperationListener(operationListener); + InstrumenterUtil.propagateOperationListenersToOnEnd(builder); + + Instant startTime = Instant.now(); + Instrumenter, Map> instrumenter = + builder.buildInstrumenter(); + InstrumenterUtil.startAndEnd( + instrumenter, Context.root(), emptyMap(), emptyMap(), null, startTime, null); + + otelTesting + .assertTraces() + .hasTracesSatisfyingExactly( + trace -> + trace.hasSpansSatisfyingExactly(span -> span.hasName("span").startsAt(startTime))); + System.out.printf( + "Epoche second of start: %d and end: %d\n", + startTime.getEpochSecond(), endTime.get() / 1_000_000_000); + Assertions.assertThat(endTime.get() / 1_000_000_000 == startTime.getEpochSecond()).isTrue(); + } + @Test void instrumentationVersion_custom() { Instrumenter, Map> instrumenter =