Skip to content
Merged
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
Expand Up @@ -79,7 +79,7 @@ tasks {
withType<JavaCompile>().configureEach {
options.errorprone {
disableWarningsInGeneratedCode.set(true)
disable("Slf4jLoggerShouldBeNonStatic")
disable("Slf4jLoggerShouldBeNonStatic", "BooleanLiteral")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package io.github.mfvanek.spring.boot3.kotlin.test

import io.github.mfvanek.spring.boot3.kotlin.test.support.TestBase
import io.micrometer.tracing.Tracer
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired

internal class NewTraceIdTest : TestBase() {

@Autowired
private lateinit var tracer: Tracer

@Suppress("NestedBlockDepth")
@DisplayName("Demonstration of how to create a new traceId using the span API")
@Test
fun canCreateNewTraceIdViaSpan() {
val firstSpan = tracer.startScopedSpan("first")
try {
val previousTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(previousTraceId)
.isEqualTo(firstSpan.context().traceId())

tracer.withSpan(null).use {
val newSpan = tracer.nextSpan().name("new")
try {
tracer.withSpan(newSpan.start()).use {
val newTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(newTraceId)
.isNotEqualTo(previousTraceId)
}
} catch (e: Exception) {
newSpan.error(e)
throw e
} finally {
newSpan.end()
}
}

val lastTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(lastTraceId)
.isEqualTo(previousTraceId)
} catch (e: Exception) {
firstSpan.error(e)
throw e
} finally {
firstSpan.end()
}
}

@DisplayName("Demonstration of creating a new traceId using the API traceContext")
@Test
@Suppress("NestedBlockDepth")
fun canCreateNewTraceIdViaContext() {
val firstSpan = tracer.startScopedSpan("first")
try {
val previousTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(previousTraceId)
.isEqualTo(firstSpan.context().traceId())

tracer.withSpan(null).use {
val newSpan = tracer.nextSpan()
val traceContext = tracer.traceContextBuilder()
.traceId(newSpan.context().traceId())
.spanId(newSpan.context().spanId())
.sampled(true) // Important!
.build()
tracer.currentTraceContext().newScope(
traceContext
).use { // Scope from newScope must be closed
val newTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(newTraceId)
.isNotEqualTo(previousTraceId)
}
}

val lastTraceId = tracer.currentSpan()?.context()?.traceId()
assertThat(lastTraceId)
.isEqualTo(previousTraceId)
} catch (e: Exception) {
firstSpan.error(e)
throw e
} finally {
firstSpan.end()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2020-2025. Ivan Vakhrushev and others.
* https://github.com/mfvanek/spring-boot-open-telemetry-demo
*
* Licensed under the Apache License 2.0
*/

package io.github.mfvanek.spring.boot3.test;

import io.github.mfvanek.spring.boot3.test.support.TestBase;
import io.micrometer.tracing.CurrentTraceContext;
import io.micrometer.tracing.ScopedSpan;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.TraceContext;
import io.micrometer.tracing.Tracer;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

@SuppressWarnings({"PMD.AvoidCatchingThrowable", "PMD.ExceptionAsFlowControl", "checkstyle:NestedTryDepth", "checkstyle:IllegalCatch"})
class NewTraceIdTest extends TestBase {

@Autowired
private Tracer tracer;

@Test
@DisplayName("Demonstration of how to create a new traceId using the span API")
void canCreateNewTraceIdViaSpan() {
final ScopedSpan firstSpan = tracer.startScopedSpan("first");
try {
final String previousTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(previousTraceId)
.isEqualTo(firstSpan.context().traceId());

try (Tracer.SpanInScope ignored = tracer.withSpan(null)) {
final Span newSpan = tracer.nextSpan().name("new");
try (Tracer.SpanInScope ignored2 = tracer.withSpan(newSpan.start())) {
final String newTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(newTraceId)
.isNotEqualTo(previousTraceId);
} catch (Throwable e) {
newSpan.error(e);
throw e;
} finally {
newSpan.end();
}
}

final String lastTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(lastTraceId)
.isEqualTo(previousTraceId);
} catch (Throwable e) {
firstSpan.error(e);
throw e;
} finally {
firstSpan.end();
}
}

@Test
@DisplayName("Demonstration of creating a new traceId using the API traceContext")
void canCreateNewTraceIdViaContext() {
final ScopedSpan firstSpan = tracer.startScopedSpan("first");
try {
final String previousTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(previousTraceId)
.isEqualTo(firstSpan.context().traceId());

try (Tracer.SpanInScope ignored = tracer.withSpan(null)) {
final Span newSpan = tracer.nextSpan();
final TraceContext traceContext = tracer.traceContextBuilder()
.traceId(newSpan.context().traceId())
.spanId(newSpan.context().spanId())
.sampled(Boolean.TRUE) // Important!
.build();

try (CurrentTraceContext.Scope unused = tracer.currentTraceContext().newScope(traceContext)) {
final String newTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(newTraceId)
.isNotEqualTo(previousTraceId);
}
}

final String lastTraceId = Objects.requireNonNull(tracer.currentSpan()).context().traceId();
assertThat(lastTraceId)
.isEqualTo(previousTraceId);
} catch (Throwable e) {
firstSpan.error(e);
throw e;
} finally {
firstSpan.end();
}
}
}