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

com.undefinedlabs.scope.ScopeTracer Maven / Gradle / Ivy

package com.undefinedlabs.scope;

import com.undefinedlabs.scope.clock.Clock;
import com.undefinedlabs.scope.clock.NtpClock;
import com.undefinedlabs.scope.events.EventFieldsFactory;
import com.undefinedlabs.scope.exceptions.UnsupportedFormatException;
import com.undefinedlabs.scope.propagation.Extractor;
import com.undefinedlabs.scope.propagation.Injector;
import com.undefinedlabs.scope.propagation.PropagationRegistry;
import com.undefinedlabs.scope.propagation.internal.TextMapCodec;
import com.undefinedlabs.scope.reporter.Reporter;
import com.undefinedlabs.scope.reporter.internal.NoopReporter;
import com.undefinedlabs.scope.scopemanager.DistributedContextScopeManager;
import com.undefinedlabs.scope.span.SpanTracker;
import com.undefinedlabs.scope.span.SpanTrackerData;
import com.undefinedlabs.scope.span.SpanTrackerImpl;
import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.propagation.Format;
import java.io.Closeable;

public class ScopeTracer implements io.opentracing.Tracer, Closeable {

  private final ScopeManager scopeManager;
  private final Clock clock;
  private final Reporter reporter;
  private final EventFieldsFactory eventFieldsFactory;
  private final PropagationRegistry propagationRegistry;
  private final SpanTracker spanTracker;

  private ScopeTracer(final ScopeTracer.Builder builder) {
    scopeManager = builder.scopeManager;
    clock = builder.clock;
    reporter = builder.reporter;
    eventFieldsFactory = builder.eventFieldsFactory;
    propagationRegistry = builder.propagationRegistry;
    spanTracker = builder.spanTracker;
  }

  @Override
  public ScopeManager scopeManager() {
    return scopeManager;
  }

  public Clock clock() {
    return clock;
  }

  public Reporter reporter() {
    return reporter;
  }

  public SpanTracker spanTracker() {
    return spanTracker;
  }

  public EventFieldsFactory eventFieldsFactory() {
    return eventFieldsFactory;
  }

  public PropagationRegistry propagationRegistry() {
    return propagationRegistry;
  }

  @Override
  public Span activeSpan() {
    return scopeManager().activeSpan();
  }

  @Override
  public Scope activateSpan(final Span span) {
    return scopeManager().activate(span);
  }

  @Override
  public SpanBuilder buildSpan(final String operationName) {
    return new com.undefinedlabs.scope.SpanBuilder(this, operationName);
  }

  @Override
  public  void inject(final SpanContext spanContext, final Format format, final C carrier) {
    final Injector injector = propagationRegistry().getInjector(format);
    if (injector == null) {
      throw new UnsupportedFormatException(format);
    }
    injector.inject((com.undefinedlabs.scope.SpanContext) spanContext, carrier);
  }

  @Override
  public  SpanContext extract(final Format format, final C carrier) {
    final Extractor extractor = propagationRegistry().getExtractor(format);
    if (extractor == null) {
      throw new UnsupportedFormatException(format);
    }
    return extractor.extract(carrier);
  }

  @Override
  public void close() {
    final SpanTrackerData spanTrackerData = spanTracker().close();

    for (final com.undefinedlabs.scope.Span span : spanTrackerData.getUnfinishedSpans()) {
      span.markUnfinished();
      span.finish();
    }

    reporter().close();
  }

  public void reportSpan(final com.undefinedlabs.scope.Span span) {
    reporter().report(span);
  }

  public void registerStartedSpan(final com.undefinedlabs.scope.Span span) {
    spanTracker().registerStartedSpan(span);
  }

  public void registerFinishedSpan(final com.undefinedlabs.scope.Span span) {
    spanTracker().registerFinishedSpan(span);
  }

  public static class Builder {

    private ScopeManager scopeManager;
    private Clock clock;
    private Reporter reporter;
    private final EventFieldsFactory eventFieldsFactory;
    private PropagationRegistry propagationRegistry = new PropagationRegistry();
    private final SpanTracker spanTracker;

    private Builder(
        final ScopeManager scopeManager,
        final Clock clock,
        final Reporter reporter,
        final EventFieldsFactory eventFieldsFactory,
        final SpanTracker spanTracker) {
      this.scopeManager = scopeManager;
      this.clock = clock;
      this.reporter = reporter;
      this.eventFieldsFactory = eventFieldsFactory;
      this.spanTracker = spanTracker;

      final TextMapCodec textMapCodec = TextMapCodec.newBuilder().withUseUrlEncoding(false).build();
      propagationRegistry.registerInjector(Format.Builtin.TEXT_MAP, textMapCodec);
      propagationRegistry.registerExtractor(Format.Builtin.TEXT_MAP, textMapCodec);

      final TextMapCodec httpHeadersCodec =
          TextMapCodec.newBuilder().withUseUrlEncoding(true).build();
      propagationRegistry.registerInjector(Format.Builtin.HTTP_HEADERS, httpHeadersCodec);
      propagationRegistry.registerExtractor(Format.Builtin.HTTP_HEADERS, httpHeadersCodec);
    }

    public Builder withScopeManager(final ScopeManager scopeManager) {
      this.scopeManager = scopeManager;
      return this;
    }

    public Builder withClock(final Clock clock) {
      this.clock = clock;
      return this;
    }

    public Builder withReporter(final Reporter reporter) {
      this.reporter = reporter;
      return this;
    }

    // Test purposes
    protected Builder withPropagationRegistry(final PropagationRegistry propagationRegistry) {
      this.propagationRegistry = propagationRegistry;
      return this;
    }

    public ScopeTracer build() {
      return new ScopeTracer(this);
    }

    public static Builder newDefault() {
      return new Builder(
          new DistributedContextScopeManager(),
          new NtpClock(),
          new NoopReporter(),
          EventFieldsFactory.INSTANCE,
          SpanTrackerImpl.INSTANCE);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy