read(URLConnection request, String key) {
33 | return request.getRequestProperties().get(key);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/brave-tests/src/test/java/brave/test/ITRemoteTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.test;
6 |
7 | import brave.handler.MutableSpan;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | class ITRemoteTest {
13 | static final class ITRemoteDummy extends ITRemote {
14 | }
15 |
16 | @Test void tracer_includesClassName() {
17 | ITRemoteDummy itRemote = new ITRemoteDummy();
18 | itRemote.tracing.tracer().newTrace().start(1L).finish(1L);
19 |
20 | MutableSpan span = itRemote.testSpanHandler.takeLocalSpan();
21 | assertThat(span.localServiceName())
22 | .isEqualTo("ITRemoteDummy"); // much better than "unknown"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/brave/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave,\
5 | brave.baggage,\
6 | brave.handler,\
7 | brave.propagation,\
8 | brave.sampler,\
9 | brave.internal;braveinternal=true;mandatory:=braveinternal
10 |
--------------------------------------------------------------------------------
/brave/src/it/no_deps/README.md:
--------------------------------------------------------------------------------
1 | # no_deps
2 | This tests that Brave has no dependencies, not even on Zipkin
3 |
--------------------------------------------------------------------------------
/brave/src/it/no_deps/src/test/java/brave/no_deps/TracingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.no_deps;
6 |
7 | import brave.ScopedSpan;
8 | import brave.Tracing;
9 | import brave.handler.SpanHandler;
10 |
11 | import org.junit.jupiter.api.Test;
12 |
13 | class TracingTest {
14 | @Test void basicUsage() {
15 | try (Tracing tracing = Tracing.newBuilder().addSpanHandler(new SpanHandler() {
16 | // avoid NOOP short-circuiting tracing
17 | }).build()) {
18 | ScopedSpan parent = tracing.tracer().startScopedSpan("parent");
19 | tracing.tracer().newChild(parent.context()).finish();
20 | parent.finish();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/Clock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | /**
8 | * Epoch microseconds used for {@link brave.Span#start(long)}, {@link brave.Span#finish(long)} and
9 | * {@link brave.Span#annotate(long, String)}.
10 | *
11 | * This should use the most precise value possible. For example, {@code gettimeofday} or
12 | * multiplying {@link System#currentTimeMillis} by 1000.
13 | *
14 | *
See Instrumenting a service for
15 | * more.
16 | *
17 | *
Note: This type is safe to implement as a lambda, or use as a method reference as it
18 | * is effectively a {@code FunctionalInterface}. It isn't annotated as such because the project has
19 | * a minimum Java language level 6.
20 | *
21 | * @since 4.0
22 | */
23 | // @FunctionalInterface, except Java language level 6. Do not add methods as it will break API!
24 | public interface Clock {
25 |
26 | long currentTimeMicroseconds();
27 | }
28 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/CurrentSpanCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | /**
8 | * Provides a mechanism for end users to be able to customise the current span.
9 | *
10 | *
Handles the case of there being no current span in scope.
11 | */
12 | public final class CurrentSpanCustomizer implements SpanCustomizer {
13 |
14 | private final Tracer tracer;
15 |
16 | /** Creates a span customizer that will affect the current span in scope if present */
17 | public static CurrentSpanCustomizer create(Tracing tracing) {
18 | return new CurrentSpanCustomizer(tracing);
19 | }
20 |
21 | CurrentSpanCustomizer(Tracing tracing) {
22 | this.tracer = tracing.tracer();
23 | }
24 |
25 | /** {@inheritDoc} */
26 | @Override public SpanCustomizer name(String name) {
27 | return tracer.currentSpanCustomizer().name(name);
28 | }
29 |
30 | /** {@inheritDoc} */
31 | @Override public SpanCustomizer tag(String key, String value) {
32 | return tracer.currentSpanCustomizer().tag(key, value);
33 | }
34 |
35 | /** {@inheritDoc} */
36 | @Override public SpanCustomizer annotate(String value) {
37 | return tracer.currentSpanCustomizer().annotate(value);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/NoopSpanCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | /**
8 | * Performs no operations as the span represented by this is not sampled to report to the tracing
9 | * system.
10 | */
11 | // Preferred to a constant NOOP in SpanCustomizer as the latter ends up in a hierarchy with Span
12 | public enum NoopSpanCustomizer implements SpanCustomizer {
13 | INSTANCE;
14 |
15 | @Override public SpanCustomizer name(String name) {
16 | return this;
17 | }
18 |
19 | @Override public SpanCustomizer tag(String key, String value) {
20 | return this;
21 | }
22 |
23 | @Override public SpanCustomizer annotate(String value) {
24 | return this;
25 | }
26 |
27 | @Override public String toString() {
28 | return "NoopSpanCustomizer{}";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/SpanCustomizerShield.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | /** This reduces exposure of methods on {@link Span} to those exposed on {@link SpanCustomizer}. */
8 | final class SpanCustomizerShield implements SpanCustomizer {
9 | final Span delegate;
10 |
11 | SpanCustomizerShield(Span delegate) {
12 | this.delegate = delegate;
13 | }
14 |
15 | @Override public SpanCustomizer name(String name) {
16 | delegate.name(name);
17 | return this;
18 | }
19 |
20 | @Override public SpanCustomizer annotate(String value) {
21 | delegate.annotate(value);
22 | return this;
23 | }
24 |
25 | @Override public SpanCustomizer tag(String key, String value) {
26 | delegate.tag(key, value);
27 | return this;
28 | }
29 |
30 | @Override public String toString() {
31 | return "SpanCustomizer(" + delegate + ")";
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/CorrelationContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal;
6 |
7 | /**
8 | * Dispatches methods to synchronize fields with a context such as SLF4J MDC.
9 | *
10 | *
This is internal: All subtypes of {@link CorrelationContext} are sealed
11 | * to this repository until we better understand implications of making this a public type.
12 | */
13 | // NOTE: revert to abstract class with protected signatures if this is ever promoted to the
14 | // brave.propagation package.
15 | public interface CorrelationContext {
16 | /** Returns the string property of the specified name or {@code null}. */
17 | // same as BaggageContext#getValue(BaggageField, TraceContext)
18 | @Nullable String getValue(String name);
19 |
20 | /** Returns false if the update was ignored. */
21 | // same as BaggageContext#updateValue(BaggageField, TraceContext, String)
22 | boolean update(String name, @Nullable String value);
23 | }
24 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/Nullable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal;
6 |
7 | /**
8 | * Libraries such as Guice and AutoValue will process any annotation named {@code Nullable}. This
9 | * avoids a dependency on one of the many jsr305 jars, causes problems in OSGi and Java 9 projects
10 | * (where a project is also using jax-ws).
11 | */
12 | @java.lang.annotation.Documented
13 | @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
14 | public @interface Nullable {
15 | }
16 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/RecyclableBuffers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal;
6 |
7 | public final class RecyclableBuffers {
8 |
9 | private static final ThreadLocal PARSE_BUFFER = new ThreadLocal();
10 |
11 | /**
12 | * Returns a {@link ThreadLocal} reused {@code char[]} for use when decoding bytes into an ID hex
13 | * string. The buffer should be immediately copied into a {@link String} after decoding within the
14 | * same method.
15 | */
16 | public static char[] parseBuffer() {
17 | char[] idBuffer = PARSE_BUFFER.get();
18 | if (idBuffer == null) {
19 | idBuffer = new char[32 + 1 + 16 + 3 + 16]; // traceid128-spanid-1-parentid
20 | PARSE_BUFFER.set(idBuffer);
21 | }
22 | return idBuffer;
23 | }
24 |
25 | private RecyclableBuffers() {
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/Throwables.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal;
6 |
7 | public final class Throwables {
8 | // Taken from RxJava throwIfFatal, which was taken from scala
9 | public static void propagateIfFatal(Throwable t) {
10 | if (t instanceof VirtualMachineError) {
11 | throw (VirtualMachineError) t;
12 | } else if (t instanceof ThreadDeath) {
13 | throw (ThreadDeath) t;
14 | } else if (t instanceof LinkageError) {
15 | throw (LinkageError) t;
16 | }
17 | }
18 |
19 | Throwables() {
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/baggage/BaggageContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal.baggage;
6 |
7 | import brave.baggage.BaggageField;
8 | import brave.internal.Nullable;
9 | import brave.propagation.TraceContext;
10 | import brave.propagation.TraceContextOrSamplingFlags;
11 |
12 | /** Internal type that implements context storage for the field. */
13 | public abstract class BaggageContext {
14 | @Nullable
15 | public abstract String getValue(BaggageField field, TraceContextOrSamplingFlags extracted);
16 |
17 | @Nullable public abstract String getValue(BaggageField field, TraceContext context);
18 |
19 | /** Returns false if the update was ignored. */
20 | public abstract boolean updateValue(BaggageField field, TraceContextOrSamplingFlags extracted,
21 | @Nullable String value);
22 |
23 | /** Returns false if the update was ignored. */
24 | public abstract boolean updateValue(BaggageField field, TraceContext context,
25 | @Nullable String value);
26 |
27 | /** Appropriate for constants or immutable fields defined in {@link TraceContext}. */
28 | public static abstract class ReadOnly extends BaggageContext {
29 | @Override public boolean updateValue(BaggageField field, TraceContextOrSamplingFlags extracted,
30 | @Nullable String value) {
31 | return false;
32 | }
33 |
34 | @Override public boolean updateValue(BaggageField field, TraceContext context, String value) {
35 | return false;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/collect/LongBitSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal.collect;
6 |
7 | import java.util.BitSet;
8 |
9 | /**
10 | * This is more efficient than {@link BitSet} as this doesn't implicitly allocate arrays.
11 | */
12 | public final class LongBitSet {
13 | public static final int MAX_SIZE = Long.SIZE;
14 |
15 | public static int size(long bitset) {
16 | return Long.bitCount(bitset);
17 | }
18 |
19 | public static boolean isSet(long bitset, long i) {
20 | return (bitset & (1 << i)) != 0;
21 | }
22 |
23 | public static long setBit(long bitset, long i) {
24 | return bitset | (1 << i);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/internal/recorder/TickClock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal.recorder;
6 |
7 | import brave.Clock;
8 | import brave.internal.Platform;
9 |
10 | final class TickClock implements Clock {
11 | final Platform platform;
12 | final long baseEpochMicros;
13 | final long baseTickNanos;
14 |
15 | TickClock(Platform platform, long baseEpochMicros, long baseTickNanos) {
16 | this.platform = platform;
17 | this.baseEpochMicros = baseEpochMicros;
18 | this.baseTickNanos = baseTickNanos;
19 | }
20 |
21 | @Override public long currentTimeMicroseconds() {
22 | return ((platform.nanoTime() - baseTickNanos) / 1000) + baseEpochMicros;
23 | }
24 |
25 | @Override public String toString() {
26 | return "TickClock{"
27 | + "baseEpochMicros=" + baseEpochMicros + ", "
28 | + "baseTickNanos=" + baseTickNanos
29 | + "}";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/propagation/B3SinglePropagation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.propagation;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * Implements the propagation format described in {@link B3SingleFormat}.
11 | *
12 | * Use {@link B3Propagation#newFactoryBuilder()} to control inject formats.
13 | */
14 | public final class B3SinglePropagation {
15 | public static final Propagation.Factory FACTORY = B3Propagation.newFactoryBuilder()
16 | .injectFormat(B3Propagation.Format.SINGLE)
17 | .injectFormat(Span.Kind.CLIENT, B3Propagation.Format.SINGLE)
18 | .injectFormat(Span.Kind.SERVER, B3Propagation.Format.SINGLE)
19 | .build();
20 | }
21 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/sampler/Matcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.sampler;
6 |
7 | /**
8 | * Returns true if this rule matches the input parameters
9 | *
10 | *
Implement {@link #hashCode()} and {@link #equals(Object)} if you want to replace existing
11 | * rules by something besides object identity.
12 | *
13 | * @see Matchers
14 | * @since 5.8
15 | */
16 | public interface Matcher
{
17 | boolean matches(P parameters);
18 | }
19 |
--------------------------------------------------------------------------------
/brave/src/main/java/brave/sampler/SamplerFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.sampler;
6 |
7 | import brave.Request;
8 | import brave.internal.Nullable;
9 |
10 | /**
11 | * Decides whether to start a new trace based on request properties such as an HTTP path.
12 | *
13 | *
Ex. Here's a sampler that only traces api requests
14 | *
{@code
15 | * serverSampler = new SamplerFunction() {
16 | * @Override public Boolean trySample(HttpRequest request) {
17 | * return request.path().startsWith("/api");
18 | * }
19 | * });
20 | * }
21 | *
22 | * @param type of the input, for example a request or method
23 | * @see SamplerFunctions
24 | * @see Request
25 | * @since 5.8
26 | */
27 | // interface, not abstract type, to allow backporting of existing samplers.
28 | // This implies we cannot add new methods later, as the bytecode level of Brave core is 1.6
29 | public interface SamplerFunction {
30 | /**
31 | * Returns an overriding sampling decision for a new trace. Returning null is typically used to
32 | * defer to the {@link brave.Tracing#sampler() trace ID sampler}.
33 | *
34 | * @param arg parameter to evaluate for a sampling decision. null input results in a null result
35 | * @return true to sample a new trace or false to deny. Null defers the decision.
36 | * @since 5.8
37 | */
38 | @Nullable Boolean trySample(@Nullable T arg);
39 | }
40 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/GarbageCollectors.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | import java.lang.ref.WeakReference;
8 |
9 | /**
10 | * Utilities for working with the garbage collector in tests.
11 | */
12 | public final class GarbageCollectors {
13 |
14 | /**
15 | * Runs the garbage collector and waits until all of the provided {@link WeakReference} are
16 | * cleared, indicating the referenced objects have been collected.
17 | */
18 | public static void blockOnGC() {
19 | System.gc();
20 | try {
21 | Thread.sleep(200);
22 | } catch (InterruptedException e) {
23 | Thread.currentThread().interrupt();
24 | throw new AssertionError(e);
25 | }
26 | }
27 |
28 | private GarbageCollectors() {}
29 | }
30 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/RealSpanCustomizerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | import brave.test.TestSpanHandler;
8 | import org.junit.jupiter.api.AfterEach;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import static org.assertj.core.api.Assertions.assertThat;
12 | import static org.assertj.core.api.Assertions.entry;
13 |
14 | class RealSpanCustomizerTest {
15 | TestSpanHandler spans = new TestSpanHandler();
16 | Tracing tracing = Tracing.newBuilder().addSpanHandler(spans).build();
17 | Span span = tracing.tracer().newTrace();
18 | SpanCustomizer spanCustomizer = span.customizer();
19 |
20 | @AfterEach void close() {
21 | tracing.close();
22 | }
23 |
24 | @Test void name() {
25 | spanCustomizer.name("foo");
26 | span.flush();
27 |
28 | assertThat(spans.get(0).name())
29 | .isEqualTo("foo");
30 | }
31 |
32 | @Test void annotate() {
33 | spanCustomizer.annotate("foo");
34 | span.flush();
35 |
36 | assertThat(spans.get(0).containsAnnotation("foo"))
37 | .isTrue();
38 | }
39 |
40 | @Test void tag() {
41 | spanCustomizer.tag("foo", "bar");
42 | span.flush();
43 |
44 | assertThat(spans).flatExtracting(s -> s.tags().entrySet())
45 | .containsExactly(entry("foo", "bar"));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/RequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | class RequestTest {
12 | @Test void toString_mentionsDelegate() {
13 | class IceCreamRequest extends Request {
14 | @Override public Span.Kind spanKind() {
15 | return Span.Kind.SERVER;
16 | }
17 |
18 | @Override public Object unwrap() {
19 | return "chocolate";
20 | }
21 | }
22 | assertThat(new IceCreamRequest())
23 | .hasToString("IceCreamRequest{chocolate}");
24 | }
25 |
26 | @Test void toString_doesntStackoverflowWhenUnwrapIsThis() {
27 | class BuggyRequest extends Request {
28 | @Override public Object unwrap() {
29 | return this;
30 | }
31 |
32 | @Override public Span.Kind spanKind() {
33 | return Span.Kind.SERVER;
34 | }
35 | }
36 | assertThat(new BuggyRequest())
37 | .hasToString("BuggyRequest");
38 | }
39 |
40 | @Test void toString_doesntNPEWhenUnwrapIsNull() {
41 | class NoRequest extends Request {
42 | @Override public Object unwrap() {
43 | return null;
44 | }
45 |
46 | @Override public Span.Kind spanKind() {
47 | return Span.Kind.SERVER;
48 | }
49 | }
50 | assertThat(new NoRequest())
51 | .hasToString("NoRequest");
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/SpanCustomizerShieldTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | class SpanCustomizerShieldTest {
12 | Tracing tracing = Tracing.newBuilder().build();
13 |
14 | @Test void doesNotStackOverflowOnToString() {
15 | Span span = tracing.tracer().newTrace();
16 | SpanCustomizerShield shield = new SpanCustomizerShield(span);
17 | assertThat(shield.toString())
18 | .isNotEmpty()
19 | .isEqualTo("SpanCustomizer(RealSpan(" + span.context().traceIdString() + "/" + span.context()
20 | .spanIdString() + "))");
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/baggage/Access.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.baggage;
6 |
7 | import brave.internal.baggage.BaggageCodec;
8 |
9 | public abstract class Access {
10 | /** {@link BaggageCodec} is not yet a public api */
11 | public static BaggagePropagationConfig newBaggagePropagationConfig(
12 | BaggageCodec baggageCodec, int maxDynamicFields) {
13 | return new BaggagePropagationConfig(baggageCodec, maxDynamicFields);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/features/finagle_context/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | /**
6 | * This shows how you can reuse finagle's trace context in Brave
7 | */
8 | package brave.features.finagle_context;
9 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/features/handler/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | /**
6 | * Shows how {@link brave.handler.SpanHandler} related work.
7 | */
8 | package brave.features.handler;
9 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/features/opentracing/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | /**
6 | * It was difficult to implement OpenTracing directly within Brave 3, particularly as spans were
7 | * spread across 3 different tracing abstractions. Now, {@link brave.Span} can implement {@link
8 | * io.opentracing.Span} directly, at least the features that can be mapped to Zipkin.
9 | */
10 | package brave.features.opentracing;
11 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/features/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.features;
6 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/features/propagation/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | /**
6 | * Before, we had the same algorithm for encoding B3 copy pasted a couple times. We now have a type
7 | * {@link brave.propagation.Propagation} which supplies an implementation such as B3. This includes
8 | * common functions such as how to extract and inject header-based requests.
9 | */
10 | package brave.features.propagation;
11 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/internal/InternalPropagationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal;
6 |
7 | import brave.propagation.SamplingFlags;
8 | import brave.propagation.TraceContext;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import static brave.internal.InternalPropagation.FLAG_SAMPLED;
12 | import static brave.internal.InternalPropagation.FLAG_SAMPLED_SET;
13 | import static brave.internal.InternalPropagation.sampled;
14 | import static org.assertj.core.api.Assertions.assertThat;
15 |
16 | class InternalPropagationTest {
17 | @Test void set_sampled_true() {
18 | assertThat(sampled(true, 0))
19 | .isEqualTo(FLAG_SAMPLED_SET + FLAG_SAMPLED);
20 | }
21 |
22 | @Test void set_sampled_false() {
23 | assertThat(sampled(false, FLAG_SAMPLED_SET | FLAG_SAMPLED))
24 | .isEqualTo(FLAG_SAMPLED_SET);
25 | }
26 |
27 | static {
28 | SamplingFlags.EMPTY.toString(); // ensure wired
29 | }
30 |
31 | @Test void shallowCopy() {
32 | TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).debug(true)
33 | .addExtra(1L).build();
34 |
35 | assertThat(InternalPropagation.instance.shallowCopy(context))
36 | .isNotSameAs(context)
37 | .usingRecursiveComparison()
38 | .isEqualTo(context);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/internal/extra/BasicMapExtra.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal.extra;
6 |
7 | final class BasicMapExtra extends MapExtra {
8 | static final class FactoryBuilder
9 | extends MapExtraFactory.Builder {
10 | @Override protected Factory build() {
11 | return new Factory(this);
12 | }
13 | }
14 |
15 | static final class Factory extends MapExtraFactory {
16 | Factory(FactoryBuilder builder) {
17 | super(builder);
18 | }
19 |
20 | @Override protected BasicMapExtra create() {
21 | return new BasicMapExtra(this);
22 | }
23 | }
24 |
25 | BasicMapExtra(Factory factory) {
26 | super(factory);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/internal/recorder/TickClockTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.internal.recorder;
6 |
7 | import brave.internal.Platform;
8 | import org.junit.jupiter.api.Test;
9 | import org.junit.jupiter.api.extension.ExtendWith;
10 | import org.mockito.Mock;
11 | import org.mockito.junit.jupiter.MockitoExtension;
12 |
13 | import static org.assertj.core.api.Assertions.assertThat;
14 | import static org.mockito.Mockito.when;
15 |
16 | @ExtendWith(MockitoExtension.class)
17 | class TickClockTest {
18 | @Mock Platform platform;
19 |
20 | @Test void relativeTimestamp_incrementsAccordingToNanoTick() {
21 | TickClock clock = new TickClock(platform, 1000L /* 1ms */, 0L /* 0ns */);
22 |
23 | when(platform.nanoTime()).thenReturn(1000L); // 1 microsecond = 1000 nanoseconds
24 |
25 | assertThat(clock.currentTimeMicroseconds()).isEqualTo(1001L); // 1ms + 1us
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/propagation/PropagationConstantsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.propagation;
6 |
7 | import brave.Tracing;
8 | import org.junit.jupiter.api.Test;
9 |
10 | /** Ensures there's no NPE when tracing builder uses defaults */
11 | class PropagationConstantsTest {
12 |
13 | @Test void eagerReferencePropagationConstantPriorToUse() {
14 | Propagation foo = Propagation.B3_STRING;
15 | Tracing.newBuilder().build().close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/propagation/PropagationFactoryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.propagation;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | class PropagationFactoryTest {
12 | Propagation.Factory factory = new Propagation.Factory() {
13 | @Override public Propagation get() {
14 | return null;
15 | }
16 | };
17 |
18 | /** 64 bit trace IDs are not consistently mandatory across propagation, yet. */
19 | @Test void requires128BitTraceId_defaultsToFalse() {
20 | assertThat(factory.requires128BitTraceId())
21 | .isFalse();
22 | }
23 |
24 | /** join (reusing span ID on client and server side) is rarely supported outside B3. */
25 | @Test void supportsJoin_defaultsToFalse() {
26 | assertThat(B3Propagation.FACTORY.supportsJoin())
27 | .isTrue();
28 | assertThat(factory.supportsJoin())
29 | .isFalse();
30 | }
31 |
32 | @Test void decorate_defaultsToReturnSameInstance() {
33 | TraceContext context = TraceContext.newBuilder().traceId(1).spanId(1).build();
34 | assertThat(factory.decorate(context))
35 | .isSameAs(context);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/propagation/ThreadLocalSpanTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.propagation;
6 |
7 | import brave.Tracing;
8 | import brave.test.TestSpanHandler;
9 | import org.junit.jupiter.api.AfterEach;
10 | import org.junit.jupiter.api.Test;
11 |
12 | import static org.assertj.core.api.Assertions.assertThat;
13 |
14 | class ThreadLocalSpanTest {
15 | StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create();
16 | TestSpanHandler spans = new TestSpanHandler();
17 | Tracing tracing = Tracing.newBuilder()
18 | .currentTraceContext(currentTraceContext)
19 | .addSpanHandler(spans)
20 | .build();
21 |
22 | ThreadLocalSpan threadLocalSpan = ThreadLocalSpan.create(tracing.tracer());
23 |
24 | @AfterEach void close() {
25 | tracing.close();
26 | currentTraceContext.close();
27 | }
28 |
29 | @Test void next() {
30 | assertThat(threadLocalSpan.next())
31 | .isEqualTo(threadLocalSpan.remove());
32 | }
33 |
34 | @Test void next_extracted() {
35 | assertThat(threadLocalSpan.next(TraceContextOrSamplingFlags.DEBUG))
36 | .isEqualTo(threadLocalSpan.remove());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/sampler/BoundarySamplerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.sampler;
6 |
7 | import org.assertj.core.data.Percentage;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.data.Percentage.withPercentage;
11 |
12 | class BoundarySamplerTest extends SamplerTest {
13 | @Override Sampler newSampler(float probability) {
14 | return BoundarySampler.create(probability);
15 | }
16 |
17 | @Override Percentage expectedErrorProbability() {
18 | return withPercentage(11);
19 | }
20 |
21 | @Test void acceptsOneInTenThousandProbability() {
22 | newSampler(0.0001f);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/sampler/CountingSamplerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.sampler;
6 |
7 | import org.assertj.core.data.Percentage;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.data.Percentage.withPercentage;
11 | import static org.junit.jupiter.api.Assertions.assertThrows;
12 |
13 | class CountingSamplerTest extends SamplerTest {
14 | @Override Sampler newSampler(float probability) {
15 | return CountingSampler.create(probability);
16 | }
17 |
18 | @Override Percentage expectedErrorProbability() {
19 | return withPercentage(0);
20 | }
21 |
22 | @Test void probabilityMinimumOnePercent() {
23 | assertThrows(IllegalArgumentException.class, () -> {
24 | newSampler(0.0001f);
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/brave/src/test/java/brave/test/TestSpanHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.test;
6 |
7 | import brave.handler.MutableSpan;
8 | import brave.handler.SpanHandler;
9 | import brave.propagation.TraceContext;
10 | import java.util.ArrayList;
11 | import java.util.Iterator;
12 | import java.util.List;
13 |
14 | // copy of what's in brave-tests
15 | public final class TestSpanHandler extends SpanHandler implements Iterable {
16 | final List spans = new ArrayList<>();
17 |
18 | public MutableSpan get(int i) {
19 | return spans.get(i);
20 | }
21 |
22 | public List spans() {
23 | return spans;
24 | }
25 |
26 | @Override public boolean end(TraceContext context, MutableSpan span, Cause cause) {
27 | spans.add(span);
28 | return true;
29 | }
30 |
31 | @Override public Iterator iterator() {
32 | return spans.iterator();
33 | }
34 |
35 | public void clear() {
36 | spans.clear();
37 | }
38 |
39 | @Override public String toString() {
40 | return "TestSpanHandler{" + spans + "}";
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/brave/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/build-bin/configure_deploy:
--------------------------------------------------------------------------------
1 | #!/bin/sh -ue
2 |
3 | # This script sets up anything needed for `./deploy`. Do not assume `configure_test` was called.
4 | #
5 | # See [README.md] for an explanation of this and how CI should use it.
6 | build-bin/gpg/configure_gpg
7 | build-bin/maven/maven_go_offline
8 |
9 | # openzipkin/brave publishes Javadoc to https://zipkin.io/brave/ on release
10 | build-bin/git/login_git
11 |
--------------------------------------------------------------------------------
/build-bin/configure_test:
--------------------------------------------------------------------------------
1 | #!/bin/sh -ue
2 |
3 | # This script sets up anything needed for `./test`. This should not login to anything, as that
4 | # should be done in `configure_deploy`.
5 | #
6 | # See [README.md] for an explanation of this and how CI should use it.
7 |
8 | # Docker (testcontainers) tests
9 | build-bin/docker/configure_docker
10 | build-bin/maven/maven_go_offline
11 |
--------------------------------------------------------------------------------
/build-bin/deploy:
--------------------------------------------------------------------------------
1 | #!/bin/sh -ue
2 |
3 | # This script deploys a master or release version.
4 | #
5 | # See [README.md] for an explanation of this and how CI should use it.
6 | version=${1:-master}
7 |
8 | # Use implicit version when master, if we can..
9 | if [ "${version}" = "master" ]; then
10 | version=$(sed -En 's/.*(.*)<\/version>.*/\1/p' pom.xml| head -1)
11 | fi
12 |
13 | build-bin/maven/maven_deploy -pl -:brave-bom
14 |
15 | # openzipkin/brave publishes Javadoc to gh-pages (https://zipkin.io/brave/) on release
16 | case ${version} in
17 | *-SNAPSHOT )
18 | ;;
19 | * )
20 | build-bin/javadoc_to_gh_pages ${version}
21 | ;;
22 | esac
23 |
--------------------------------------------------------------------------------
/build-bin/deploy_bom:
--------------------------------------------------------------------------------
1 | #!/bin/sh -ue
2 |
3 | # Deploy the Bill of Materials (BOM) separately as it is unhooked from the main project intentionally
4 | build-bin/maven/maven_deploy -f brave-bom/pom.xml
5 |
--------------------------------------------------------------------------------
/build-bin/docker/configure_docker:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | # Defends against build outages caused by Docker Hub (docker.io) pull rate limits.
8 | #
9 | # It should not login to anything, as that should be done in `configure_docker_push`
10 |
11 | set -ue
12 |
13 | # The below sets up testcontainers configuration, which will be ignored if it isn't used. Even if
14 | # this is Docker related, it is coupled to integration tests configuration invoked with Maven.
15 | # * See https://www.testcontainers.org/supported_docker_environment/image_registry_rate_limiting/
16 | # * checks.disable=true - saves time and a docker.io pull of alpine
17 | # * ryuk doesn't count against docker.io rate limits because Docker approved testcontainers as OSS
18 | echo checks.disable=true >> ~/.testcontainers.properties
19 |
20 | # We don't use any docker.io images, but add a Google's mirror in case something implicitly does
21 | # * See https://cloud.google.com/container-registry/docs/pulling-cached-images
22 | echo '{ "registry-mirrors": ["https://mirror.gcr.io"] }' | sudo tee /etc/docker/daemon.json
23 | sudo service docker restart
24 |
--------------------------------------------------------------------------------
/build-bin/git/login_git:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | set -ue
8 |
9 | # Allocate commits to CI, not the owner of the deploy key
10 | git config user.name "zipkinci"
11 | git config user.email "zipkinci+zipkin-dev@googlegroups.com"
12 |
13 | # Setup https authentication credentials, used by ./mvnw release:prepare
14 | git config credential.helper "store --file=.git/credentials"
15 | echo "https://$GH_TOKEN:@github.com" > .git/credentials
16 |
--------------------------------------------------------------------------------
/build-bin/git/version_from_trigger_tag:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | set -ue
8 |
9 | # This script echos a `MAJOR.MINOR.PATCH` version tag based on..
10 | # * arg1: XXXXX- prefix
11 | # * arg2: XXXXX-MAJOR.MINOR.PATCH git trigger tag
12 | #
13 | # The script exits 1 if the prefix doesn't match. On success, the tag is deleted if it exists.
14 | #
15 | # Note: In CI, `build-bin/git/login_git` must be called before invoking this.
16 |
17 | trigger_tag_prefix=${1?required. Ex docker- to match docker-1.2.3}
18 | trigger_tag=${2?trigger_tag is required. Ex ${trigger_tag_prefix}1.2.3}
19 |
20 | # Checking sed output to determine success as exit code handling in sed or awk is awkward
21 | version=$(echo "${trigger_tag}" | sed -En "s/^${trigger_tag_prefix}([0-9]+\.[0-9]+\.[0-9]+)$/\1/p")
22 |
23 | if [ -z "$version" ]; then
24 | >&2 echo invalid trigger tag: ${trigger_tag}
25 | exit 1;
26 | fi
27 |
28 | # try to cleanup the trigger tag if it exists, but don't fail if it doesn't
29 | git tag -d ${trigger_tag} 2>&- >&- || true
30 | git push origin :${trigger_tag} 2>&- >&- || true
31 |
32 | echo $version
33 |
--------------------------------------------------------------------------------
/build-bin/gpg/configure_gpg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | set -ue
8 |
9 | # This script prepares GPG, needed to sign jars for Sonatype deployment during `maven_deploy`
10 |
11 | # ensure GPG commands work non-interactively
12 | export GPG_TTY=$(tty)
13 | # import signing key used for jar files
14 | echo ${GPG_SIGNING_KEY} | base64 --decode | gpg --batch --passphrase ${GPG_PASSPHRASE} --import
15 |
--------------------------------------------------------------------------------
/build-bin/maven/maven_deploy:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | set -ue
8 |
9 | export MAVEN_OPTS="$($(dirname "$0")/maven_opts)"
10 |
11 | # This script deploys a SNAPSHOT or release version to Sonatype.
12 | #
13 | # Note: In CI, `configure_maven_deploy` must be called before invoking this.
14 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DskipTests clean deploy $@
15 |
--------------------------------------------------------------------------------
/build-bin/maven/maven_go_offline:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | # This is a go-offline that properly works with multi-module builds
8 |
9 | set -ue
10 |
11 | export MAVEN_OPTS="$($(dirname "$0")/maven_opts)"
12 | if [ -x ./mvnw ]; then alias mvn=${PWD}/mvnw; fi
13 |
14 | (
15 | if [ "${MAVEN_PROJECT_BASEDIR:-.}" != "." ]; then cd ${MAVEN_PROJECT_BASEDIR}; fi
16 | mvn -q --batch-mode -nsu -Prelease de.qaware.maven:go-offline-maven-plugin:resolve-dependencies "$@"
17 | )
18 |
--------------------------------------------------------------------------------
/build-bin/maven/maven_opts:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright The OpenZipkin Authors
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | # This script checks each variable value, so it isn't important to fail on unbound (set -u)
8 | set -e
9 |
10 | maven_project_basedir=${MAVEN_PROJECT_BASEDIR:-.}
11 | pom="${maven_project_basedir}/pom.xml"
12 |
13 | # fail if there's no pom
14 | test -f "${pom}"
15 |
16 | arch=$(uname -m)
17 | case ${arch} in
18 | arm64* )
19 | arch=arm64
20 | ;;
21 | aarch64* )
22 | arch=arm64
23 | ;;
24 | esac
25 |
26 | maven_opts="${MAVEN_OPTS:-}"
27 | if [ ${arch} = "arm64" ] && [ -f /etc/alpine-release ]; then
28 | # Defensively avoid arm64+alpine problems with posix_spawn
29 | maven_opts="${maven_opts} -Djdk.lang.Process.launchMechanism=vfork"
30 | fi
31 |
32 | echo ${maven_opts}
33 |
--------------------------------------------------------------------------------
/build-bin/test:
--------------------------------------------------------------------------------
1 | #!/bin/sh -ue
2 |
3 | # This script runs the tests of the project.
4 | #
5 | # See [README.md] for an explanation of this and how CI should use it.
6 |
7 | # We use install, not verify, because maven-invoker-tests need brave-tests
8 | # installed into the local repository before it can run.
9 | #
10 | # We avoid -T1C because some plugins don't work in parallel and also ITs are
11 | # difficult to debug when failures are in parallel.
12 | ./mvnw install -nsu "$@"
13 |
--------------------------------------------------------------------------------
/context/jfr/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.context.jfr
7 |
--------------------------------------------------------------------------------
/context/jfr/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 | io.zipkin.brave
11 | brave-context-parent
12 | 6.3.1-SNAPSHOT
13 |
14 | 4.0.0
15 |
16 | brave-context-jfr
17 | Brave Context: JDK Flight Recorder
18 |
19 |
20 |
21 | brave.context.jfr
22 |
23 |
24 | 11
25 | 11
26 | 11
27 |
28 | ${project.basedir}/../..
29 |
30 |
31 |
32 |
33 |
34 | maven-compiler-plugin
35 |
36 | ${main.java.version}
37 |
38 | --add-modules
39 | jdk.jfr
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/context/jfr/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) [%X{traceId}/%X{spanId}] - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/context/log4j12/README.md:
--------------------------------------------------------------------------------
1 | # brave-context-log4j12
2 | This adds trace and span IDs to the Log4J v1.2 Mapped Diagnostic Context (MDC) so that you
3 | can search or aggregate logs accordingly.
4 |
5 | To enable this, configure `brave.Tracing` with `MDCScopeDecorator` like so:
6 |
7 | ```java
8 | correlationContext = new Log4jContext();
9 | tracing = Tracing.newBuilder()
10 | .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
11 | .addScopeDecorator(MDCScopeDecorator.get())
12 | .build()
13 | )
14 | ...
15 | .build();
16 | ```
17 |
18 | Then, in your log configuration, you can use `traceId` and `spanId`.
19 |
20 | Here's an example log4j.properties pattern:
21 |
22 | ```xml
23 | appender.console.layout.ConversionPattern = %d{ABSOLUTE} [%X{traceId}/%X{spanId}] %-5p [%t] %C{2} (%F:%L) - %m%n
24 | ```
25 |
26 | When a trace is in progress, it would log statements like this:
27 | ```
28 | 11:01:29,799 [e2ffceb485bdfb1d/e2ffceb485bdfb1d] INFO [main] c.a.FooController (FooController.java:30) - I got here!
29 | ```
30 |
31 | Users could then copy/paste the trace ID into the zipkin UI, or use log
32 | correlation to further debug a problem.
33 |
34 | ## Log4J 1.2.x MDC is inheritable
35 |
36 | Log4J 1.2.x MDC uses an inheritable thread local by default. This means
37 | trace identifiers could leak onto new threads and mislable log lines. If
38 | this is a problem, consider Log4J 2.x or SLF4J which do not inherit by
39 | default.
40 |
--------------------------------------------------------------------------------
/context/log4j12/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.CorrelationContext
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.context.log4j12
8 |
--------------------------------------------------------------------------------
/context/log4j12/src/it/log4j12/README.md:
--------------------------------------------------------------------------------
1 | # log4j12
2 | This tests that MDCScopeDecorator does not rely on Log4J 2+ APIs.
3 |
--------------------------------------------------------------------------------
/context/log4j12/src/it/log4j12/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO, console
2 | log4j.appender.console=org.apache.log4j.ConsoleAppender
3 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
4 | log4j.appender.console.layout.ConversionPattern=[%d{dd MMM yyyy HH:mm:ss,SSS}] [%X{traceId}/%X{spanId} - sampled=%X{sampled}] : %m%n
5 |
6 |
--------------------------------------------------------------------------------
/context/log4j12/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) [%X{traceId}/%X{spanId} - sampled=%X{sampled}] - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/context/log4j2/README.md:
--------------------------------------------------------------------------------
1 | # brave-context-log4j2
2 | This adds trace and span IDs to the Log4J 2 Thread Context so that you
3 | can search or aggregate logs accordingly.
4 |
5 | To enable this, configure `brave.Tracing` with `ThreadLocalCurrentTraceContext` like so:
6 |
7 | ```java
8 | tracing = Tracing.newBuilder()
9 | .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
10 | .addScopeDecorator(ThreadContextScopeDecorator.get())
11 | .build()
12 | )
13 | ...
14 | .build();
15 | ```
16 |
17 | Then, in your log configuration, you can use `traceId` and `spanId`.
18 |
19 | Here's an example log4j2.properties pattern:
20 |
21 | ```xml
22 | appender.console.layout.pattern = %d{ABSOLUTE} [%X{traceId}/%X{spanId}] %-5p [%t] %C{2} (%F:%L) - %m%n
23 | ```
24 |
25 | When a trace is in progress, it would log statements like this:
26 | ```
27 | 11:01:29,799 [e2ffceb485bdfb1d/e2ffceb485bdfb1d] INFO [main] c.a.FooController (FooController.java:30) - I got here!
28 | ```
29 |
30 | Users could then copy/paste the trace ID into the zipkin UI, or use log
31 | correlation to further debug a problem.
32 |
--------------------------------------------------------------------------------
/context/log4j2/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.CorrelationContext
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.context.log4j2
8 |
--------------------------------------------------------------------------------
/context/log4j2/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) [%X{traceId}/%X{spanId} - sampled=%X{sampled}] - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/context/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | 4.0.0
10 |
11 |
12 | io.zipkin.brave
13 | brave-parent
14 | 6.3.1-SNAPSHOT
15 |
16 |
17 | brave-context-parent
18 | Brave: Trace Contexts
19 | pom
20 |
21 |
22 | ${project.basedir}/..
23 |
24 |
25 |
26 | jfr
27 | slf4j
28 | log4j12
29 | log4j2
30 |
31 |
32 |
33 |
34 | ${project.groupId}
35 | brave
36 | ${project.version}
37 |
38 |
39 | ${project.groupId}
40 | brave-tests
41 | ${project.version}
42 | test
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/context/slf4j/README.md:
--------------------------------------------------------------------------------
1 | # brave-context-slf4j
2 | This adds trace and span IDs to the SLF4J Mapped Diagnostic Context (MDC)
3 | so that you can search or aggregate logs accordingly.
4 |
5 | To enable this, configure `brave.Tracing` with `MDCScopeDecorator` like so:
6 |
7 | ```java
8 | correlationContext = new SLF4JContext();
9 | tracing = Tracing.newBuilder()
10 | .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
11 | .addScopeDecorator(MDCScopeDecorator.get()
12 | .build()
13 | )
14 | ...
15 | .build();
16 | ```
17 |
18 | Then, in your log configuration, you can use `traceId`, `parentId`, `spanId` and `sampled`.
19 |
20 | Here's an example logback configuration:
21 |
22 | ```xml
23 | %d [%X{traceId}/%X{spanId}] [%thread] %-5level %logger{36} - %msg%n
24 | ```
25 |
26 | When a trace is in progress, it would log statements like this:
27 | ```
28 | 2017-05-02 23:36:04,789 [fcd015bf6f8b05ba/fcd015bf6f8b05ba] [main] INFO c.a.FooController - I got here!
29 | ```
30 |
31 | Users could then copy/paste the trace ID into the zipkin UI, or use log
32 | correlation to further debug a problem.
33 |
--------------------------------------------------------------------------------
/context/slf4j/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.CorrelationContext
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.context.slf4j
8 |
--------------------------------------------------------------------------------
/context/slf4j/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) [%X{traceId}/%X{spanId} - sampled=%X{sampled}] - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/benchmarks/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-benchmarks
2 |
3 | This module includes [JMH](http://openjdk.java.net/projects/code-tools/jmh/)
4 | benchmarks for Brave instrumentation. You can use these to measure overhead
5 | of using Brave.
6 |
7 | ### Running the benchmark
8 | From the project directory, run this to build the benchmarks:
9 |
10 | ```bash
11 | $ ./mvnw install -pl instrumentation/benchmarks -am -Dmaven.test.skip.exec=true`
12 | ```
13 |
14 | and the following to run them:
15 |
16 | ```bash
17 | $ java -jar instrumentation/benchmarks/target/benchmarks.jar
18 | ```
19 |
--------------------------------------------------------------------------------
/instrumentation/benchmarks/src/test/assembly/test-jar.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
12 | test-jar
13 |
14 | jar
15 |
16 | false
17 |
18 |
19 | /
20 | true
21 | true
22 | test
23 |
24 |
25 |
26 |
27 | ${project.build.directory}/test-classes
28 | /
29 |
30 | **/*
31 |
32 | true
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/instrumentation/benchmarks/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed to the Apache Software Foundation (ASF) under one or more
3 | # contributor license agreements. See the NOTICE file distributed with
4 | # this work for additional information regarding copyright ownership.
5 | # The ASF licenses this file to You under the Apache License, Version 2.0
6 | # (the "License"); you may not use this file except in compliance with
7 | # the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 | appenders=console
18 | appender.console.type=Console
19 | appender.console.name=STDOUT
20 | appender.console.layout.type=PatternLayout
21 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
22 | rootLogger.level=info
23 | rootLogger.appenderRefs=stdout
24 | rootLogger.appenderRef.stdout.ref=STDOUT
25 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/RATIONALE.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-dubbo rationale
2 | See [RPC](../rpc/RATIONALE.md) for general RPC rationale.
3 |
4 | ## Error code words not numbers
5 | As per normal rationale, we use code names, not numbers, for Dubbo, as defined
6 | in `RpcException`'s constants. In short, this makes trace data more intuitive
7 | and easier to search.
8 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Platform
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.dubbo
8 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/main/java/brave/dubbo/DubboClientResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import brave.internal.Nullable;
8 | import brave.rpc.RpcClientResponse;
9 | import org.apache.dubbo.rpc.Result;
10 | import org.apache.dubbo.rpc.RpcException;
11 |
12 | final class DubboClientResponse extends RpcClientResponse implements DubboResponse {
13 | final DubboClientRequest request;
14 | @Nullable final Result result;
15 | @Nullable final Throwable error;
16 |
17 | DubboClientResponse(
18 | DubboClientRequest request, @Nullable Result result, @Nullable Throwable error) {
19 | if (request == null) throw new NullPointerException("request == null");
20 | this.request = request;
21 | this.result = result;
22 | this.error = error;
23 | }
24 |
25 | @Override public Result result() {
26 | return result;
27 | }
28 |
29 | @Override public Result unwrap() {
30 | return result;
31 | }
32 |
33 | @Override public DubboClientRequest request() {
34 | return request;
35 | }
36 |
37 | @Override public Throwable error() {
38 | return error;
39 | }
40 |
41 | /** Returns the string form of the {@link RpcException#getCode()} */
42 | @Override public String errorCode() {
43 | return DubboParser.errorCode(error);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/main/java/brave/dubbo/DubboRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import brave.rpc.RpcClientRequest;
8 | import brave.rpc.RpcServerRequest;
9 | import brave.rpc.RpcTracing;
10 | import org.apache.dubbo.rpc.Invocation;
11 | import org.apache.dubbo.rpc.Invoker;
12 |
13 | /**
14 | * Used to access Dubbo specific aspects of a client or server request.
15 | *
16 | * Here's an example that adds default tags, and if Dubbo, Java arguments:
17 | *
{@code
18 | * rpcTracing = rpcTracingBuilder
19 | * .clientRequestParser((req, context, span) -> {
20 | * RpcRequestParser.DEFAULT.parse(req, context, span);
21 | * if (req instanceof DubboRequest) {
22 | * tagArguments(((DubboRequest) req).invocation().getArguments());
23 | * }
24 | * }).build();
25 | * }
26 | *
27 | * Note: Do not implement this type directly. An implementation will be
28 | * either as {@link RpcClientRequest} or an {@link RpcServerRequest}.
29 | *
30 | * @see RpcTracing#clientRequestParser()
31 | * @see RpcTracing#serverRequestParser()
32 | * @see DubboResponse
33 | * @since 5.12
34 | */
35 | // Note: Unlike Alibaba Dubbo, Apache Dubbo is Java 8+.
36 | // This means we can add default methods later should needs arise.
37 | public interface DubboRequest {
38 | Invoker> invoker();
39 |
40 | Invocation invocation();
41 | }
42 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/main/java/brave/dubbo/DubboResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import brave.internal.Nullable;
8 | import brave.rpc.RpcClientResponse;
9 | import brave.rpc.RpcServerResponse;
10 | import brave.rpc.RpcTracing;
11 | import org.apache.dubbo.rpc.Result;
12 |
13 | /**
14 | * Used to access Dubbo specific aspects of a client or server response.
15 | *
16 | *
Here's an example that adds default tags, and if Dubbo, the Java result:
17 | *
{@code
18 | * rpcTracing = rpcTracingBuilder
19 | * .clientResponseParser((res, context, span) -> {
20 | * RpcResponseParser.DEFAULT.parse(res, context, span);
21 | * if (res instanceof DubboResponse) {
22 | * DubboResponse dubboResponse = (DubboResponse) res;
23 | * if (res.result() != null) {
24 | * tagJavaResult(res.result().value());
25 | * }
26 | * }
27 | * }).build();
28 | * }
29 | *
30 | * Note: Do not implement this type directly. An implementation will be
31 | * either as {@link RpcClientResponse} or an {@link RpcServerResponse}.
32 | *
33 | * @see RpcTracing#clientResponseParser()
34 | * @see RpcTracing#serverResponseParser()
35 | * @see DubboResponse
36 | * @since 5.12
37 | */
38 | public interface DubboResponse {
39 | DubboRequest request();
40 |
41 | @Nullable Result result();
42 | }
43 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/main/java/brave/dubbo/DubboServerResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import brave.internal.Nullable;
8 | import brave.rpc.RpcServerResponse;
9 | import org.apache.dubbo.rpc.Result;
10 | import org.apache.dubbo.rpc.RpcException;
11 |
12 | final class DubboServerResponse extends RpcServerResponse implements DubboResponse {
13 | final DubboServerRequest request;
14 | @Nullable final Result result;
15 | @Nullable final Throwable error;
16 |
17 | DubboServerResponse(
18 | DubboServerRequest request, @Nullable Result result, @Nullable Throwable error) {
19 | if (request == null) throw new NullPointerException("request == null");
20 | this.request = request;
21 | this.result = result;
22 | this.error = error;
23 | }
24 |
25 | @Override public Result result() {
26 | return result;
27 | }
28 |
29 | @Override public Result unwrap() {
30 | return result;
31 | }
32 |
33 | @Override public DubboServerRequest request() {
34 | return request;
35 | }
36 |
37 | @Override public Throwable error() {
38 | return error;
39 | }
40 |
41 | /** Returns the string form of the {@link RpcException#getCode()} */
42 | @Override public String errorCode() {
43 | return DubboParser.errorCode(error);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter:
--------------------------------------------------------------------------------
1 | tracing=brave.dubbo.TracingFilter
2 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/test/java/brave/dubbo/DubboServerResponseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import org.apache.dubbo.rpc.Invocation;
8 | import org.apache.dubbo.rpc.Invoker;
9 | import org.apache.dubbo.rpc.Result;
10 | import org.apache.dubbo.rpc.RpcException;
11 | import org.junit.jupiter.api.Test;
12 |
13 | import static org.apache.dubbo.rpc.RpcException.TIMEOUT_EXCEPTION;
14 | import static org.assertj.core.api.Assertions.assertThat;
15 | import static org.mockito.Mockito.mock;
16 |
17 | public class DubboServerResponseTest {
18 | Invoker invoker = mock(Invoker.class);
19 | Invocation invocation = mock(Invocation.class);
20 | Result result = mock(Result.class);
21 | RpcException error = new RpcException(TIMEOUT_EXCEPTION);
22 | DubboServerRequest request = new DubboServerRequest(invoker, invocation);
23 | DubboServerResponse response = new DubboServerResponse(request, result, error);
24 |
25 | @Test void request() {
26 | assertThat(response.request()).isSameAs(request);
27 | }
28 |
29 | @Test void result() {
30 | assertThat(response.result()).isSameAs(result);
31 | }
32 |
33 | @Test void unwrap() {
34 | assertThat(response.unwrap()).isSameAs(result);
35 | }
36 |
37 | @Test void error() {
38 | assertThat(response.error()).isSameAs(error);
39 | }
40 |
41 | @Test void errorCode() {
42 | assertThat(response.errorCode()).isEqualTo("TIMEOUT_EXCEPTION");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/test/java/brave/dubbo/GraterService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | public interface GraterService {
8 | String sayHello(String name);
9 | }
10 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/test/java/brave/dubbo/GreeterService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | public interface GreeterService {
8 | String sayHello(String name);
9 |
10 | String sayGoodbye(String name);
11 | }
12 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/test/java/brave/dubbo/PickUnusedPort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.dubbo;
6 |
7 | import java.io.IOException;
8 | import java.net.ServerSocket;
9 |
10 | class PickUnusedPort {
11 | static int get() {
12 | try {
13 | ServerSocket serverSocket = new ServerSocket(0);
14 | int port = serverSocket.getLocalPort();
15 | serverSocket.close();
16 | return port;
17 | } catch (IOException e) {
18 | throw new AssertionError(e);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/instrumentation/dubbo/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # mute logs that have to do with config re-loading, which is constant during tests
11 | logger.model.name=org.apache.dubbo.rpc.model.ApplicationModel
12 | logger.model.level=off
13 | logger.config.name=org.apache.dubbo.config.AbstractConfig
14 | logger.config.level=off
15 | logger.server.name=org.apache.dubbo.remoting.transport.AbstractServer
16 | logger.server.level=off
17 | logger.spring-extension.name=org.apache.dubbo.config.spring.extension.SpringExtensionFactory
18 | logger.spring-extension.level=off
19 |
20 | # mute dispatcher error as we intentionally dispatch to an unknown route
21 | logger.dispatcher.name=org.apache.dubbo.remoting.transport.dispatcher
22 | logger.dispatcher.level=off
23 |
24 | # mute exception filter as we intentionally test exception paths
25 | logger.exception-filter.name=org.apache.dubbo.rpc.filter.ExceptionFilter
26 | logger.exception-filter.level=off
27 |
--------------------------------------------------------------------------------
/instrumentation/grpc/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Platform,MapPropagationFields,PropagationFieldsFactory
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.grpc
8 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/it/grpc_floor/README.md:
--------------------------------------------------------------------------------
1 | # grpc_floor
2 | This tests that GrpcTracing does not require gRPC >1.2
3 |
4 | Note: this uses manually generated protoc sources to remove a compile dependency on protoc.
5 | protoc used gRPC <1.9 did not include aarch64 support, which is something that should be irrelevant
6 | in Java code generators (because Java is platform independent). Also, gRPC 1.9 breaks grpc-trace-bin
7 | propagation, which is something we otherwise want to test. The easiest way out was to check-in
8 | generated sources that match the floor gRPC version 1.2.
9 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/it/grpc_floor/src/main/java/io/grpc/examples/helloworld/HelloReplyOrBuilder.java:
--------------------------------------------------------------------------------
1 | // Generated by the protocol buffer compiler. DO NOT EDIT!
2 | // source: helloworld.proto
3 |
4 | package io.grpc.examples.helloworld;
5 |
6 | public interface HelloReplyOrBuilder extends
7 | // @@protoc_insertion_point(interface_extends:helloworld.HelloReply)
8 | com.google.protobuf.MessageOrBuilder {
9 |
10 | /**
11 | * string message = 1;
12 | */
13 | java.lang.String getMessage();
14 | /**
15 | * string message = 1;
16 | */
17 | com.google.protobuf.ByteString
18 | getMessageBytes();
19 | }
20 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/it/grpc_floor/src/main/java/io/grpc/examples/helloworld/HelloRequestOrBuilder.java:
--------------------------------------------------------------------------------
1 | // Generated by the protocol buffer compiler. DO NOT EDIT!
2 | // source: helloworld.proto
3 |
4 | package io.grpc.examples.helloworld;
5 |
6 | public interface HelloRequestOrBuilder extends
7 | // @@protoc_insertion_point(interface_extends:helloworld.HelloRequest)
8 | com.google.protobuf.MessageOrBuilder {
9 |
10 | /**
11 | * string name = 1;
12 | */
13 | java.lang.String getName();
14 | /**
15 | * string name = 1;
16 | */
17 | com.google.protobuf.ByteString
18 | getNameBytes();
19 | }
20 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/it/grpc_floor/src/test/java/brave/grpc12/ITTracingClientInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc_floor;
6 |
7 | import brave.grpc.BaseITTracingClientInterceptor;
8 | import io.grpc.ManagedChannelBuilder;
9 |
10 | class ITTracingClientInterceptor extends BaseITTracingClientInterceptor {
11 | @Override protected ManagedChannelBuilder> usePlainText(ManagedChannelBuilder> builder) {
12 | return builder.usePlaintext(true);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/it/grpc_floor/src/test/java/brave/grpc12/ITTracingServerInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc_floor;
6 |
7 | import brave.grpc.BaseITTracingServerInterceptor;
8 | import io.grpc.ManagedChannelBuilder;
9 |
10 | class ITTracingServerInterceptor extends BaseITTracingServerInterceptor {
11 | @Override protected ManagedChannelBuilder> usePlainText(ManagedChannelBuilder> builder) {
12 | return builder.usePlaintext(true);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/main/java/brave/grpc/GrpcParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import brave.internal.Nullable;
8 |
9 | final class GrpcParser {
10 | @Nullable static String method(String fullMethodName) {
11 | int index = fullMethodName.lastIndexOf('/');
12 | if (index == -1 || index == 0) return null;
13 | return fullMethodName.substring(index + 1);
14 | }
15 |
16 | @Nullable static String service(String fullMethodName) {
17 | int index = fullMethodName.lastIndexOf('/');
18 | if (index == -1 || index == 0) return null;
19 | return fullMethodName.substring(0, index);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/main/java/brave/grpc/GrpcPropagation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import brave.baggage.BaggagePropagation;
8 | import brave.propagation.Propagation;
9 | import io.grpc.Metadata;
10 | import io.grpc.Metadata.Key;
11 | import java.util.LinkedHashMap;
12 | import java.util.Map;
13 |
14 | final class GrpcPropagation {
15 | /** Creates constant keys for use in propagating trace identifiers or baggage. */
16 | static Map> nameToKey(Propagation propagation) {
17 | Map> result = new LinkedHashMap>();
18 | for (String keyName : propagation.keys()) {
19 | result.put(keyName, Key.of(keyName, Metadata.ASCII_STRING_MARSHALLER));
20 | }
21 | for (String keyName : BaggagePropagation.allKeyNames(propagation)) {
22 | result.put(keyName, Key.of(keyName, Metadata.ASCII_STRING_MARSHALLER));
23 | }
24 | return result;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/java/brave/grpc/GrpcParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static brave.grpc.TestObjects.METHOD_DESCRIPTOR;
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | class GrpcParserTest {
13 | @Test void method() {
14 | assertThat(GrpcParser.method(METHOD_DESCRIPTOR.getFullMethodName()))
15 | .isEqualTo("SayHello");
16 | }
17 |
18 | @Test void method_malformed() {
19 | assertThat(GrpcParser.method("/")).isNull();
20 | }
21 |
22 | @Test void service() {
23 | assertThat(GrpcParser.service(METHOD_DESCRIPTOR.getFullMethodName()))
24 | .isEqualTo("helloworld.Greeter");
25 | }
26 |
27 | @Test void service_malformed() {
28 | assertThat(GrpcParser.service("/")).isNull();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/java/brave/grpc/ITTracingClientInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import io.grpc.ManagedChannelBuilder;
8 |
9 | class ITTracingClientInterceptor extends BaseITTracingClientInterceptor {
10 | @Override protected ManagedChannelBuilder> usePlainText(ManagedChannelBuilder> builder) {
11 | return builder.usePlaintext();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/java/brave/grpc/ITTracingServerInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import io.grpc.ManagedChannelBuilder;
8 |
9 | class ITTracingServerInterceptor extends BaseITTracingServerInterceptor {
10 | @Override protected ManagedChannelBuilder> usePlainText(ManagedChannelBuilder> builder) {
11 | return builder.usePlaintext();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/java/brave/grpc/PickUnusedPort.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import java.io.IOException;
8 | import java.net.ServerSocket;
9 |
10 | class PickUnusedPort {
11 | static int get() {
12 | try {
13 | ServerSocket serverSocket = new ServerSocket(0);
14 | int port = serverSocket.getLocalPort();
15 | serverSocket.close();
16 | return port;
17 | } catch (IOException e) {
18 | throw new AssertionError(e);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/java/brave/grpc/TestObjects.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.grpc;
6 |
7 | import io.grpc.MethodDescriptor;
8 | import java.io.ByteArrayInputStream;
9 | import java.io.InputStream;
10 |
11 | final class TestObjects {
12 | // Allows invoker tests to run without needing to compile protos
13 | static final MethodDescriptor METHOD_DESCRIPTOR =
14 | MethodDescriptor.newBuilder()
15 | .setType(MethodDescriptor.MethodType.UNARY)
16 | .setFullMethodName("helloworld.Greeter/SayHello")
17 | .setRequestMarshaller(VoidMarshaller.INSTANCE)
18 | .setResponseMarshaller(VoidMarshaller.INSTANCE)
19 | .build();
20 |
21 | enum VoidMarshaller implements MethodDescriptor.Marshaller {
22 | INSTANCE;
23 |
24 | @Override public InputStream stream(Void value) {
25 | return new ByteArrayInputStream(new byte[0]);
26 | }
27 |
28 | @Override public Void parse(InputStream stream) {
29 | return null;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/proto/helloworld.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option java_multiple_files = true;
4 | option java_package = "io.grpc.examples.helloworld";
5 | option java_outer_classname = "HelloWorldProto";
6 |
7 | package helloworld;
8 |
9 | // The greeting service definition.
10 | service Greeter {
11 | // Sends a greeting
12 | rpc SayHello (HelloRequest) returns (HelloReply);
13 | rpc SayHelloWithManyReplies (HelloRequest) returns (stream HelloReply);
14 | }
15 |
16 | // intentionally different to test service not found
17 | service Grater {
18 | // Sends a greeting
19 | rpc SeyHallo (HelloRequest) returns (HelloReply);
20 | }
21 |
22 | // The request message containing the user's name.
23 | message HelloRequest {
24 | string name = 1;
25 | }
26 |
27 | // The response message containing the greetings
28 | message HelloReply {
29 | string message = 1;
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/instrumentation/grpc/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) [%X{traceId}/%X{spanId}] - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # our tests intentionally create errors, but we don't to see them normally
11 | logger.SerializingExecutor.name=io.grpc.internal.SerializingExecutor
12 | logger.SerializingExecutor.level=off
13 |
--------------------------------------------------------------------------------
/instrumentation/http-tests-jakarta/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-http-tests-jakarta
2 |
3 | This module contains test base classes used to ensure instrumentation
4 | work portably.
5 |
--------------------------------------------------------------------------------
/instrumentation/http-tests-jakarta/src/main/java/brave/test/jakarta/http/Jetty11ServerController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.test.jakarta.http;
6 |
7 | import brave.test.http.ServletContainer.ServerController;
8 | import org.eclipse.jetty.server.Connector;
9 | import org.eclipse.jetty.server.Server;
10 | import org.eclipse.jetty.server.ServerConnector;
11 |
12 | public final class Jetty11ServerController implements ServerController {
13 | @Override public Server newServer(int port) {
14 | Server result = new Server();
15 | ServerConnector connector = new ServerConnector(result);
16 | connector.setPort(port);
17 | connector.setIdleTimeout(1000 * 60 * 60);
18 | result.setConnectors(new Connector[] {connector});
19 | return result;
20 | }
21 |
22 | @Override public int getLocalPort(Server server) {
23 | return ((ServerConnector) server.getConnectors()[0]).getLocalPort();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/instrumentation/http-tests-jakarta/src/main/resources/jetty-logging.properties:
--------------------------------------------------------------------------------
1 | org.eclipse.jetty.LEVEL=WARN
--------------------------------------------------------------------------------
/instrumentation/http-tests/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-http-tests
2 |
3 | This module contains test base classes used to ensure instrumentation
4 | work portably.
5 |
--------------------------------------------------------------------------------
/instrumentation/http-tests/src/main/java/brave/test/http/Jetty9ServerController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.test.http;
6 |
7 | import brave.test.http.ServletContainer.ServerController;
8 | import org.eclipse.jetty.server.Connector;
9 | import org.eclipse.jetty.server.Server;
10 | import org.eclipse.jetty.server.ServerConnector;
11 |
12 | public final class Jetty9ServerController implements ServerController {
13 | @Override public Server newServer(int port) {
14 | Server result = new Server();
15 | ServerConnector connector = new ServerConnector(result);
16 | connector.setPort(port);
17 | connector.setIdleTimeout(1000 * 60 * 60);
18 | result.setConnectors(new Connector[] {connector});
19 | return result;
20 | }
21 |
22 | @Override public int getLocalPort(Server server) {
23 | return ((ServerConnector) server.getConnectors()[0]).getLocalPort();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/instrumentation/http-tests/src/main/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/http/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.http
7 |
--------------------------------------------------------------------------------
/instrumentation/http/src/main/java/brave/http/HttpClientResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.http;
6 |
7 | import brave.Span;
8 | import brave.internal.Nullable;
9 |
10 | /**
11 | * Marks an interface for use in {@link HttpClientHandler#handleReceive(HttpClientResponse, Span)}.
12 | * This gives a standard type to consider when parsing an incoming context.
13 | *
14 | * @see HttpClientRequest
15 | * @since 5.7
16 | */
17 | public abstract class HttpClientResponse extends HttpResponse {
18 | @Override public final Span.Kind spanKind() {
19 | return Span.Kind.CLIENT;
20 | }
21 |
22 | /** {@inheritDoc} */
23 | @Override @Nullable public HttpClientRequest request() {
24 | return null;
25 | }
26 |
27 | @Override public Throwable error() {
28 | return null; // error() was added in v5.10, but this type was added in v5.7
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/instrumentation/http/src/main/java/brave/http/HttpServerResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.http;
6 |
7 | import brave.Span;
8 | import brave.internal.Nullable;
9 |
10 | /**
11 | * Marks an interface for use in {@link HttpServerHandler#handleSend(Object, Throwable, Span)}. This
12 | * gives a standard type to consider when parsing an outgoing context.
13 | *
14 | * @see HttpServerRequest
15 | * @since 5.7
16 | */
17 | public abstract class HttpServerResponse extends HttpResponse {
18 | @Override public final Span.Kind spanKind() {
19 | return Span.Kind.SERVER;
20 | }
21 |
22 | /** {@inheritDoc} */
23 | @Override @Nullable public HttpServerRequest request() {
24 | return null;
25 | }
26 |
27 | @Override public Throwable error() {
28 | return null; // error() was added in v5.10, but this type was added in v5.7
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/instrumentation/http/src/test/java/brave/http/HttpResponseParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.http;
6 |
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static brave.http.HttpResponseParser.Default.catchAllName;
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class HttpResponseParserTest {
13 |
14 | @Test void catchAllName_redirect() {
15 | assertThat(catchAllName("GET", 307))
16 | .isEqualTo("GET redirected"); // zipkin will implicitly lowercase this
17 | }
18 |
19 | @Test void routeBasedName_notFound() {
20 | assertThat(catchAllName("DELETE", 404))
21 | .isEqualTo("DELETE not_found"); // zipkin will implicitly lowercase this
22 | }
23 |
24 | @Test void notCatchAll() {
25 | assertThat(catchAllName("GET", 304))
26 | .isNull(); // not redirect
27 | assertThat(catchAllName("DELETE", 500))
28 | .isNull(); // not redirect or not found
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/instrumentation/httpasyncclient/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-httpasyncclient
2 | This module contains a tracing decorator for [Apache HttpAsyncClient](https://hc.apache.org/httpcomponents-asyncclient-dev/) 4.0+.
3 | `TracingHttpAsyncClientBuilder` adds trace headers to outgoing requests. It
4 | then reports to Zipkin how long each request takes, along with relevant
5 | tags like the http url.
6 |
7 | To enable tracing, create your client using `TracingHttpAsyncClientBuilder`.
8 |
9 | ```java
10 | httpasyncclient = TracingHttpAsyncClientBuilder.create(tracing).build();
11 | ```
12 |
--------------------------------------------------------------------------------
/instrumentation/httpasyncclient/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.httpasyncclient
7 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-httpclient
2 | This module contains a tracing decorator for [Apache HttpClient](http://hc.apache.org/httpcomponents-client-4.3.x/index.html) 4.3+.
3 | `TracingHttpClientBuilder` adds trace headers to outgoing requests. It
4 | then reports to Zipkin how long each request takes, along with relevant
5 | tags like the http url.
6 |
7 | To enable tracing, create your client using `TracingHttpClientBuilder`.
8 |
9 | ```java
10 | httpclient = TracingHttpClientBuilder.create(tracing).build();
11 | ```
12 |
13 | You can also use `TracingCachingHttpClientBuilder` if you depend on
14 | `org.apache.httpcomponents:httpclient-cache`
15 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.httpclient
7 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/src/it/httpclient_floor/README.md:
--------------------------------------------------------------------------------
1 | # httpclient_floor
2 | This tests that TracingHttpClientBuilder can be used with httpclient 4.3
3 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/src/it/httpclient_floor/src/test/java/brave/httpclient_v43/ITTracingCachingHttpClientBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient_floor;
6 |
7 | class ITTracingCachingHttpClientBuilder
8 | extends brave.httpclient.ITTracingCachingHttpClientBuilder {
9 | }
10 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/src/it/httpclient_floor/src/test/java/brave/httpclient_v43/ITTracingHttpClientBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient_floor;
6 |
7 | class ITTracingHttpClientBuilder extends brave.httpclient.ITTracingHttpClientBuilder {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/httpclient/src/main/java/brave/httpclient/TracingHttpClientBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient;
6 |
7 | import brave.Tracing;
8 | import brave.http.HttpTracing;
9 | import org.apache.http.impl.client.HttpClientBuilder;
10 | import org.apache.http.impl.execchain.ClientExecChain;
11 |
12 | public final class TracingHttpClientBuilder extends HttpClientBuilder {
13 |
14 | public static HttpClientBuilder create(Tracing tracing) {
15 | return new TracingHttpClientBuilder(HttpTracing.create(tracing));
16 | }
17 |
18 | public static HttpClientBuilder create(HttpTracing httpTracing) {
19 | return new TracingHttpClientBuilder(httpTracing);
20 | }
21 |
22 | final HttpTracing httpTracing;
23 |
24 | TracingHttpClientBuilder(HttpTracing httpTracing) { // intentionally hidden
25 | if (httpTracing == null) throw new NullPointerException("HttpTracing == null");
26 | this.httpTracing = httpTracing;
27 | }
28 |
29 | @Override protected ClientExecChain decorateProtocolExec(ClientExecChain protocolExec) {
30 | return new TracingProtocolExec(httpTracing, protocolExec);
31 | }
32 |
33 | @Override protected ClientExecChain decorateMainExec(ClientExecChain exec) {
34 | return new TracingMainExec(httpTracing, exec);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-httpclient5
2 | This module contains a tracing decorator for [Apache HttpClient](http://hc.apache.org/httpcomponents-client-5.2.x/index.html) 5.2+.
3 | `HttpClient5Tracing` adds trace headers to outgoing requests. It
4 | then reports to Zipkin how long each request takes, along with relevant
5 | tags like the http url.
6 |
7 | To enable tracing, create your client using `HttpClient5Tracing`.
8 |
9 | ```java
10 | HttpClientBuilder httpClientBuilder = HttpClients.custom();
11 | httpclient = HttpClient5Tracing.newBuilder(httpTracing).create(httpClientBuilder);
12 | ```
13 |
14 | `HttpClient5Tracing` also supports `CachingHttpClientBuilder`, `HttpAsyncClientBuilder`,
15 | `CachingHttpAsyncClientBuilder`, `H2AsyncClientBuilder` and `CachingH2AsyncClientBuilder`.
16 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.httpclient5
7 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/src/main/java/brave/httpclient5/HttpResponseWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient5;
6 |
7 | import brave.http.HttpClientResponse;
8 | import brave.internal.Nullable;
9 | import org.apache.hc.core5.http.HttpResponse;
10 |
11 | final class HttpResponseWrapper extends HttpClientResponse {
12 | @Nullable final HttpRequestWrapper request;
13 | @Nullable final HttpResponse response;
14 | @Nullable final Throwable error;
15 |
16 | HttpResponseWrapper(@Nullable HttpResponse response, @Nullable HttpRequestWrapper request,
17 | @Nullable Throwable error) {
18 | this.request = request;
19 | this.response = response;
20 | this.error = error;
21 | }
22 |
23 | @Override
24 | @Nullable
25 | public Object unwrap() {
26 | return response;
27 | }
28 |
29 | @Override
30 | @Nullable
31 | public HttpRequestWrapper request() {
32 | return request;
33 | }
34 |
35 | @Override
36 | public Throwable error() {
37 | return error;
38 | }
39 |
40 | @Override
41 | public int statusCode() {
42 | if (response == null) {
43 | return 0;
44 | }
45 | return response.getCode();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/src/main/java/brave/httpclient5/TraceContextCloseScopeInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient5;
6 |
7 | import org.apache.hc.core5.http.EntityDetails;
8 | import org.apache.hc.core5.http.HttpRequest;
9 | import org.apache.hc.core5.http.HttpRequestInterceptor;
10 | import org.apache.hc.core5.http.HttpResponse;
11 | import org.apache.hc.core5.http.HttpResponseInterceptor;
12 | import org.apache.hc.core5.http.protocol.HttpContext;
13 |
14 | class TraceContextCloseScopeInterceptor implements HttpRequestInterceptor,
15 | HttpResponseInterceptor {
16 |
17 | @Override public void process(HttpRequest httpRequest, EntityDetails entityDetails,
18 | HttpContext httpContext) {
19 | HttpClientUtils.closeScope(httpContext);
20 | }
21 |
22 | @Override public void process(HttpResponse httpResponse,
23 | EntityDetails entityDetails, HttpContext httpContext) {
24 | HttpClientUtils.closeScope(httpContext);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/src/main/java/brave/httpclient5/TraceContextOpenScopeInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient5;
6 |
7 | import brave.propagation.CurrentTraceContext;
8 | import org.apache.hc.core5.http.EntityDetails;
9 | import org.apache.hc.core5.http.HttpRequest;
10 | import org.apache.hc.core5.http.HttpRequestInterceptor;
11 | import org.apache.hc.core5.http.HttpResponse;
12 | import org.apache.hc.core5.http.HttpResponseInterceptor;
13 | import org.apache.hc.core5.http.protocol.HttpContext;
14 |
15 | class TraceContextOpenScopeInterceptor implements HttpRequestInterceptor,
16 | HttpResponseInterceptor {
17 |
18 | final CurrentTraceContext currentTraceContext;
19 |
20 | public TraceContextOpenScopeInterceptor(CurrentTraceContext currentTraceContext) {
21 | this.currentTraceContext = currentTraceContext;
22 | }
23 |
24 | @Override public void process(HttpRequest httpRequest, EntityDetails entityDetails,
25 | HttpContext httpContext) {
26 | HttpClientUtils.openScope(httpContext, currentTraceContext);
27 | }
28 |
29 | @Override public void process(HttpResponse httpResponse,
30 | EntityDetails entityDetails, HttpContext httpContext) {
31 | HttpClientUtils.openScope(httpContext, currentTraceContext);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/httpclient5/src/test/java/brave/httpclient5/HttpResponseWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.httpclient5;
6 |
7 | import org.apache.hc.core5.http.HttpRequest;
8 | import org.apache.hc.core5.http.HttpResponse;
9 | import org.junit.jupiter.api.Test;
10 | import org.junit.jupiter.api.extension.ExtendWith;
11 | import org.mockito.Mock;
12 | import org.mockito.junit.jupiter.MockitoExtension;
13 |
14 | import static org.assertj.core.api.Assertions.assertThat;
15 | import static org.mockito.Mockito.when;
16 |
17 | @ExtendWith(MockitoExtension.class)
18 | public class HttpResponseWrapperTest {
19 | @Mock HttpRequest request;
20 | @Mock HttpResponse response;
21 |
22 | @Test void request() {
23 | assertThat(
24 | new HttpResponseWrapper(response, new HttpRequestWrapper(request, null), null).request()
25 | .unwrap())
26 | .isSameAs(request);
27 | }
28 |
29 | @Test void statusCode() {
30 | when(response.getCode()).thenReturn(200);
31 | assertThat(new HttpResponseWrapper(response, new HttpRequestWrapper(request, null),
32 | null).statusCode()).isEqualTo(200);
33 | }
34 |
35 | @Test void statusCode_zeroWhenNoResponse() {
36 | assertThat(new HttpResponseWrapper(null, new HttpRequestWrapper(request, null),
37 | null).statusCode()).isZero();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/instrumentation/jakarta-jms/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 | io.zipkin.brave
11 | brave-instrumentation-parent
12 | 6.3.1-SNAPSHOT
13 |
14 | 4.0.0
15 |
16 | brave-instrumentation-jakarta-jms
17 | Brave Instrumentation: JMS (Jakarta) - Relocation Artifact
18 |
19 |
20 | true
21 |
22 |
23 |
24 |
25 | brave-instrumentation-jms-jakarta
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/instrumentation/jaxrs2/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.jaxrs2
5 |
--------------------------------------------------------------------------------
/instrumentation/jaxrs2/src/test/java/brave/jaxrs2/ClientResponseContextWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jaxrs2;
6 |
7 | import brave.jaxrs2.TracingClientFilter.ClientResponseContextWrapper;
8 | import javax.ws.rs.client.ClientRequestContext;
9 | import javax.ws.rs.client.ClientResponseContext;
10 | import org.junit.jupiter.api.Test;
11 | import org.junit.jupiter.api.extension.ExtendWith;
12 | import org.mockito.Mock;
13 | import org.mockito.junit.jupiter.MockitoExtension;
14 |
15 | import static org.assertj.core.api.Assertions.assertThat;
16 | import static org.mockito.Mockito.when;
17 |
18 | @ExtendWith(MockitoExtension.class)
19 | public class ClientResponseContextWrapperTest {
20 | @Mock ClientRequestContext request;
21 | @Mock ClientResponseContext response;
22 |
23 | @Test void request() {
24 | assertThat(new ClientResponseContextWrapper(request, response).request().unwrap())
25 | .isSameAs(request);
26 | }
27 |
28 | @Test void statusCode() {
29 | when(response.getStatus()).thenReturn(200);
30 |
31 | assertThat(new ClientResponseContextWrapper(request, response).statusCode()).isEqualTo(200);
32 | }
33 |
34 | @Test void statusCode_zeroWhenNegative() {
35 | when(response.getStatus()).thenReturn(-1);
36 |
37 | assertThat(new ClientResponseContextWrapper(request, response).statusCode()).isZero();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/instrumentation/jaxrs2/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/jdbi3/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-jdbi3
2 |
3 | This includes [TracingSqlLogger][TracingSqlLogger] for the Jdbi instance that
4 | reports via Brave how long each query takes, along with relevant tags like the
5 | query.
6 |
7 | Example Usage:
8 | ```java
9 | SqlLogger sqlLogger = JdbiTracing.create(tracing).sqlLogger();
10 | jdbi.getConfig(SqlStatements.class).setSqlLogger(sqlLogger);
11 | ```
12 |
13 | ---
14 | [TracingSqlLogger]: src/main/java/brave/jdbi3/TracingSqlLogger.java
15 |
--------------------------------------------------------------------------------
/instrumentation/jdbi3/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server-jakarta/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.jakarta.jersey.server
7 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server-jakarta/src/test/java/brave/jakarta/jersey/server/ContainerRequestWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jersey.server;
6 |
7 | import brave.jakarta.jersey.server.TracingApplicationEventListener.ContainerRequestWrapper;
8 | import java.net.URI;
9 | import org.glassfish.jersey.server.ContainerRequest;
10 | import org.glassfish.jersey.server.ExtendedUriInfo;
11 | import org.junit.jupiter.api.Test;
12 |
13 | import static org.assertj.core.api.Assertions.assertThat;
14 | import static org.mockito.Mockito.mock;
15 | import static org.mockito.Mockito.when;
16 |
17 | public class ContainerRequestWrapperTest {
18 | ContainerRequest request = mock(ContainerRequest.class);
19 |
20 | @Test void path_prefixesSlashWhenMissing() {
21 | when(request.getPath(false)).thenReturn("bar");
22 |
23 | assertThat(new ContainerRequestWrapper(request).path())
24 | .isEqualTo("/bar");
25 | }
26 |
27 | @Test void url_derivedFromExtendedUriInfo() {
28 | ExtendedUriInfo uriInfo = mock(ExtendedUriInfo.class);
29 | when(request.getUriInfo()).thenReturn(uriInfo);
30 | when(uriInfo.getRequestUri()).thenReturn(URI.create("http://foo:8080/bar?hello=world"));
31 |
32 | assertThat(new ContainerRequestWrapper(request).url())
33 | .isEqualTo("http://foo:8080/bar?hello=world");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server-jakarta/src/test/java/brave/jakarta/jersey/server/EventParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jersey.server;
6 |
7 | import brave.SpanCustomizer;
8 | import org.glassfish.jersey.server.ContainerRequest;
9 | import org.glassfish.jersey.server.ExtendedUriInfo;
10 | import org.glassfish.jersey.server.monitoring.RequestEvent;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.Mock;
14 | import org.mockito.junit.jupiter.MockitoExtension;
15 |
16 | import static org.mockito.Mockito.verifyNoMoreInteractions;
17 | import static org.mockito.Mockito.when;
18 |
19 | @ExtendWith(MockitoExtension.class)
20 | public class EventParserTest {
21 | @Mock RequestEvent event;
22 | @Mock ContainerRequest request;
23 | @Mock ExtendedUriInfo uriInfo;
24 | @Mock SpanCustomizer customizer;
25 |
26 | EventParser eventParser = new EventParser();
27 |
28 | @Test void requestMatched_missingResourceMethodOk() {
29 | when(event.getContainerRequest()).thenReturn(request);
30 | when(request.getUriInfo()).thenReturn(uriInfo);
31 |
32 | eventParser.requestMatched(event, customizer);
33 |
34 | verifyNoMoreInteractions(customizer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server-jakarta/src/test/java/brave/jakarta/jersey/server/TracingApplicationEventListenerInjectionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jersey.server;
6 |
7 | import brave.Tracing;
8 | import brave.http.HttpTracing;
9 | import com.google.inject.AbstractModule;
10 | import com.google.inject.Guice;
11 | import com.google.inject.Injector;
12 | import org.junit.jupiter.api.AfterEach;
13 | import org.junit.jupiter.api.Test;
14 |
15 | import static org.assertj.core.api.Assertions.assertThat;
16 |
17 | public class TracingApplicationEventListenerInjectionTest {
18 | Tracing tracing = Tracing.newBuilder().build();
19 |
20 | Injector injector = Guice.createInjector(new AbstractModule() {
21 | @Override protected void configure() {
22 | bind(HttpTracing.class).toInstance(HttpTracing.create(tracing));
23 | }
24 | });
25 |
26 | @AfterEach void close() {
27 | tracing.close();
28 | }
29 |
30 | @Test void onlyRequiresHttpTracing() {
31 | assertThat(injector.getInstance(TracingApplicationEventListener.class))
32 | .isNotNull();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server-jakarta/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # mute logs that do not effect our tests
11 | logger.wadl.name=org.glassfish.jersey.server.wadl.WadlFeature
12 | logger.wadl.level=off
13 | logger.model.name=org.glassfish.jersey.internal.inject.Providers
14 | logger.model.level=off
15 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.jersey.server
7 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server/src/test/java/brave/jersey/server/ContainerRequestWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jersey.server;
6 |
7 | import brave.jersey.server.TracingApplicationEventListener.ContainerRequestWrapper;
8 | import java.net.URI;
9 | import org.glassfish.jersey.server.ContainerRequest;
10 | import org.glassfish.jersey.server.ExtendedUriInfo;
11 | import org.junit.jupiter.api.Test;
12 |
13 | import static org.assertj.core.api.Assertions.assertThat;
14 | import static org.mockito.Mockito.mock;
15 | import static org.mockito.Mockito.when;
16 |
17 | public class ContainerRequestWrapperTest {
18 | ContainerRequest request = mock(ContainerRequest.class);
19 |
20 | @Test void path_prefixesSlashWhenMissing() {
21 | when(request.getPath(false)).thenReturn("bar");
22 |
23 | assertThat(new ContainerRequestWrapper(request).path())
24 | .isEqualTo("/bar");
25 | }
26 |
27 | @Test void url_derivedFromExtendedUriInfo() {
28 | ExtendedUriInfo uriInfo = mock(ExtendedUriInfo.class);
29 | when(request.getUriInfo()).thenReturn(uriInfo);
30 | when(uriInfo.getRequestUri()).thenReturn(URI.create("http://foo:8080/bar?hello=world"));
31 |
32 | assertThat(new ContainerRequestWrapper(request).url())
33 | .isEqualTo("http://foo:8080/bar?hello=world");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server/src/test/java/brave/jersey/server/EventParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jersey.server;
6 |
7 | import brave.SpanCustomizer;
8 | import org.glassfish.jersey.server.ContainerRequest;
9 | import org.glassfish.jersey.server.ExtendedUriInfo;
10 | import org.glassfish.jersey.server.monitoring.RequestEvent;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.Mock;
14 | import org.mockito.junit.jupiter.MockitoExtension;
15 |
16 | import static org.mockito.Mockito.verifyNoMoreInteractions;
17 | import static org.mockito.Mockito.when;
18 |
19 | @ExtendWith(MockitoExtension.class)
20 | public class EventParserTest {
21 | @Mock RequestEvent event;
22 | @Mock ContainerRequest request;
23 | @Mock ExtendedUriInfo uriInfo;
24 | @Mock SpanCustomizer customizer;
25 |
26 | EventParser eventParser = new EventParser();
27 |
28 | @Test void requestMatched_missingResourceMethodOk() {
29 | when(event.getContainerRequest()).thenReturn(request);
30 | when(request.getUriInfo()).thenReturn(uriInfo);
31 |
32 | eventParser.requestMatched(event, customizer);
33 |
34 | verifyNoMoreInteractions(customizer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server/src/test/java/brave/jersey/server/TracingApplicationEventListenerInjectionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jersey.server;
6 |
7 | import brave.Tracing;
8 | import brave.http.HttpTracing;
9 | import com.google.inject.AbstractModule;
10 | import com.google.inject.Guice;
11 | import com.google.inject.Injector;
12 | import org.junit.jupiter.api.AfterEach;
13 | import org.junit.jupiter.api.Test;
14 |
15 | import static org.assertj.core.api.Assertions.assertThat;
16 |
17 | public class TracingApplicationEventListenerInjectionTest {
18 | Tracing tracing = Tracing.newBuilder().build();
19 |
20 | Injector injector = Guice.createInjector(new AbstractModule() {
21 | @Override protected void configure() {
22 | bind(HttpTracing.class).toInstance(HttpTracing.create(tracing));
23 | }
24 | });
25 |
26 | @AfterEach void close() {
27 | tracing.close();
28 | }
29 |
30 | @Test void onlyRequiresHttpTracing() {
31 | assertThat(injector.getInstance(TracingApplicationEventListener.class))
32 | .isNotNull();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/instrumentation/jersey-server/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # mute logs that do not effect our tests
11 | logger.wadl.name=org.glassfish.jersey.server.wadl.WadlFeature
12 | logger.wadl.level=off
13 | logger.model.name=org.glassfish.jersey.internal.inject.Providers
14 | logger.model.level=off
15 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Throwables
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.jakarta.jms
8 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/it/jms30/README.md:
--------------------------------------------------------------------------------
1 | # Jakarta JMS 3.0
2 | This tests that JmsTracing does work on Jakarta JMS 3.0 APIs
3 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/it/jms30/src/test/java/brave/jms/ITJmsTracingMessageConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | class ITJmsTracingMessageConsumer extends ITTracingMessageConsumer {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/it/jms30/src/test/java/brave/jms/ITJmsTracingMessageProducer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | class ITJmsTracingMessageProducer extends ITTracingMessageProducer {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/main/java/brave/jakarta/jms/MessageProperties.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | import brave.internal.Nullable;
8 | import jakarta.jms.Message;
9 |
10 | import static brave.internal.Throwables.propagateIfFatal;
11 | import static brave.jakarta.jms.JmsTracing.log;
12 |
13 | class MessageProperties {
14 | /**
15 | * Same as {@link Message#getStringProperty(String)}, just doesn't throw or coerce non-strings to
16 | * strings.
17 | */
18 | @Nullable static String getPropertyIfString(Message message, String name) {
19 | try {
20 | Object o = message.getObjectProperty(name);
21 | if (o instanceof String) return o.toString();
22 | return null;
23 | } catch (Throwable t) {
24 | propagateIfFatal(t);
25 | log(t, "error getting property {0} from message {1}", name, message);
26 | return null;
27 | }
28 | }
29 |
30 | /** Same as {@link Message#setStringProperty(String, String)}, just doesn't throw. */
31 | static void setStringProperty(Message message, String name, String value) {
32 | try {
33 | message.setStringProperty(name, value);
34 | } catch (Throwable t) {
35 | propagateIfFatal(t);
36 | log(t, "error setting property {0} on message {1}", name, message);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/main/java/brave/jakarta/jms/TracingConnectionConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | import jakarta.jms.ConnectionConsumer;
8 | import jakarta.jms.JMSException;
9 | import jakarta.jms.ServerSessionPool;
10 |
11 | final class TracingConnectionConsumer implements ConnectionConsumer {
12 | static ConnectionConsumer create(ConnectionConsumer delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("connectionConsumer == null");
14 | if (delegate instanceof TracingConnectionConsumer) return delegate;
15 | return new TracingConnectionConsumer(delegate, jmsTracing);
16 | }
17 |
18 | final ConnectionConsumer delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingConnectionConsumer(ConnectionConsumer delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public ServerSessionPool getServerSessionPool() throws JMSException {
27 | return TracingServerSessionPool.create(delegate.getServerSessionPool(), jmsTracing);
28 | }
29 |
30 | @Override public void close() throws JMSException {
31 | delegate.close();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/main/java/brave/jakarta/jms/TracingServerSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | import jakarta.jms.JMSException;
8 | import jakarta.jms.ServerSession;
9 | import jakarta.jms.Session;
10 |
11 | final class TracingServerSession implements ServerSession {
12 | static ServerSession create(ServerSession delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("serverSession == null");
14 | if (delegate instanceof TracingServerSession) return delegate;
15 | return new TracingServerSession(delegate, jmsTracing);
16 | }
17 |
18 | final ServerSession delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingServerSession(ServerSession delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public Session getSession() throws JMSException {
27 | return TracingSession.create(delegate.getSession(), jmsTracing);
28 | }
29 |
30 | @Override public void start() throws JMSException {
31 | delegate.start();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/main/java/brave/jakarta/jms/TracingServerSessionPool.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | import jakarta.jms.JMSException;
8 | import jakarta.jms.ServerSession;
9 | import jakarta.jms.ServerSessionPool;
10 |
11 | final class TracingServerSessionPool implements ServerSessionPool {
12 | static ServerSessionPool create(ServerSessionPool delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("serverSessionPool == null");
14 | if (delegate instanceof TracingServerSessionPool) return delegate;
15 | return new TracingServerSessionPool(delegate, jmsTracing);
16 | }
17 |
18 | final ServerSessionPool delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingServerSessionPool(ServerSessionPool delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public ServerSession getServerSession() throws JMSException {
27 | return TracingServerSession.create(delegate.getServerSession(), jmsTracing);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/main/java/brave/jakarta/jms/TracingXAJMSContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jakarta.jms;
6 |
7 | import jakarta.jms.JMSContext;
8 | import jakarta.jms.XAJMSContext;
9 | import javax.transaction.xa.XAResource;
10 |
11 | final class TracingXAJMSContext extends TracingJMSContext implements XAJMSContext {
12 | static XAJMSContext create(XAJMSContext delegate, JmsTracing jmsTracing) {
13 | if (delegate instanceof TracingXAJMSContext) return delegate;
14 | return new TracingXAJMSContext(delegate, jmsTracing);
15 | }
16 |
17 | TracingXAJMSContext(XAJMSContext delegate, JmsTracing jmsTracing) {
18 | super(delegate, jmsTracing);
19 | }
20 |
21 | @Override public JMSContext getContext() {
22 | return this;
23 | }
24 |
25 | @Override public XAResource getXAResource() {
26 | return ((XAJMSContext) delegate).getXAResource();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/instrumentation/jms-jakarta/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # don't log about missing DLQ config
11 | logger.artemis-server.name=org.apache.activemq.artemis.core.server
12 | logger.artemis-server.level=off
13 |
--------------------------------------------------------------------------------
/instrumentation/jms/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Throwables
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.jms
8 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/it/jms11/README.md:
--------------------------------------------------------------------------------
1 | # Jms 1.1
2 | This tests that JmsTracing does not rely on JMS 2.0 apis
3 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/it/jms11/src/test/java/brave/jms/ITJmsTracingMessageConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | class ITJmsTracingMessageConsumer extends ITJms_1_1_TracingMessageConsumer {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/it/jms11/src/test/java/brave/jms/ITJmsTracingMessageProducer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | class ITJmsTracingMessageProducer extends ITJms_1_1_TracingMessageProducer {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/JMS2_0.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.RetentionPolicy;
9 |
10 | /**
11 | * Indicates a type or method is only available since JMS 2.0, mainly to be careful so we don't
12 | * break JMS 1.1.
13 | *
14 | * For example, a wrapped method on a type present in JMS 1.1, but defined in JMS 2.0, should
15 | * not use {@linkplain Override}.
16 | */
17 | @java.lang.annotation.Documented
18 | @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
19 | @java.lang.annotation.Target({ElementType.TYPE, ElementType.METHOD}) @interface JMS2_0 {
20 | }
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/MessageProperties.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import brave.internal.Nullable;
8 | import javax.jms.Message;
9 |
10 | import static brave.internal.Throwables.propagateIfFatal;
11 | import static brave.jms.JmsTracing.log;
12 |
13 | class MessageProperties {
14 | /**
15 | * Same as {@link Message#getStringProperty(String)}, just doesn't throw or coerce non-strings to
16 | * strings.
17 | */
18 | @Nullable static String getPropertyIfString(Message message, String name) {
19 | try {
20 | Object o = message.getObjectProperty(name);
21 | if (o instanceof String) return o.toString();
22 | return null;
23 | } catch (Throwable t) {
24 | propagateIfFatal(t);
25 | log(t, "error getting property {0} from message {1}", name, message);
26 | return null;
27 | }
28 | }
29 |
30 | /** Same as {@link Message#setStringProperty(String, String)}, just doesn't throw. */
31 | static void setStringProperty(Message message, String name, String value) {
32 | try {
33 | message.setStringProperty(name, value);
34 | } catch (Throwable t) {
35 | propagateIfFatal(t);
36 | log(t, "error setting property {0} on message {1}", name, message);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/TracingConnectionConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import javax.jms.ConnectionConsumer;
8 | import javax.jms.JMSException;
9 | import javax.jms.ServerSessionPool;
10 |
11 | final class TracingConnectionConsumer implements ConnectionConsumer {
12 | static ConnectionConsumer create(ConnectionConsumer delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("connectionConsumer == null");
14 | if (delegate instanceof TracingConnectionConsumer) return delegate;
15 | return new TracingConnectionConsumer(delegate, jmsTracing);
16 | }
17 |
18 | final ConnectionConsumer delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingConnectionConsumer(ConnectionConsumer delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public ServerSessionPool getServerSessionPool() throws JMSException {
27 | return TracingServerSessionPool.create(delegate.getServerSessionPool(), jmsTracing);
28 | }
29 |
30 | @Override public void close() throws JMSException {
31 | delegate.close();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/TracingServerSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import javax.jms.JMSException;
8 | import javax.jms.ServerSession;
9 | import javax.jms.Session;
10 |
11 | final class TracingServerSession implements ServerSession {
12 | static ServerSession create(ServerSession delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("serverSession == null");
14 | if (delegate instanceof TracingServerSession) return delegate;
15 | return new TracingServerSession(delegate, jmsTracing);
16 | }
17 |
18 | final ServerSession delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingServerSession(ServerSession delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public Session getSession() throws JMSException {
27 | return TracingSession.create(delegate.getSession(), jmsTracing);
28 | }
29 |
30 | @Override public void start() throws JMSException {
31 | delegate.start();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/TracingServerSessionPool.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import javax.jms.JMSException;
8 | import javax.jms.ServerSession;
9 | import javax.jms.ServerSessionPool;
10 |
11 | final class TracingServerSessionPool implements ServerSessionPool {
12 | static ServerSessionPool create(ServerSessionPool delegate, JmsTracing jmsTracing) {
13 | if (delegate == null) throw new NullPointerException("serverSessionPool == null");
14 | if (delegate instanceof TracingServerSessionPool) return delegate;
15 | return new TracingServerSessionPool(delegate, jmsTracing);
16 | }
17 |
18 | final ServerSessionPool delegate;
19 | final JmsTracing jmsTracing;
20 |
21 | TracingServerSessionPool(ServerSessionPool delegate, JmsTracing jmsTracing) {
22 | this.delegate = delegate;
23 | this.jmsTracing = jmsTracing;
24 | }
25 |
26 | @Override public ServerSession getServerSession() throws JMSException {
27 | return TracingServerSession.create(delegate.getServerSession(), jmsTracing);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/main/java/brave/jms/TracingXAJMSContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.jms;
6 |
7 | import javax.jms.JMSContext;
8 | import javax.jms.XAJMSContext;
9 | import javax.transaction.xa.XAResource;
10 |
11 | @JMS2_0 final class TracingXAJMSContext extends TracingJMSContext implements XAJMSContext {
12 | static XAJMSContext create(XAJMSContext delegate, JmsTracing jmsTracing) {
13 | if (delegate instanceof TracingXAJMSContext) return delegate;
14 | return new TracingXAJMSContext(delegate, jmsTracing);
15 | }
16 |
17 | TracingXAJMSContext(XAJMSContext delegate, JmsTracing jmsTracing) {
18 | super(delegate, jmsTracing);
19 | }
20 |
21 | @Override public JMSContext getContext() {
22 | return this;
23 | }
24 |
25 | @Override public XAResource getXAResource() {
26 | return ((XAJMSContext) delegate).getXAResource();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/instrumentation/jms/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
10 | # don't log about missing DLQ config
11 | logger.artemis-server.name=org.apache.activemq.artemis.core.server
12 | logger.artemis-server.level=off
13 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.kafka.clients
7 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/it/kafka_floor/README.md:
--------------------------------------------------------------------------------
1 | # kafka_floor
2 | This tests that KafkaPropagation can be used with kafka-client v<2
3 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/it/kafka_floor/src/test/java/brave/kafka1/clients/ITKafkaTracing.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka_floor.clients;
6 |
7 | class ITKafkaTracing extends brave.kafka.clients.ITKafkaTracing {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/main/java/brave/kafka/clients/KafkaHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import brave.internal.Nullable;
8 | import org.apache.kafka.common.header.Header;
9 | import org.apache.kafka.common.header.Headers;
10 |
11 | import static brave.kafka.clients.KafkaTracing.log;
12 | import static java.nio.charset.StandardCharsets.UTF_8;
13 |
14 | final class KafkaHeaders {
15 | static void replaceHeader(Headers headers, String key, String value) {
16 | try {
17 | headers.remove(key);
18 | headers.add(key, value.getBytes(UTF_8));
19 | } catch (IllegalStateException e) {
20 | log(e, "error setting header {0} in headers {1}", key, headers);
21 | }
22 | }
23 |
24 | @Nullable static String lastStringHeader(Headers headers, String key) {
25 | Header header = headers.lastHeader(key);
26 | if (header == null || header.value() == null) return null;
27 | return new String(header.value(), UTF_8);
28 | }
29 |
30 | KafkaHeaders() {
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/main/java/brave/kafka/clients/KafkaTags.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import org.apache.kafka.clients.consumer.Consumer;
8 | import org.apache.kafka.clients.consumer.ConsumerRecord;
9 | import org.apache.kafka.clients.producer.Producer;
10 |
11 | /**
12 | * Tagging policy is not yet dynamic. The descriptions below reflect static policy.
13 | */
14 | final class KafkaTags {
15 | /**
16 | * Added on {@link KafkaTracing#producer(Producer) producer} and {@link
17 | * KafkaTracing#nextSpan(ConsumerRecord) processor} spans when the key not null or empty.
18 | *
19 | *
Note: this is not added on {@link KafkaTracing#consumer(Consumer) consumer} spans
20 | * as they represent a bulk task (potentially multiple keys).
21 | */
22 | static final String KAFKA_KEY_TAG = "kafka.key";
23 | static final String KAFKA_TOPIC_TAG = "kafka.topic";
24 | }
25 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/test/java/brave/kafka/clients/ITKafka.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import brave.messaging.MessagingTracing;
8 | import brave.test.ITRemote;
9 | import brave.test.util.AssertableCallback;
10 | import org.apache.kafka.clients.producer.Callback;
11 | import org.apache.kafka.clients.producer.RecordMetadata;
12 |
13 | abstract class ITKafka extends ITRemote {
14 | MessagingTracing messagingTracing = MessagingTracing.create(tracing);
15 | KafkaTracing kafkaTracing = KafkaTracing.create(messagingTracing);
16 |
17 | /** {@link #join()} waits for the callback to complete without any errors */
18 | static final class BlockingCallback implements Callback {
19 | final AssertableCallback delegate = new AssertableCallback<>();
20 |
21 | void join() {
22 | delegate.join();
23 | }
24 |
25 | @Override public void onCompletion(RecordMetadata metadata, Exception exception) {
26 | if (exception != null) {
27 | delegate.onError(exception);
28 | } else {
29 | delegate.onSuccess(metadata);
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/test/java/brave/kafka/clients/KafkaConsumerRequestSetterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import brave.propagation.Propagation;
8 | import brave.test.propagation.PropagationSetterTest;
9 | import java.util.stream.Collectors;
10 | import java.util.stream.StreamSupport;
11 | import org.apache.kafka.clients.consumer.ConsumerRecord;
12 |
13 | import static java.nio.charset.StandardCharsets.UTF_8;
14 |
15 | public class KafkaConsumerRequestSetterTest extends PropagationSetterTest {
16 | KafkaConsumerRequest request = new KafkaConsumerRequest(
17 | new ConsumerRecord<>("topic", 0, 1L, "key", "value")
18 | );
19 |
20 | @Override protected KafkaConsumerRequest request() {
21 | return request;
22 | }
23 |
24 | @Override protected Propagation.Setter setter() {
25 | return KafkaConsumerRequest.SETTER;
26 | }
27 |
28 | @Override protected Iterable read(KafkaConsumerRequest request, String key) {
29 | return StreamSupport.stream(request.delegate.headers().headers(key).spliterator(), false)
30 | .map(h -> new String(h.value(), UTF_8))
31 | .collect(Collectors.toList());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/test/java/brave/kafka/clients/KafkaConsumerRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import org.apache.kafka.clients.consumer.ConsumerRecord;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class KafkaConsumerRequestTest {
13 | ConsumerRecord record = new ConsumerRecord<>("top", 0, 1, "key", "value");
14 | KafkaConsumerRequest request = new KafkaConsumerRequest(record);
15 |
16 | @Test void operation() {
17 | assertThat(request.operation()).isEqualTo("receive");
18 | }
19 |
20 | @Test void topic() {
21 | assertThat(request.channelKind()).isEqualTo("topic");
22 | assertThat(request.channelName()).isEqualTo(record.topic());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/test/java/brave/kafka/clients/KafkaProducerRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.clients;
6 |
7 | import org.apache.kafka.clients.producer.ProducerRecord;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class KafkaProducerRequestTest {
13 | ProducerRecord record = new ProducerRecord<>("top", "key", "value");
14 | KafkaProducerRequest request = new KafkaProducerRequest(record);
15 |
16 | @Test void operation() {
17 | assertThat(request.operation()).isEqualTo("send");
18 | }
19 |
20 | @Test void topic() {
21 | assertThat(request.channelKind()).isEqualTo("topic");
22 | assertThat(request.channelName()).isEqualTo(record.topic());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/instrumentation/kafka-clients/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 | # uncomment to include kafka consumer configuration in test logs
10 | #logger.kafka-clients.name=org.apache.kafka.clients
11 | #logger.kafka-clients.level=info
12 | logger.kafkaunit.name=com.github.charithe.kafka
13 | logger.kafkaunit.level=off
14 | logger.kafka.name=zipkin2.collector.kafka
15 | logger.kafka.level=debug
16 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.kafka.streams
5 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/KafkaHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import brave.internal.Nullable;
8 | import org.apache.kafka.common.header.Header;
9 | import org.apache.kafka.common.header.Headers;
10 |
11 | import static java.nio.charset.StandardCharsets.UTF_8;
12 |
13 | final class KafkaHeaders {
14 | static void replaceHeader(Headers headers, String key, String value) {
15 | headers.remove(key);
16 | headers.add(key, value.getBytes(UTF_8));
17 | }
18 |
19 | @Nullable static String lastStringHeader(Headers headers, String key) {
20 | Header header = headers.lastHeader(key);
21 | if (header == null || header.value() == null) return null;
22 | return new String(header.value(), UTF_8);
23 | }
24 |
25 | KafkaHeaders() {
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/KafkaStreamsPropagation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import brave.propagation.Propagation.Getter;
8 | import brave.propagation.Propagation.Setter;
9 | import org.apache.kafka.common.header.Headers;
10 | import org.apache.kafka.streams.processor.api.ProcessingContext;
11 |
12 | final class KafkaStreamsPropagation {
13 | /**
14 | * Used by {@link KafkaStreamsTracing#nextSpan(ProcessingContext, Headers)} to extract a trace
15 | * context from a prior stage.
16 | */
17 | static final Getter GETTER = new Getter() {
18 | @Override public String get(Headers headers, String key) {
19 | return KafkaHeaders.lastStringHeader(headers, key);
20 | }
21 |
22 | @Override public String toString() {
23 | return "Headers::lastHeader";
24 | }
25 | };
26 |
27 | /** Used to inject the trace context between stages. */
28 | static final Setter SETTER = new Setter() {
29 | @Override public void put(Headers headers, String key, String value) {
30 | KafkaHeaders.replaceHeader(headers, key, value);
31 | }
32 |
33 | @Override public String toString() {
34 | return "Headers::replaceHeader";
35 | }
36 | };
37 |
38 | KafkaStreamsPropagation() {
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/KafkaStreamsTags.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import org.apache.kafka.streams.processor.ProcessorContext;
8 |
9 | /**
10 | * Tagging policy is not yet dynamic. The descriptions below reflect static policy.
11 | */
12 | class KafkaStreamsTags {
13 | /**
14 | * Added on {@link KafkaStreamsTracing#nextSpan(ProcessorContext)} when the key not null or
15 | * empty.
16 | */
17 | static final String KAFKA_STREAMS_APPLICATION_ID_TAG = "kafka.streams.application.id";
18 | static final String KAFKA_STREAMS_TASK_ID_TAG = "kafka.streams.task.id";
19 | }
20 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/TracingFixedKeyProcessorContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import brave.propagation.TraceContext;
8 | import org.apache.kafka.common.header.Headers;
9 | import org.apache.kafka.streams.processor.api.FixedKeyProcessorContext;
10 | import org.apache.kafka.streams.processor.api.FixedKeyRecord;
11 |
12 | /** Injects the initialization tracing context to record headers on forward */
13 | final class TracingFixedKeyProcessorContext
14 | extends TracingProcessingContext>
15 | implements FixedKeyProcessorContext {
16 |
17 | TracingFixedKeyProcessorContext(FixedKeyProcessorContext delegate,
18 | TraceContext.Injector injector, TraceContext context) {
19 | super(delegate, injector, context);
20 | }
21 |
22 | @Override public void forward(FixedKeyRecord r) {
23 | injector.inject(context, r.headers());
24 | delegate.forward(r);
25 | }
26 |
27 | @Override
28 | public void forward(FixedKeyRecord r, String s) {
29 | injector.inject(context, r.headers());
30 | delegate.forward(r, s);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/TracingFixedKeyProcessorSupplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import org.apache.kafka.streams.processor.api.FixedKeyProcessor;
8 | import org.apache.kafka.streams.processor.api.FixedKeyProcessorSupplier;
9 |
10 | class TracingFixedKeyProcessorSupplier
11 | implements FixedKeyProcessorSupplier {
12 | final KafkaStreamsTracing kafkaStreamsTracing;
13 | final String spanName;
14 | final FixedKeyProcessorSupplier delegateProcessorSupplier;
15 |
16 | TracingFixedKeyProcessorSupplier(KafkaStreamsTracing kafkaStreamsTracing,
17 | String spanName,
18 | FixedKeyProcessorSupplier processorSupplier) {
19 | this.kafkaStreamsTracing = kafkaStreamsTracing;
20 | this.spanName = spanName;
21 | this.delegateProcessorSupplier = processorSupplier;
22 | }
23 |
24 | /** This wraps process method to enable tracing. */
25 | @Override public FixedKeyProcessor get() {
26 | return new TracingFixedKeyProcessor<>(kafkaStreamsTracing, spanName,
27 | delegateProcessorSupplier.get());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/TracingProcessorContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import brave.propagation.TraceContext;
8 | import brave.propagation.TraceContext.Injector;
9 | import org.apache.kafka.common.header.Headers;
10 | import org.apache.kafka.streams.processor.api.ProcessorContext;
11 | import org.apache.kafka.streams.processor.api.Record;
12 |
13 | /** Injects the initialization tracing context to record headers on forward */
14 | final class TracingProcessorContext
15 | extends TracingProcessingContext>
16 | implements ProcessorContext {
17 |
18 | TracingProcessorContext(ProcessorContext delegate,
19 | Injector injector, TraceContext context) {
20 | super(delegate, injector, context);
21 | }
22 |
23 | @Override public void forward(Record r) {
24 | injector.inject(context, r.headers());
25 | delegate.forward(r);
26 | }
27 |
28 | @Override
29 | public void forward(Record r, String s) {
30 | injector.inject(context, r.headers());
31 | delegate.forward(r, s);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/main/java/brave/kafka/streams/TracingProcessorSupplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import org.apache.kafka.streams.processor.api.Processor;
8 | import org.apache.kafka.streams.processor.api.ProcessorSupplier;
9 |
10 | class TracingProcessorSupplier
11 | implements ProcessorSupplier {
12 | final KafkaStreamsTracing kafkaStreamsTracing;
13 | final String spanName;
14 | final ProcessorSupplier delegateProcessorSupplier;
15 |
16 | TracingProcessorSupplier(KafkaStreamsTracing kafkaStreamsTracing,
17 | String spanName,
18 | ProcessorSupplier processorSupplier) {
19 | this.kafkaStreamsTracing = kafkaStreamsTracing;
20 | this.spanName = spanName;
21 | this.delegateProcessorSupplier = processorSupplier;
22 | }
23 |
24 | /** This wraps process method to enable tracing. */
25 | @Override public Processor get() {
26 | return new TracingProcessor<>(kafkaStreamsTracing, spanName, delegateProcessorSupplier.get());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/test/java/brave/kafka/streams/ITKafkaStreams.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import brave.messaging.MessagingTracing;
8 | import brave.test.ITRemote;
9 | import brave.test.util.AssertableCallback;
10 | import org.apache.kafka.clients.producer.Callback;
11 | import org.apache.kafka.clients.producer.RecordMetadata;
12 |
13 | abstract class ITKafkaStreams extends ITRemote {
14 | MessagingTracing messagingTracing = MessagingTracing.create(tracing);
15 | KafkaStreamsTracing kafkaStreamsTracing = KafkaStreamsTracing.create(messagingTracing);
16 |
17 | /** {@link #join()} waits for the callback to complete without any errors */
18 | static final class BlockingCallback implements Callback {
19 | final AssertableCallback delegate = new AssertableCallback<>();
20 |
21 | void join() {
22 | delegate.join();
23 | }
24 |
25 | @Override public void onCompletion(RecordMetadata metadata, Exception exception) {
26 | if (exception != null) {
27 | delegate.onError(exception);
28 | } else {
29 | delegate.onSuccess(metadata);
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/test/java/brave/kafka/streams/KafkaHeadersTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.kafka.streams;
6 |
7 | import org.apache.kafka.clients.consumer.ConsumerRecord;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class KafkaHeadersTest {
13 | ConsumerRecord record = new ConsumerRecord<>("top", 0, 1, "key", "value");
14 |
15 | @Test void lastStringHeader() {
16 | record.headers().add("b3", new byte[] {'1'});
17 |
18 | assertThat(KafkaHeaders.lastStringHeader(record.headers(), "b3"))
19 | .isEqualTo("1");
20 | }
21 |
22 | @Test void lastStringHeader_null() {
23 | assertThat(KafkaHeaders.lastStringHeader(record.headers(), "b3")).isNull();
24 | }
25 |
26 | @Test void replaceHeader() {
27 | KafkaHeaders.replaceHeader(record.headers(), "b3", "1");
28 |
29 | assertThat(record.headers().lastHeader("b3").value())
30 | .containsExactly('1');
31 | }
32 |
33 | @Test void replaceHeader_replace() {
34 | record.headers().add("b3", new byte[0]);
35 | KafkaHeaders.replaceHeader(record.headers(), "b3", "1");
36 |
37 | assertThat(record.headers().lastHeader("b3").value())
38 | .containsExactly('1');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/instrumentation/kafka-streams/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 | # uncomment to include kafka consumer configuration in test logs
10 | #logger.kafka-clients.name=org.apache.kafka.clients
11 | #logger.kafka-clients.level=info
12 | logger.kafkaunit.name=com.github.charithe.kafka
13 | logger.kafkaunit.level=off
14 | logger.kafka.name=zipkin2.collector.kafka
15 | logger.kafka.level=debug
16 |
--------------------------------------------------------------------------------
/instrumentation/messaging/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.messaging
7 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/main/java/brave/messaging/ConsumerRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging;
6 |
7 | import brave.Span;
8 |
9 | import static brave.Span.Kind.CONSUMER;
10 |
11 | /**
12 | * Marks an interface for use in extraction and {@link MessagingRuleSampler}. This gives a standard
13 | * type to consider when parsing an incoming context.
14 | *
15 | * @since 5.9
16 | */
17 | public abstract class ConsumerRequest extends MessagingRequest {
18 | @Override public Span.Kind spanKind() {
19 | return CONSUMER;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/main/java/brave/messaging/ConsumerResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * @see ConsumerRequest
11 | * @since 5.13
12 | */
13 | public abstract class ConsumerResponse extends MessagingResponse {
14 | @Override public final Span.Kind spanKind() {
15 | return Span.Kind.CONSUMER;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/main/java/brave/messaging/MessagingResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging;
6 |
7 | import brave.Response;
8 | import brave.internal.Nullable;
9 |
10 | /**
11 | * Abstract response type used for parsing and sampling of messaging clients and servers.
12 | *
13 | * @see ProducerResponse
14 | * @see ConsumerResponse
15 | * @since 5.13
16 | */
17 | public abstract class MessagingResponse extends Response {
18 | /**
19 | * Information about the request that initiated this messaging response or {@code null} if
20 | * unknown.
21 | *
22 | * @since 5.13
23 | */
24 | @Override @Nullable public MessagingRequest request() {
25 | return null;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/main/java/brave/messaging/ProducerRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * Marks an interface for use in injection and {@link MessagingRuleSampler}. This gives a standard
11 | * type to consider when parsing an outgoing context.
12 | *
13 | * @since 5.9
14 | */
15 | public abstract class ProducerRequest extends MessagingRequest {
16 | @Override public Span.Kind spanKind() {
17 | return Span.Kind.PRODUCER;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/main/java/brave/messaging/ProducerResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * @see ProducerRequest
11 | * @since 5.13
12 | */
13 | public abstract class ProducerResponse extends MessagingResponse {
14 | @Override public final Span.Kind spanKind() {
15 | return Span.Kind.PRODUCER;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/instrumentation/messaging/src/test/java/brave/messaging/features/ExampleTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.messaging.features;
6 |
7 | import brave.Tracing;
8 | import brave.messaging.MessagingRuleSampler;
9 | import brave.messaging.MessagingTracing;
10 | import brave.sampler.RateLimitingSampler;
11 | import brave.sampler.Sampler;
12 | import brave.sampler.SamplerFunctions;
13 | import org.junit.jupiter.api.Test;
14 |
15 | import static brave.messaging.MessagingRequestMatchers.channelNameEquals;
16 | import static brave.messaging.MessagingRequestMatchers.operationEquals;
17 | import static org.mockito.Mockito.mock;
18 |
19 | public class ExampleTest {
20 | Tracing tracing = mock(Tracing.class);
21 | MessagingTracing messagingTracing;
22 |
23 | // This mainly shows that we don't accidentally rely on package-private access
24 | @Test void showConstruction() {
25 | messagingTracing = MessagingTracing.newBuilder(tracing)
26 | .consumerSampler(MessagingRuleSampler.newBuilder()
27 | .putRule(channelNameEquals("alerts"), Sampler.NEVER_SAMPLE)
28 | .putRule(operationEquals("receive"), RateLimitingSampler.create(100))
29 | .build())
30 | .producerSampler(SamplerFunctions.neverSample())
31 | .build();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/mongodb/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.mongodb
5 |
--------------------------------------------------------------------------------
/instrumentation/mongodb/src/it/mongodb_floor/README.md:
--------------------------------------------------------------------------------
1 | # mongodb_floor
2 | This tests that MongoDBTracing can be used with mongodb <5
3 |
--------------------------------------------------------------------------------
/instrumentation/mongodb/src/it/mongodb_floor/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.mongodb_floor;
6 |
7 | class ITMongoDBTracing extends brave.mongodb.ITMongoDBTracing {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBDriverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.mongodb;
6 |
7 | import brave.Span;
8 | import com.mongodb.ServerAddress;
9 | import org.junit.jupiter.api.Test;
10 | import org.junit.jupiter.api.extension.ExtendWith;
11 | import org.mockito.Mock;
12 | import org.mockito.junit.jupiter.MockitoExtension;
13 |
14 | import static org.mockito.Mockito.verify;
15 | import static org.mockito.Mockito.when;
16 |
17 | @ExtendWith(MockitoExtension.class)
18 | public class MongoDBDriverTest {
19 | @Mock ServerAddress serverAddress;
20 | @Mock Span span;
21 |
22 | @Test void setRemoteIpAndPort() {
23 | when(serverAddress.getHost()).thenReturn("127.0.0.1");
24 | when(serverAddress.getPort()).thenReturn(27017);
25 |
26 | MongoDBDriver.get().setRemoteIpAndPort(span, serverAddress);
27 |
28 | verify(span).remoteIpAndPort("127.0.0.1", 27017);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/instrumentation/mongodb/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/mysql/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-mysql
2 |
3 | This includes a MySQL statement interceptor that will report to Zipkin
4 | how long each statement takes, along with relevant tags like the query.
5 |
6 | To use it, append `?statementInterceptors=brave.mysql.TracingStatementInterceptor`
7 | to the end of the connection url.
8 |
9 | By default the service name corresponding to your database uses the format
10 | `mysql-${database}`, but you can append another property `zipkinServiceName` to customise it.
11 |
12 | `?statementInterceptors=brave.mysql.TracingStatementInterceptor&zipkinServiceName=myDatabaseService`
13 |
14 | The current tracing component is used at runtime. Until you have
15 | instantiated `brave.Tracing`, no traces will appear.
16 |
--------------------------------------------------------------------------------
/instrumentation/mysql/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.mysql
5 |
--------------------------------------------------------------------------------
/instrumentation/mysql/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/mysql6/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-mysql6
2 |
3 | This includes a mysql-connector-java 6+ statement interceptor that will report to Zipkin
4 | how long each statement takes, along with relevant tags like the query.
5 |
6 | To use it, append `?statementInterceptors=brave.mysql6.TracingStatementInterceptor`
7 | to the end of the connection url.
8 |
9 | By default the service name corresponding to your database uses the format
10 | `mysql-${database}`, but you can append another property `zipkinServiceName` to customise it.
11 |
12 | `?statementInterceptors=brave.mysql6.TracingStatementInterceptor&zipkinServiceName=myDatabaseService`
13 |
14 | The current tracing component is used at runtime. Until you have
15 | instantiated `brave.Tracing`, no traces will appear.
16 |
--------------------------------------------------------------------------------
/instrumentation/mysql6/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.mysql6
5 |
--------------------------------------------------------------------------------
/instrumentation/mysql6/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 | io.zipkin.brave
11 | brave-instrumentation-parent
12 | 6.3.1-SNAPSHOT
13 |
14 | 4.0.0
15 |
16 | brave-instrumentation-mysql6
17 | Brave Instrumentation: MySQL6
18 |
19 |
20 |
21 | brave.mysql6
22 |
23 | ${project.basedir}/../..
24 |
25 | 6.0.6
26 |
27 |
28 |
29 |
30 | mysql
31 | mysql-connector-java
32 | ${mysql-connector-java6.version}
33 | provided
34 |
35 |
36 |
37 | ${project.groupId}
38 | brave-tests
39 | ${project.version}
40 | test
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/instrumentation/mysql6/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/mysql8/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-mysql8
2 |
3 | This includes a mysql-connector-java 8+ query interceptor that will report to Zipkin
4 | how long each query takes, along with relevant tags like the query.
5 |
6 | To use it, append `?queryInterceptors=brave.mysql8.TracingQueryInterceptor`
7 | to the end of the connection url.
8 |
9 | It is also recommended to add the exception interceptor so errors are added to the span, e.g.,
10 | `?queryInterceptors=brave.mysql8.TracingQueryInterceptor&exceptionInterceptors=brave.mysql8.TracingExceptionInterceptor`
11 |
12 | By default, the service name corresponding to your database uses the format
13 | `mysql-${database}`, but you can append another property `zipkinServiceName` to customise it.
14 |
15 | `?queryInterceptors=brave.mysql8.TracingQueryInterceptor&exceptionInterceptors=brave.mysql8.TracingExceptionInterceptor&zipkinServiceName=myDatabaseService`
16 |
17 | The current tracing component is used at runtime. Until you have
18 | instantiated `brave.Tracing`, no traces will appear.
19 |
--------------------------------------------------------------------------------
/instrumentation/mysql8/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.mysql8
5 |
--------------------------------------------------------------------------------
/instrumentation/mysql8/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/netty-codec-http/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-netty-codec-http
2 |
3 | This module contains a tracing decorators for [Netty's Http Codec](https://github.com/netty/netty/tree/4.1/codec-http) 4.x.
4 |
5 | `NettyHttpTracing.serverHandler()` extracts trace state from incoming requests,
6 | and reports to Zipkin how long each take, along with relevant tags like the
7 | http url.
8 |
9 | ## Configuration
10 |
11 | To enable tracing for an http server you need to add it to your pipeline:
12 | ```java
13 | NettyHttpTracing nettyHttpTracing = NettyHttpTracing.create(httpTracing);
14 | ChannelPipeline pipeline = ch.pipeline();
15 | ... add your infrastructure handlers, in particular HttpRequestDecoder and HttpResponseEncoder
16 | pipeline.addLast("tracing", nettyHttpTracing.serverHandler());
17 | ... add your application handlers
18 | ```
19 |
--------------------------------------------------------------------------------
/instrumentation/netty-codec-http/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Platform
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.netty.http
8 |
--------------------------------------------------------------------------------
/instrumentation/netty-codec-http/src/main/java/brave/netty/http/NettyHttpTracing.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.netty.http;
6 |
7 | import brave.Span;
8 | import brave.Tracing;
9 | import brave.http.HttpServerRequest;
10 | import brave.http.HttpTracing;
11 | import io.netty.channel.ChannelDuplexHandler;
12 | import io.netty.util.AttributeKey;
13 |
14 | public final class NettyHttpTracing {
15 | static final AttributeKey REQUEST_ATTRIBUTE =
16 | AttributeKey.valueOf(HttpServerRequest.class.getName());
17 | static final AttributeKey SPAN_ATTRIBUTE = AttributeKey.valueOf(Span.class.getName());
18 |
19 | public static NettyHttpTracing create(Tracing tracing) {
20 | return new NettyHttpTracing(HttpTracing.create(tracing));
21 | }
22 |
23 | public static NettyHttpTracing create(HttpTracing httpTracing) {
24 | return new NettyHttpTracing(httpTracing);
25 | }
26 |
27 | final ChannelDuplexHandler serverHandler;
28 |
29 | NettyHttpTracing(HttpTracing httpTracing) { // intentionally hidden constructor
30 | serverHandler = new TracingHttpServerHandler(httpTracing);
31 | }
32 |
33 | /**
34 | * Returns a duplex handler that traces {@link io.netty.handler.codec.http.HttpRequest} messages.
35 | */
36 | public ChannelDuplexHandler serverHandler() {
37 | return serverHandler;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/instrumentation/netty-codec-http/src/test/java/brave/netty/http/HttpResponseWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.netty.http;
6 |
7 | import brave.http.HttpServerRequest;
8 | import brave.netty.http.TracingHttpServerHandler.HttpResponseWrapper;
9 | import io.netty.handler.codec.http.HttpResponse;
10 | import io.netty.handler.codec.http.HttpResponseStatus;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.Mock;
14 | import org.mockito.junit.jupiter.MockitoExtension;
15 |
16 | import static org.assertj.core.api.Assertions.assertThat;
17 | import static org.mockito.Mockito.when;
18 |
19 | @ExtendWith(MockitoExtension.class)
20 | public class HttpResponseWrapperTest {
21 | @Mock HttpServerRequest request;
22 | @Mock HttpResponse response;
23 | @Mock HttpResponseStatus status;
24 |
25 | @Test void request() {
26 | assertThat(new HttpResponseWrapper(request, response, null).request())
27 | .isSameAs(request);
28 | }
29 |
30 | @Test void statusCode() {
31 | when(response.status()).thenReturn(status);
32 | when(status.code()).thenReturn(200);
33 |
34 | assertThat(new HttpResponseWrapper(request, response, null).statusCode()).isEqualTo(200);
35 | }
36 |
37 | @Test void statusCode_zeroNoResponse() {
38 | assertThat(new HttpResponseWrapper(request, response, null).statusCode()).isZero();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/instrumentation/netty-codec-http/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=info
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-okhttp3
2 | This module contains a tracing decorators for [OkHttp](https://github.com/square/okhttp) 3.x.
3 |
4 | ## TracingCallFactory
5 | `TracingCallFactory` adds trace headers to outgoing requests. It
6 | then reports to Zipkin how long each request takes, along with relevant
7 | tags like the http url.
8 |
9 | To enable tracing, wrap your client using `TracingCallFactory`.
10 |
11 | ```java
12 | callFactory = TracingCallFactory.create(httpTracing, okhttp);
13 | ```
14 |
15 | ## TracingInterceptor
16 | Sometimes code must use `OkHttpClient`, not `Call.Factory`. When this is
17 | the case, you can add the network interceptor `TracingInterceptor`. Make
18 | sure you wrap the dispatcher's executor service.
19 |
20 | ```java
21 | new OkHttpClient.Builder()
22 | .dispatcher(new Dispatcher(
23 | httpTracing.tracing().currentTraceContext()
24 | .executorService(new Dispatcher().executorService())
25 | ))
26 | .addNetworkInterceptor(TracingInterceptor.create(httpTracing))
27 | .build()
28 | ```
29 |
30 | Note that when the keep-alive pool is full (backlog situation), this
31 | approach can result in broken traces. This limitation is not the case
32 | when using the call factory approach.
33 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | okhttp3;version="[3.11, 5)",\
3 | okio;version="[1.15,3)",\
4 | *
5 | Export-Package: \
6 | brave.okhttp3
7 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/it/okhttp3_floor/README.md:
--------------------------------------------------------------------------------
1 | # okhttp3_floor
2 | This tests that TracingCallFactory can be used with okhttp3 <3.12
3 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/it/okhttp3_floor/src/test/java/brave/okhttp3_v3/ITTracingCallFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.okhttp3_floor;
6 |
7 | class ITTracingCallFactory extends brave.okhttp3.ITTracingCallFactory {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/it/okhttp3_floor/src/test/java/brave/okhttp3_v3/ITTracingInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.okhttp3_floor;
6 |
7 | class ITTracingInterceptor extends brave.okhttp3.ITTracingInterceptor {
8 | }
9 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/test/java/brave/okhttp3/ResponseWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.okhttp3;
6 |
7 | import brave.okhttp3.TracingInterceptor.RequestWrapper;
8 | import brave.okhttp3.TracingInterceptor.ResponseWrapper;
9 | import okhttp3.Protocol;
10 | import okhttp3.Request;
11 | import okhttp3.Response;
12 | import org.junit.jupiter.api.Test;
13 |
14 | import static org.assertj.core.api.Assertions.assertThat;
15 |
16 | public class ResponseWrapperTest {
17 | RequestWrapper request =
18 | new RequestWrapper(new Request.Builder().url("http://localhost/foo").build());
19 | Response.Builder responseBuilder = new Response.Builder()
20 | .request(request.delegate)
21 | .protocol(Protocol.HTTP_1_1);
22 |
23 | @Test void request() {
24 | Response response = responseBuilder.code(200).message("ok").build();
25 |
26 | assertThat(new ResponseWrapper(request, response, null).request())
27 | .isSameAs(request);
28 | }
29 |
30 | @Test void statusCode() {
31 | Response response = responseBuilder.code(200).message("ok").build();
32 |
33 | assertThat(new ResponseWrapper(request, response, null).statusCode()).isEqualTo(200);
34 | }
35 |
36 | @Test void statusCode_zero() {
37 | Response response = responseBuilder.code(0).message("ice cream!").build();
38 |
39 | assertThat(new ResponseWrapper(request, response, null).statusCode()).isZero();
40 | assertThat(new ResponseWrapper(request, null, null).statusCode()).isZero();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/test/java/brave/okhttp3/TracingInterceptorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.okhttp3;
6 |
7 | import brave.Span;
8 | import brave.Tracing;
9 | import okhttp3.Interceptor;
10 | import org.junit.jupiter.api.AfterEach;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.Mock;
14 | import org.mockito.junit.jupiter.MockitoExtension;
15 |
16 | import static org.mockito.Mockito.verify;
17 | import static org.mockito.Mockito.verifyNoMoreInteractions;
18 | import static org.mockito.Mockito.when;
19 |
20 | @ExtendWith(MockitoExtension.class)
21 | public class TracingInterceptorTest {
22 | Tracing tracing = Tracing.newBuilder().build();
23 | @Mock Interceptor.Chain chain;
24 | @Mock Span span;
25 |
26 | @Test void parseRouteAddress_skipsOnNoop() {
27 | when(span.isNoop()).thenReturn(true);
28 | TracingInterceptor.parseRouteAddress(chain, span);
29 |
30 | verify(span).isNoop();
31 | verifyNoMoreInteractions(span);
32 | }
33 |
34 | @AfterEach void close() {
35 | tracing.close();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/instrumentation/okhttp3/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/rocketmq-client/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.rocketmq.client
7 |
--------------------------------------------------------------------------------
/instrumentation/rocketmq-client/src/test/java/brave/rocketmq/client/MessagePropertiesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.rocketmq.client;
6 |
7 | import org.apache.rocketmq.common.message.Message;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | public class MessagePropertiesTest {
13 | Message message = new Message();
14 |
15 | @Test void putUserProperty_noProperties() {
16 | message.putUserProperty("b3", "1");
17 |
18 | assertThat(message.getProperty("b3"))
19 | .isEqualTo("1");
20 | }
21 |
22 | @Test void putUserProperty_replace() {
23 | message.putUserProperty("b3", String.valueOf((byte) 0));
24 | message.putUserProperty("b3", "1");
25 |
26 | assertThat(message.getUserProperty("b3"))
27 | .isEqualTo("1");
28 | }
29 |
30 | @Test void getUserProperty_hasProperties() {
31 | message = new Message("topic", new byte[0]);
32 | message.putUserProperty("b3", "1");
33 |
34 | assertThat(message.getProperty("b3"))
35 | .isEqualTo("1");
36 | }
37 |
38 | @Test void getUserProperty_null() {
39 | assertThat(message.getProperty("b3")).isNull();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/instrumentation/rocketmq-client/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 | # stop huge spam
10 | logger.dockerclient.name=org.testcontainers.dockerclient
11 | logger.dockerclient.level=off
12 |
--------------------------------------------------------------------------------
/instrumentation/rpc/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.rpc
7 |
--------------------------------------------------------------------------------
/instrumentation/rpc/src/main/java/brave/rpc/RpcClientResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.rpc;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * Marks an interface for use in {@link RpcClientHandler#handleReceive(RpcClientResponse, Span)}.
11 | * This gives a standard type to consider when parsing an incoming context.
12 | *
13 | * @see RpcClientRequest
14 | * @since 5.10
15 | */
16 | public abstract class RpcClientResponse extends RpcResponse {
17 | @Override public final Span.Kind spanKind() {
18 | return Span.Kind.CLIENT;
19 | }
20 |
21 | /**
22 | * Like {@link RpcRequest#parseRemoteIpAndPort(Span)} for when the client library cannot read
23 | * socket information before a request is made.
24 | *
25 | * To reduce overhead, only implement this when not implementing {@link
26 | * RpcRequest#parseRemoteIpAndPort(Span)}.
27 | *
28 | * @since 5.10
29 | */
30 | // This is on the response object because clients often don't know their final IP until after the
31 | // request started.
32 | public boolean parseRemoteIpAndPort(Span span) {
33 | return false;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/instrumentation/rpc/src/main/java/brave/rpc/RpcServerResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.rpc;
6 |
7 | import brave.Span;
8 |
9 | /**
10 | * Marks an interface for use in {@link RpcServerHandler#handleSend(RpcServerResponse, Span)}. This
11 | * gives a standard type to consider when parsing an incoming context.
12 | *
13 | * @see RpcClientRequest
14 | * @since 5.10
15 | */
16 | public abstract class RpcServerResponse extends RpcResponse {
17 | @Override public final Span.Kind spanKind() {
18 | return Span.Kind.SERVER;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/instrumentation/rpc/src/test/java/brave/rpc/RpcClientRequestSetterTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.rpc;
6 |
7 | import brave.propagation.Propagation.Setter;
8 | import brave.test.propagation.PropagationSetterTest;
9 | import java.util.Collections;
10 | import java.util.LinkedHashMap;
11 | import java.util.Map;
12 |
13 | import static brave.rpc.RpcClientRequest.SETTER;
14 |
15 | public class RpcClientRequestSetterTest extends PropagationSetterTest {
16 | Map propagationFields = new LinkedHashMap<>();
17 |
18 | @Override protected RpcClientRequest request() {
19 | return new RpcClientRequest() {
20 | @Override public Object unwrap() {
21 | return null;
22 | }
23 |
24 | @Override public String method() {
25 | return null;
26 | }
27 |
28 | @Override public String service() {
29 | return null;
30 | }
31 |
32 | @Override protected void propagationField(String keyName, String value) {
33 | propagationFields.put(keyName, value);
34 | }
35 | };
36 | }
37 |
38 | @Override protected Setter setter() {
39 | return SETTER;
40 | }
41 |
42 | @Override protected Iterable read(RpcClientRequest request, String key) {
43 | String result = propagationFields.get(key);
44 | return result != null ? Collections.singletonList(result) : Collections.emptyList();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/instrumentation/rpc/src/test/java/brave/rpc/features/ExampleTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.rpc.features;
6 |
7 | import brave.Tracing;
8 | import brave.rpc.RpcRuleSampler;
9 | import brave.rpc.RpcTracing;
10 | import brave.sampler.RateLimitingSampler;
11 | import brave.sampler.Sampler;
12 | import brave.sampler.SamplerFunctions;
13 | import org.junit.jupiter.api.Test;
14 |
15 | import static brave.rpc.RpcRequestMatchers.methodEquals;
16 | import static brave.rpc.RpcRequestMatchers.serviceEquals;
17 | import static org.mockito.Mockito.mock;
18 |
19 | public class ExampleTest {
20 | Tracing tracing = mock(Tracing.class);
21 | RpcTracing rpcTracing;
22 |
23 | // This mainly shows that we don't accidentally rely on package-private access
24 | @Test void showConstruction() {
25 | rpcTracing = RpcTracing.newBuilder(tracing)
26 | .serverSampler(RpcRuleSampler.newBuilder()
27 | .putRule(serviceEquals("scribe"), Sampler.NEVER_SAMPLE)
28 | .putRule(methodEquals("Report"), RateLimitingSampler.create(100))
29 | .build())
30 | .clientSampler(SamplerFunctions.neverSample())
31 | .build();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/servlet-jakarta/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Throwables
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.jakarta.servlet
8 |
--------------------------------------------------------------------------------
/instrumentation/servlet/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use need to import to support brave.internal.Throwables
2 | # brave.internal.Nullable is not used at runtime.
3 | Import-Package: \
4 | brave.internal;braveinternal=true,\
5 | *
6 | Export-Package: \
7 | brave.servlet
8 |
--------------------------------------------------------------------------------
/instrumentation/servlet/src/it/servlet25/README.md:
--------------------------------------------------------------------------------
1 | # servlet-25
2 | This tests that TracingFilter does not rely on Servlet 3+ apis
3 |
--------------------------------------------------------------------------------
/instrumentation/spring-rabbit/bnd.bnd:
--------------------------------------------------------------------------------
1 | # We use brave.internal.Nullable, but it is not used at runtime.
2 | Import-Package: \
3 | !brave.internal*,\
4 | *
5 | Export-Package: \
6 | brave.spring.rabbit
7 |
--------------------------------------------------------------------------------
/instrumentation/spring-rabbit/src/main/java/brave/spring/rabbit/MessageHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.rabbit;
6 |
7 | import brave.internal.Nullable;
8 | import org.springframework.amqp.core.Message;
9 | import org.springframework.amqp.core.MessageProperties;
10 |
11 | class MessageHeaders {
12 | /**
13 | * If {@link MessageProperties} exist, this returns {@link MessageProperties#getHeader(String)} if
14 | * it is a string.
15 | */
16 | @Nullable static String getHeaderIfString(Message message, String name) {
17 | MessageProperties properties = message.getMessageProperties();
18 | if (properties == null) return null;
19 | Object o = properties.getHeader(name);
20 | if (o instanceof String) return o.toString();
21 | return null;
22 | }
23 |
24 | /**
25 | * If {@link MessageProperties} exist, this invokes {@link MessageProperties#setHeader(String,
26 | * Object)}.
27 | */
28 | static void setHeader(Message message, String name, String value) {
29 | MessageProperties properties = message.getMessageProperties();
30 | if (properties == null) return;
31 | properties.setHeader(name, value);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/spring-rabbit/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 | # stop huge spam
10 | logger.dockerclient.name=org.testcontainers.dockerclient
11 | logger.dockerclient.level=off
12 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-spring-web
2 | This module contains tracing interceptors for [Spring RestTemplate](https://spring.io/guides/gs/consuming-rest/).
3 | `TracingClientHttpRequestInterceptor` and `TracingAsyncClientHttpRequestInterceptor` add trace
4 | headers to outgoing requests. They then report to Zipkin how long each request took, along with
5 | relevant tags like the http url.
6 |
7 | ## Configuration
8 |
9 | Tracing always needs a bean of type `HttpTracing` configured. Make sure
10 | it is in place before proceeding. Here's an example in [XML](https://github.com/openzipkin/brave-webmvc-example/blob/master/webmvc25/src/main/webapp/WEB-INF/spring-webmvc-servlet.xml) and [Java](https://github.com/openzipkin/brave-webmvc-example/blob/master/webmvc4/src/main/java/brave/webmvc/TracingConfiguration.java).
11 |
12 | Then, wire `TracingClientHttpRequestInterceptor` and add it with the
13 | `RestTemplate.setInterceptors` method. If you are using `AsyncRestTemplate` and Spring 4.3+, you can
14 | wire `AsyncTracingClientHttpRequestInterceptor` and add it via `AsyncRestTemplate.setInterceptors`.
15 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.spring.web
5 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/src/it/spring3/README.md:
--------------------------------------------------------------------------------
1 | # spring3
2 | This tests that TracingClientHttpRequestInterceptor can be used without Spring 4
3 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/src/test/java/brave/spring/web/HttpRequestWrapperTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.web;
6 |
7 | import brave.spring.web.TracingClientHttpRequestInterceptor.HttpRequestWrapper;
8 | import java.net.URI;
9 | import org.junit.jupiter.api.Test;
10 | import org.springframework.http.HttpRequest;
11 |
12 | import static org.assertj.core.api.Assertions.assertThat;
13 | import static org.mockito.Mockito.mock;
14 | import static org.mockito.Mockito.when;
15 |
16 | public class HttpRequestWrapperTest {
17 | HttpRequest request = mock(HttpRequest.class);
18 |
19 | @Test void path() {
20 | when(request.getURI()).thenReturn(URI.create("http://localhost/api"));
21 |
22 | assertThat(new HttpRequestWrapper(request).path())
23 | .isEqualTo("/api");
24 | }
25 |
26 | // NOTE: While technically possible, it is not easy to make URI.getPath() return null!
27 | @Test void path_emptyToSlash() {
28 | when(request.getURI()).thenReturn(URI.create("http://localhost"));
29 |
30 | assertThat(new HttpRequestWrapper(request).path())
31 | .isEqualTo("/");
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/src/test/java/brave/spring/web/TracingAsyncClientHttpRequestInterceptorAutowireTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.web;
6 |
7 | import brave.Tracing;
8 | import brave.http.HttpTracing;
9 | import org.junit.jupiter.api.AfterEach;
10 | import org.junit.jupiter.api.Test;
11 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Configuration;
14 | import org.springframework.http.client.AsyncClientHttpRequestInterceptor;
15 |
16 | public class TracingAsyncClientHttpRequestInterceptorAutowireTest {
17 |
18 | @Configuration static class HttpTracingConfiguration {
19 | @Bean HttpTracing httpTracing() {
20 | return HttpTracing.create(Tracing.newBuilder().build());
21 | }
22 | }
23 |
24 | @AfterEach void close() {
25 | Tracing.current().close();
26 | }
27 |
28 | @Test void autowiredWithBeanConfig() {
29 | AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
30 | ctx.register(HttpTracingConfiguration.class);
31 | ctx.register(TracingAsyncClientHttpRequestInterceptor.class);
32 | ctx.refresh();
33 |
34 | ctx.getBean(AsyncClientHttpRequestInterceptor.class);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/src/test/java/brave/spring/web/TracingClientHttpRequestInterceptorAutowireTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.web;
6 |
7 | import brave.Tracing;
8 | import brave.http.HttpTracing;
9 | import org.junit.jupiter.api.AfterEach;
10 | import org.junit.jupiter.api.Test;
11 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Configuration;
14 | import org.springframework.http.client.ClientHttpRequestInterceptor;
15 |
16 | public class TracingClientHttpRequestInterceptorAutowireTest {
17 |
18 | @Configuration static class HttpTracingConfiguration {
19 | @Bean HttpTracing httpTracing() {
20 | return HttpTracing.create(Tracing.newBuilder().build());
21 | }
22 | }
23 |
24 | @AfterEach void close() {
25 | Tracing.current().close();
26 | }
27 |
28 | @Test void autowiredWithBeanConfig() {
29 | AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
30 | ctx.register(HttpTracingConfiguration.class);
31 | ctx.register(TracingClientHttpRequestInterceptor.class);
32 | ctx.refresh();
33 |
34 | ctx.getBean(ClientHttpRequestInterceptor.class);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/instrumentation/spring-web/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.spring.webmvc
5 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/src/it/servlet25/README.md:
--------------------------------------------------------------------------------
1 | # servlet-25
2 | This tests that TracingHandlerInterceptor does not rely on Servlet 3+ apis
3 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/src/it/servlet25/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/src/it/spring2/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/src/test/java/brave/spring/webmvc/ITSpanCustomizingHandlerInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.webmvc;
6 |
7 | import brave.test.http.Jetty9ServerController;
8 | import java.util.EnumSet;
9 | import javax.servlet.DispatcherType;
10 | import org.eclipse.jetty.servlet.ServletContextHandler;
11 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
12 |
13 | class ITSpanCustomizingHandlerInterceptor extends BaseITSpanCustomizingHandlerInterceptor {
14 | public ITSpanCustomizingHandlerInterceptor() {
15 | super(new Jetty9ServerController());
16 | }
17 |
18 | @Override protected void addDelegatingTracingFilter(ServletContextHandler handler) {
19 | handler.addFilter(DelegatingTracingFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
20 | }
21 |
22 | @Override
23 | protected void registerTestController(AnnotationConfigWebApplicationContext appContext) {
24 | appContext.register(Servlet3TestController.class); // the test resource
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/instrumentation/spring-webmvc/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/instrumentation/vertx-web/README.md:
--------------------------------------------------------------------------------
1 | # brave-instrumentation-vertx-web
2 |
3 | This module contains a routing context handler for [Vert.x Web](http://vertx.io/docs/vertx-web/js/)
4 | This extracts trace state from incoming requests. Then, it reports to
5 | Zipkin how long each request takes, along with relevant tags like the
6 | http url. Register this as an failure handler to ensure any errors are
7 | also sent to Zipkin.
8 |
9 | To enable tracing you need to set `order`, `handler` and `failureHandler`
10 | hooks:
11 | ```java
12 | vertxWebTracing = VertxWebTracing.create(httpTracing);
13 | routingContextHandler = vertxWebTracing.routingContextHandler();
14 | router.route()
15 | .order(-1) // applies before routes
16 | .handler(routingContextHandler)
17 | .failureHandler(routingContextHandler);
18 |
19 | // any routes you add are now traced, such as the below
20 | router.route("/foo").handler(ctx -> {
21 | ctx.response().end("bar");
22 | });
23 | ```
--------------------------------------------------------------------------------
/instrumentation/vertx-web/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.vertx.web
5 |
--------------------------------------------------------------------------------
/spring-beans/bnd.bnd:
--------------------------------------------------------------------------------
1 | Import-Package: \
2 | *
3 | Export-Package: \
4 | brave.spring.beans
5 |
--------------------------------------------------------------------------------
/spring-beans/src/it/spring2/README.md:
--------------------------------------------------------------------------------
1 | # spring2
2 | This tests that the brave.spring.beans package does not rely on Spring 3+ APIs.
3 |
--------------------------------------------------------------------------------
/spring-beans/src/it/spring2/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=WARN, console
2 | log4j.appender.console=org.apache.log4j.ConsoleAppender
3 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
4 | log4j.appender.console.layout.ConversionPattern=[%d{dd MMM yyyy HH:mm:ss,SSS}] - %m%n
5 |
6 |
--------------------------------------------------------------------------------
/spring-beans/src/main/java/brave/spring/beans/SingleBaggageFieldFactoryBean.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright The OpenZipkin Authors
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 | package brave.spring.beans;
6 |
7 | import brave.baggage.BaggageField;
8 | import brave.baggage.BaggagePropagationConfig;
9 | import brave.baggage.BaggagePropagationConfig.SingleBaggageField;
10 | import java.util.Collections;
11 | import java.util.List;
12 | import org.springframework.beans.factory.FactoryBean;
13 |
14 | /** Spring XML config does not support chained builders. This converts accordingly */
15 | public class SingleBaggageFieldFactoryBean implements FactoryBean {
16 | BaggageField field;
17 | List keyNames = Collections.emptyList();
18 |
19 | @Override public SingleBaggageField getObject() {
20 | SingleBaggageField.Builder builder = SingleBaggageField.newBuilder(field);
21 | if (keyNames != null) {
22 | for (String keyName : keyNames) {
23 | builder.addKeyName(keyName);
24 | }
25 | }
26 | return builder.build();
27 | }
28 |
29 | @Override public Class extends BaggagePropagationConfig> getObjectType() {
30 | return BaggagePropagationConfig.class;
31 | }
32 |
33 | @Override public boolean isSingleton() {
34 | return true;
35 | }
36 |
37 | public void setField(BaggageField field) {
38 | this.field = field;
39 | }
40 |
41 | public void setKeyNames(List keyNames) {
42 | if (keyNames == null) return;
43 | this.keyNames = keyNames;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/spring-beans/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | appenders=console
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=%d{ABSOLUTE} %-5p [%t] %C{2} (%F:%L) - %m%n
6 | rootLogger.level=warn
7 | rootLogger.appenderRefs=stdout
8 | rootLogger.appenderRef.stdout.ref=STDOUT
9 |
--------------------------------------------------------------------------------
/src/etc/header.txt:
--------------------------------------------------------------------------------
1 | Copyright The OpenZipkin Authors
2 | SPDX-License-Identifier: Apache-2.0
3 |
--------------------------------------------------------------------------------
/src/it/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 | it-repo
12 |
13 | true
14 |
15 |
16 |
17 | local.central
18 | @localRepositoryUrl@
19 |
20 | true
21 |
22 |
23 | true
24 |
25 |
26 |
27 |
28 |
29 | local.central
30 | @localRepositoryUrl@
31 |
32 | true
33 |
34 |
35 | true
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------