All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.cloud.sleuth.Tracer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.sleuth;

import java.io.Closeable;

import org.springframework.cloud.sleuth.propagation.Propagator;
import org.springframework.lang.Nullable;

/**
 * This API was heavily influenced by Brave. Parts of its documentation were taken
 * directly from Brave.
 *
 * Using a tracer, you can create a root span capturing the critical path of a request.
 * Child spans can be created to allocate latency relating to outgoing requests.
 *
 * When tracing single-threaded code, just run it inside a scoped span: 
{@code
 * // Start a new trace or a span within an existing trace representing an operation
 * ScopedSpan span = tracer.startScopedSpan("encode");
 * try {
 *   // The span is in "scope" so that downstream code such as loggers can see trace IDs
 *   return encoder.encode();
 * } catch (RuntimeException | Error e) {
 *   span.error(e); // Unless you handle exceptions, you might not know the operation failed!
 *   throw e;
 * } finally {
 *   span.end();
 * }
 * }
* * When you need more features, or finer control, use the {@linkplain Span} type: *
{@code
 * // Start a new trace or a span within an existing trace representing an operation
 * Span span = tracer.nextSpan().name("encode").start();
 * // Put the span in "scope" so that downstream code such as loggers can see trace IDs
 * try (SpanInScope ws = tracer.withSpanInScope(span)) {
 *   return encoder.encode();
 * } catch (RuntimeException | Error e) {
 *   span.error(e); // Unless you handle exceptions, you might not know the operation failed!
 *   throw e;
 * } finally {
 *   span.end(); // note the scope is independent of the span. Always finish a span.
 * }
 * }
* * Both of the above examples report the exact same span on finish! * * @author OpenZipkin Brave Authors * @author Marcin Grzejszczak * @since 3.0.0 * @see Span * @see ScopedSpan * @see Propagator */ public interface Tracer extends BaggageManager { /** * This creates a new span based on the current span in scope. If there's no such span * a new trace will be created. * @return a child span or a new trace if no span was present */ Span nextSpan(); /** * This creates a new span whose parent is {@link Span}. If parent is {@code null} * then will create act as {@link #nextSpan()}. * @param parent parent span * @return a child span for the given parent, {@code null} if context was empty. */ Span nextSpan(@Nullable Span parent); /** * Makes the given span the "current span" and returns an object that exits that scope * on close. Calls to {@link #currentSpan()} and {@link #currentSpanCustomizer()} will * affect this span until the return value is closed. * * The most convenient way to use this method is via the try-with-resources idiom. * * When tracing in-process commands, prefer {@link #startScopedSpan(String)} which * scopes by default. * * Note: While downstream code might affect the span, calling this method, and calling * close on the result have no effect on the input. For example, calling close on the * result does not finish the span. Not only is it safe to call close, you must call * close to end the scope, or risk leaking resources associated with the scope. * @param span span to place into scope or null to clear the scope * @return scope with span in it */ Tracer.SpanInScope withSpan(@Nullable Span span); /** * Returns a new child span if there's a {@link #currentSpan()} or a new trace if * there isn't. The result is the "current span" until {@link ScopedSpan#end()} ()} is * called. * * Here's an example:
{@code
	 * ScopedSpan span = tracer.startScopedSpan("encode");
	 * try {
	 *   // The span is in "scope" so that downstream code such as loggers can see trace IDs
	 *   return encoder.encode();
	 * } catch (RuntimeException | Error e) {
	 *   span.error(e); // Unless you handle exceptions, you might not know the operation failed!
	 *   throw e;
	 * } finally {
	 *   span.end();
	 * }
	 * }
* @param name of the span in scope * @return span in scope */ ScopedSpan startScopedSpan(String name); /** * In some cases (e.g. when dealing with * {@link Propagator#extract(Object, Propagator.Getter)}'s we want to create a span * that has not yet been started, yet it's heavily configurable (some options are not * possible to be set when a span has already been started). We can achieve that by * using a builder. * @return a span builder */ Span.Builder spanBuilder(); /** * Builder for {@link TraceContext}. * @return a trace context builder */ TraceContext.Builder traceContextBuilder(); /** * Returns the {@link CurrentTraceContext}. Can be {@code null} so that we don't break * backward compatibility. * @return current trace context */ @Nullable default CurrentTraceContext currentTraceContext() { return null; } /** * Allows to customize the current span in scope. * @return current span customizer */ @Nullable SpanCustomizer currentSpanCustomizer(); /** * Retrieves the current span in scope or {@code null} if one is not available. * @return current span in scope */ @Nullable Span currentSpan(); /** * Scope of a span. Needs to be closed so that resources are let go (e.g. MDC is * cleared). */ interface SpanInScope extends Closeable { /** * Noop instance. */ SpanInScope NOOP = () -> { }; @Override void close(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy