Skip to content

Commit 5f90b03

Browse files
authored
Fix span setStatus (#6990)
1 parent d3e3807 commit 5f90b03

File tree

2 files changed

+76
-9
lines changed

2 files changed

+76
-9
lines changed

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,26 @@ public ReadWriteSpan setStatus(StatusCode statusCode, @Nullable String descripti
434434
if (!isModifiableByCurrentThread()) {
435435
logger.log(Level.FINE, "Calling setStatus() on an ended Span.");
436436
return this;
437-
} else if (this.status.getStatusCode() == StatusCode.OK) {
437+
}
438+
439+
// If current status is OK, ignore further attempts to change it
440+
if (this.status.getStatusCode() == StatusCode.OK) {
438441
logger.log(Level.FINE, "Calling setStatus() on a Span that is already set to OK.");
439442
return this;
440443
}
444+
445+
// Ignore attempts to set status to UNSET
446+
if (statusCode == StatusCode.UNSET) {
447+
logger.log(Level.FINE, "Ignoring call to setStatus() with status UNSET.");
448+
return this;
449+
}
450+
451+
// Ignore description when status is not ERROR
452+
if (description != null && statusCode != StatusCode.ERROR) {
453+
logger.log(Level.FINE, "Ignoring setStatus() description since status is not ERROR.");
454+
description = null;
455+
}
456+
441457
this.status = StatusData.create(statusCode, description);
442458
}
443459
return this;

sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java

+59-8
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,16 @@
6363
import java.util.concurrent.TimeUnit;
6464
import java.util.concurrent.atomic.AtomicBoolean;
6565
import java.util.concurrent.atomic.AtomicLong;
66+
import java.util.function.Consumer;
6667
import java.util.stream.IntStream;
68+
import java.util.stream.Stream;
6769
import javax.annotation.Nullable;
6870
import org.junit.jupiter.api.BeforeEach;
6971
import org.junit.jupiter.api.Test;
7072
import org.junit.jupiter.api.extension.ExtendWith;
73+
import org.junit.jupiter.params.ParameterizedTest;
74+
import org.junit.jupiter.params.provider.Arguments;
75+
import org.junit.jupiter.params.provider.MethodSource;
7176
import org.mockito.Mock;
7277
import org.mockito.Mockito;
7378
import org.mockito.junit.jupiter.MockitoExtension;
@@ -1336,15 +1341,61 @@ void onStartOnEndNotRequired() {
13361341
verify(spanProcessor, never()).onEnd(any());
13371342
}
13381343

1339-
@Test
1340-
void setStatusCannotOverrideStatusOK() {
1344+
@ParameterizedTest
1345+
@MethodSource("setStatusArgs")
1346+
void setStatus(Consumer<Span> spanConsumer, StatusData expectedSpanData) {
13411347
SdkSpan testSpan = createTestRootSpan();
1342-
testSpan.setStatus(StatusCode.OK);
1343-
assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK);
1344-
testSpan.setStatus(StatusCode.ERROR);
1345-
assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK);
1346-
testSpan.setStatus(StatusCode.UNSET);
1347-
assertThat(testSpan.toSpanData().getStatus().getStatusCode()).isEqualTo(StatusCode.OK);
1348+
spanConsumer.accept(testSpan);
1349+
assertThat(testSpan.toSpanData().getStatus()).isEqualTo(expectedSpanData);
1350+
}
1351+
1352+
private static Stream<Arguments> setStatusArgs() {
1353+
return Stream.of(
1354+
// Default status is UNSET
1355+
Arguments.of(spanConsumer(span -> {}), StatusData.unset()),
1356+
// Simple cases
1357+
Arguments.of(spanConsumer(span -> span.setStatus(StatusCode.OK)), StatusData.ok()),
1358+
Arguments.of(spanConsumer(span -> span.setStatus(StatusCode.ERROR)), StatusData.error()),
1359+
// UNSET is ignored
1360+
Arguments.of(
1361+
spanConsumer(span -> span.setStatus(StatusCode.OK).setStatus(StatusCode.UNSET)),
1362+
StatusData.ok()),
1363+
Arguments.of(
1364+
spanConsumer(span -> span.setStatus(StatusCode.ERROR).setStatus(StatusCode.UNSET)),
1365+
StatusData.error()),
1366+
// Description is ignored unless status is ERROR
1367+
Arguments.of(
1368+
spanConsumer(span -> span.setStatus(StatusCode.UNSET, "description")),
1369+
StatusData.unset()),
1370+
Arguments.of(
1371+
spanConsumer(span -> span.setStatus(StatusCode.OK, "description")), StatusData.ok()),
1372+
Arguments.of(
1373+
spanConsumer(span -> span.setStatus(StatusCode.ERROR, "description")),
1374+
StatusData.create(StatusCode.ERROR, "description")),
1375+
// ERROR is ignored if status is OK
1376+
Arguments.of(
1377+
spanConsumer(
1378+
span -> span.setStatus(StatusCode.OK).setStatus(StatusCode.ERROR, "description")),
1379+
StatusData.ok()),
1380+
// setStatus ignored after span is ended
1381+
Arguments.of(
1382+
spanConsumer(
1383+
span -> {
1384+
span.end();
1385+
span.setStatus(StatusCode.OK);
1386+
}),
1387+
StatusData.unset()),
1388+
Arguments.of(
1389+
spanConsumer(
1390+
span -> {
1391+
span.end();
1392+
span.setStatus(StatusCode.ERROR);
1393+
}),
1394+
StatusData.unset()));
1395+
}
1396+
1397+
private static Consumer<Span> spanConsumer(Consumer<Span> spanConsumer) {
1398+
return spanConsumer;
13481399
}
13491400

13501401
private SdkSpan createTestSpanWithAttributes(Map<AttributeKey, Object> attributes) {

0 commit comments

Comments
 (0)