diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index a00b575998d..9a1ac25d49a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -76,4 +76,4 @@ java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } -} +} \ No newline at end of file diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java index 0d2c9ab83fd..ef1ba2c3c86 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java @@ -428,17 +428,38 @@ private void addTimedEvent(EventData timedEvent) { @Override public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String description) { if (statusCode == null) { - return this; + return this; // No action if statusCode is null } synchronized (lock) { if (!isModifiableByCurrentThread()) { logger.log(Level.FINE, "Calling setStatus() on an ended Span."); return this; - } else if (this.status.getStatusCode() == StatusCode.OK) { + } +<<<<<<< HEAD + +======= + +>>>>>>> d9e11e8e4aebfe44bc79436b8e7ee42344e4a5aa + StatusCode currentStatusCode = this.status.getStatusCode(); + + // Prevent setting a lower priority status. + if (currentStatusCode == StatusCode.OK) { logger.log(Level.FINE, "Calling setStatus() on a Span that is already set to OK."); - return this; + return this; // Do not allow lower priority status to override OK + } if (currentStatusCode == StatusCode.ERROR && statusCode == StatusCode.UNSET) { + logger.log(Level.FINE, "Cannot set status to UNSET when current status is ERROR."); + return this; // Do not allow UNSET to override ERROR + } + + // Set the status, ignoring description if status is not ERROR. + if (statusCode == StatusCode.ERROR) { + this.status = StatusData.create(statusCode, description); + } else { + if (currentStatusCode != statusCode) { + this.status = + StatusData.create(statusCode, null); + } } - this.status = StatusData.create(statusCode, description); } return this; } diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java index 7fbd86ef229..a5fad854241 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java @@ -119,11 +119,25 @@ void setUp() { @Test void nothingChangedAfterEnd() { SdkSpan span = createTestSpan(SpanKind.INTERNAL); + + // Set an initial status before ending the span + span.setStatus(StatusCode.OK, "Initial status"); + assertThat(span.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK); + + // End the span span.end(); - // Check that adding trace events or update fields after Span#end() does not throw any thrown + + // Store the current status for verification + StatusData currentStatus = span.toSpanData().getStatus(); + + // Check that adding trace events or update fields after Span#end() does not throw any exception // and are ignored. spanDoWork(span, StatusCode.ERROR, "CANCELLED"); + + // Verify that the status has not changed after the span has ended SpanData spanData = span.toSpanData(); + assertThat(spanData.getStatus()).isEqualTo(currentStatus); + verifySpanData( spanData, Attributes.empty(), @@ -1432,6 +1446,29 @@ private void verifySpanData( spanDataAttributes.forEach((key, value) -> assertThat(attributes.get(key)).isEqualTo(value)); } + + @Test +void setStatusCannotOverrideStatusError() { + SdkSpan testSpan = createTestRootSpan(); + + // Set an initial status to ERROR + testSpan.setStatus(StatusCode.ERROR, "Initial error status"); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.ERROR); + + // Attempt to set status to OK (should not change) + testSpan.setStatus(StatusCode.OK); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.ERROR); + + // Attempt to set status to UNSET (should not change) + testSpan.setStatus(StatusCode.UNSET); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.ERROR); + + // Attempt to set status to ERROR again (should remain ERROR) + testSpan.setStatus(StatusCode.ERROR, "Another error status"); + assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.ERROR); +} + + @Test void testAsSpanData() { String name = "GreatSpan";