Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LocalTracer #111

Closed
codefromthecrypt opened this issue Nov 19, 2015 · 1 comment
Closed

Add LocalTracer #111

codefromthecrypt opened this issue Nov 19, 2015 · 1 comment

Comments

@codefromthecrypt
Copy link
Member

I've been playing around with what's needed for local tracing. Most notably, we need more precise timestamps than what System.currentTimeMillis gives. Here's an example

final class LocalTracer {
  private final ClientTracer clientTracer;
  private final ServerAndClientSpanState state;
  private final SpanCollector spanCollector;

  LocalTracer(ClientTracer clientTracer, ServerAndClientSpanState state, SpanCollector spanCollector) {
    this.clientTracer = clientTracer;
    this.state = state;
    this.spanCollector = spanCollector;
  }

  /**
   * Request a new local span, optionally providing the time it started.
   *
   * @param component component responsible for the operation
   * @param operation name of the operation that's begun
   * @param timestamp time the operation started, in epoch microseconds, or null if now.
   * @return metadata about the new span or null if one wasn't started due to sampling policy.
   * @see Constants#LOCAL_COMPONENT
   */
  SpanId startSpan(String component, String operation, @Nullable Long timestamp) {
    SpanId spanId = clientTracer.startNewSpan(operation);
    if (spanId == null) return null; // Don't calculate time if we aren't going to trace.

    com.twitter.zipkin.gen.BinaryAnnotation lc = new com.twitter.zipkin.gen.BinaryAnnotation();
    lc.setKey(Constants.LOCAL_COMPONENT);
    lc.setValue(component.getBytes(Util.UTF_8));
    lc.setAnnotation_type(AnnotationType.STRING);
    lc.setHost(state.getClientEndpoint());

    Span span = state.getCurrentClientSpan();
    synchronized (span) {
      span.setTimestamp(timestamp == null ? System.currentTimeMillis() * 1000 : timestamp);
      span.addToBinary_annotations(lc);
    }
    return spanId;
  }

  /** Log an annotation with a relative timestamp more precise than system time. */
  void submitAnnotation(String value, long timestamp) {
    Span span = state.getCurrentClientSpan();
    if (span == null) return;
    synchronized (span) {
      span.addToAnnotations(new Annotation(timestamp, value).setHost(state.getClientEndpoint()));
    }
  }

  /** Completes the span, which took {@code duration} microseconds. */
  public void finishSpan(long duration) {
    Span span = state.getCurrentClientSpan();
    if (span == null) return;

    synchronized (span) {
      span.setDuration(duration);
      spanCollector.collect(span);
    }

    state.setCurrentClientSpan(null);
    state.setCurrentClientServiceName(null);
  }
}
@kristofa
Copy link
Member

👍

codefromthecrypt pushed a commit that referenced this issue Nov 20, 2015
A local span can represent bootstrap, codec, file i/o or other activity
that notably impacts performance.

Local spans always have a binary annotation "lc" which indicates the
component name. Usings zipkin's UI or Api, you can query by for spans
that use a component like this: `lc=spring-boot`

Here's an example of allocating precise duration for a local span:
```java
tracer.startSpan("codec", "encode");
try {
  return codec.encode(input);
} finally {
  tracer.finishSpan();
}
```

Fixes #111
See openzipkin/zipkin#821
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants