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

com.github.kristofa.brave.ClientTracer Maven / Gradle / Ivy

There is a newer version: 3.7.0
Show newest version
package com.github.kristofa.brave;

import com.google.auto.value.AutoValue;

import com.github.kristofa.brave.SpanAndEndpoint.ClientSpanAndEndpoint;
import com.twitter.zipkin.gen.Span;
import com.twitter.zipkin.gen.zipkinCoreConstants;

import java.util.List;
import java.util.Random;

/**
 * Low level api that deals with client side of a request:
 *
 * 
    *
  1. Decide on tracing or not (sampling)
  2. *
  3. Sending client set / client received annotations
  4. *
* * It is advised that you use ClientRequestInterceptor and ClientResponseInterceptor which build * upon ClientTracer and provide a higher level api. * * @see ClientRequestInterceptor * @see ClientResponseInterceptor * @author kristof */ @AutoValue public abstract class ClientTracer extends AnnotationSubmitter { public static Builder builder() { return new AutoValue_ClientTracer.Builder(); } @Override abstract ClientSpanAndEndpoint spanAndEndpoint(); abstract Random randomGenerator(); abstract SpanCollector spanCollector(); abstract List traceFilters(); @AutoValue.Builder public abstract static class Builder { public Builder state(ServerAndClientSpanState state) { return spanAndEndpoint(ClientSpanAndEndpoint.create(state)); } abstract Builder spanAndEndpoint(ClientSpanAndEndpoint spanAndEndpoint); /** * Used to generate new trace/span ids. */ public abstract Builder randomGenerator(Random randomGenerator); public abstract Builder spanCollector(SpanCollector spanCollector); /** * Will be executed in order. If one returns false there will be no tracing and * next ones will not be executed anymore. So order is important. */ public abstract Builder traceFilters(List traceFilters); abstract ClientTracer build(); } /** * Sets 'client sent' event for current thread. */ public void setClientSent() { submitAnnotation(zipkinCoreConstants.CLIENT_SEND); } /** * Sets the 'client received' event for current thread. This will also submit span because setting a client received * event means this span is finished. */ public void setClientReceived() { Span currentSpan = spanAndEndpoint().span(); if (currentSpan != null) { submitAnnotation(zipkinCoreConstants.CLIENT_RECV); spanCollector().collect(currentSpan); spanAndEndpoint().state().setCurrentClientSpan(null); spanAndEndpoint().state().setCurrentClientServiceName(null); } } /** * Start a new span for a new client request that will be bound to current thread. The ClientTracer can decide to return * null in case this request should not be traced (eg sampling). * * @param requestName Request name. Should not be null or empty. * @return Span id for new request or null in case we should not trace this new client request. */ public SpanId startNewSpan(String requestName) { Boolean sample = spanAndEndpoint().state().sample(); if (Boolean.FALSE.equals(sample)) { spanAndEndpoint().state().setCurrentClientSpan(null); spanAndEndpoint().state().setCurrentClientServiceName(null); return null; } SpanId newSpanId = getNewSpanId(); if (sample == null) { // No sample indication is present. for (TraceFilter traceFilter : traceFilters()) { if (!traceFilter.trace(newSpanId.getSpanId(), requestName)) { spanAndEndpoint().state().setCurrentClientSpan(null); spanAndEndpoint().state().setCurrentClientServiceName(null); return null; } } } Span newSpan = new Span(); newSpan.setId(newSpanId.getSpanId()); newSpan.setTrace_id(newSpanId.getTraceId()); if (newSpanId.getParentSpanId() != null) { newSpan.setParent_id(newSpanId.getParentSpanId()); } newSpan.setName(requestName); spanAndEndpoint().state().setCurrentClientSpan(newSpan); return newSpanId; } /** * Override the service name that will be submitted in the annotations. *

* This should be set before submitting any annotations. So after invoking {@link ClientTracer#startNewSpan(String)} and * before {@link ClientTracer#setClientSent()}. * * @param serviceName should be the same as the name of the service the client is calling. */ public void setCurrentClientServiceName(String serviceName) { spanAndEndpoint().state().setCurrentClientServiceName(serviceName); } private SpanId getNewSpanId() { Span currentServerSpan = spanAndEndpoint().state().getCurrentServerSpan().getSpan(); long newSpanId = randomGenerator().nextLong(); if (currentServerSpan == null) { return SpanId.create(newSpanId, newSpanId, null); } return SpanId.create(currentServerSpan.getTrace_id(), newSpanId, currentServerSpan.getId()); } ClientTracer() { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy