Add more to the opentracing quick start guide

This commit is contained in:
Tyler Benson 2017-07-12 16:28:10 -07:00
parent 232801ab62
commit 6c29e2f658
2 changed files with 91 additions and 55 deletions

View File

@ -109,8 +109,8 @@ Check the dedicated project for the full documentation: [dd-java-agent](../dd-ja
### <a name="api"></a>Custom instrumentations using OpenTracing API
If you want to add custom instrumenting to your code, you have to use the OpenTracing API.
The official documentation can be found right here: [](https://github.com/opentracing/opentracing-java).
Rather than referencing classes directly from `dd-trace` (other than registering `DDTracer`), we strongly suggest using the [OpenTracing API](https://github.com/opentracing/opentracing-java).
[Additional documentation on the api](docs/opentracing-api.md) is also available.
Let's look at a simple example.

View File

@ -2,109 +2,145 @@
The Opentraction group offers an API to instrument your code.
This document is a kind of a "Quick start for the" official specifications: https://github.com/opentracing/specification
This document is a kind of a "quick start" for the official specification: https://github.com/opentracing/specification
There are several concepts expose by the OpenTracing API:
There are several concepts exposed by the OpenTracing API:
* The core API used for instrumenting the code
* The tracer implementations, in charge of generating physically the traces. For instance the Datadog Java Tracer generates
traces that can be consumed by the Datadog agent.
* The Asynchronous API to help developers managing their spans and traces in a concurrency context.
* The tracer implementations are in charge of capturing and reporting the traces. For instance `dd-trace` generates and reports traces to the Datadog trace agent.
* In-process trace propagation for trace consistency in a concurrent/asynchronous request context.
* Distributed trace propagation for when receiving a request and making external calls.
## OpenTracing Core API
Official documentation link: [Opentracting Tracer specification](https://github.com/opentracing/specification/blob/master/specification.md#tracer)
Official documentation link: [Opentracting Tracer specification](https://github.com/opentracing/specification/blob/master/specification.md)
The core API exposes 3 main objects:
* A **Tracer**
* A **Span**
* A collection of **Tags**
* A [Tracer](https://github.com/opentracing/specification/blob/master/specification.md#tracer)
* A [Span](https://github.com/opentracing/specification/blob/master/specification.md#span)
* A collection of **Tags** associated with a Span
### Tracers
The tracer is in charge of instantiate new spans, and sending them to the appropriate sink.
The tracer is in charge of instantiating new spans for a given context, and sending them to the appropriate sink when complete.
The tracer instantiate depends of the implementation you chose. For instance, the Datadog Java Tracer allows you
The tracer instantiation depends of the implementation you chose. For instance, `dd-trace` allows you
to send the traces to a logger or directly to a running Datadog agent.
```java
// Initialize the Datadog Java Tracer
Tracer tracer = new DDTracer();
// Initialize the Datadog Java Tracer to write traces to the log:
Tracer tracer = new DDTracer();
```
Once a tracer is instantiated, you can use it to create and manage span. OpenTracing defines a SpanBuilder accessible through
the method `buildSpan(String operationName)` to serve this purpose.
After a tracer is created, you will usually want to register it with the `GlobalTracer`
to make it accessible all OpenTracing instrumentation in your JVM.
```java
// Create a new Span with the operation name "componentTracking"
Span current = tracer.buildSpan("componentTracking").startActive();
io.opentracing.util.GlobalTracer.register(tracer);
```
This example creates a simple span referenced "componentTracking". The `startActive()` method starts a new span and set it
as the active. This means that all new spans created after will be related to this one as children. If a span is already
the active one, the new span will replace it.
### Spans
Once a tracer is instantiated, you can use it to create and manage span. OpenTracing defines a SpanBuilder
accessible through the method `buildSpan(String operationName)` to serve this purpose.
```java
// Create a new Span with the operation name "componentTracking"
ActiveSpan current = tracer.buildSpan("componentTracking").startActive();
```
This example creates a simple span referenced "componentTracking". The `startActive()` method starts a new span and sets it
as the active span. This means that any new span created going forward on the same thread will reference this as its' parent.
If another span is already active, the new span will replace it.
**A collection of related spans is called a trace.**
But, sometimes you need to create a span without promoting it as the active. If you want to do that, use the `startManual()`
Sometimes you need to create a span without promoting it as the active. If you want to do that, use the `startManual()`
method instead.
```java
// Create a span, but do not promoting it as the active span
Span anotherSpan = tracer.buildSpan("componentTracking").startManual();
// Create a span, but do not promoting it as the active span
Span anotherSpan = tracer.buildSpan("componentTracking").startManual();
```
Typically, span creations are made in the begging of the methods you want to trace.
Typically, span creations are made in the beginning of the methods you want to trace.
And of course, you need to finish/close the span in order to get the operation duration.
This is achieving using the `finish` method.
```java
// Finishing the tracing operation
current.finish()
// Finishing the tracing operation
current.finish()
```
**Be careful!!** You have to be sure that all children spans are finished/closed before calling the method on the root span.
If you don't do this, you may face to span incomplete issues or some traces/spans will not be reported by the tracer.
**Be careful!!** All children spans must be finished/closed before finishing the root span.
If child spans are unfinished when the parent attempts to finish, the span will remain incomplete and risk being unreported.
Now, you are able to create, start and stop very simple spans.
You can manipulate them at any time and add extra information using the tags.
Tags are local to the span. So, no tags will be inherit from the parent. In order to propagate meta accross all spans of a
trace, use the `baggageItems` (see right after).
You can manipulate them at any time and add contextual information using tags.
OpenTracing Tags are standardized meta and allow developers to add more value to the span.
### Tags
Tags are local to each span and no tags will be inherited from the parent. Information relevant to all spans in a trace
should be stored as [baggage](#baggage).
OpenTracing defines a [standard set of tags](https://github.com/opentracing/specification/blob/master/semantic_conventions.md#standard-span-tags-and-log-fields) and should be used appropriately. Custom tags can also be defined as needed.
```java
// Create a span, but do not promoting it as the active span
Span valuableSpan = tracer.
buildSpan("componentTracking")
.withTag("custom-meta", "some-useful-value")
.withTag(Tags.COMPONENT, "my-component-mysql")
.startActive();
// Create a span and set it as the active span
ActiveSpan valuableSpan = tracer.
buildSpan("componentTracking")
.withTag("custom-meta", "some-useful-value")
.withTag(Tags.COMPONENT, "my-component-mysql")
.startActive();
// Somewhere further in the code
Tags.HTTP_URL.setTag(valuableSpan, "https://my-endpoint/resource/item");
Tags.HTTP_STATUS.setTag(valuableSpan, 200);
// Somewhere further in the code
Tags.HTTP_URL.setTag(valuableSpan, "https://my-endpoint/resource/item");
Tags.HTTP_STATUS.setTag(valuableSpan, 200);
```
All standardized tags can be consulted there: [OpenTracing Semantic specification](https://github.com/opentracing/specification/blob/master/semantic_conventions.md)
### Baggage
So, tags are local to the span. If you want set for meta for a trace, you have to use `baggabeItems` instead.
Baggage are very similar to the tags, but they have a powerful capabilities:
* A baggage is attached to all spans of a trace.
* A baggage is propagated outside the trace context via Http or Tcp protocols (depends of the tracer implementation).
Information relevant for the entire trace is stored as baggage.
Baggage is very similar to tags, but has important distinctions. Baggage is:
* Associated with all spans for a trace.
* Propagated outside the trace context via HTTP or Messaging protocols (depends of the tracer implementation).
```java
// Like tags, you can add baggage item to the span
valuableSpan.setBaggageItem("username", "@gpolaert");
// Like tags, you can add baggage item to the span
valuableSpan.setBaggageItem("username", "modernmajorgeneral");
```
## OpenTracing Asynchronous API
see WIP: https://github.com/opentracing/specification/issues/23
An `ActiveSpan` can generate a `Continuation` as a way of propagating traces from across a thread boundary.
On the parent thread:
```java
Continuation spanContinuation = valuableSpan.capture();
// pass the continuation onto a new thread
```
On a different thread:
```java
ActiveSpan valuableSpan = spanContinuation.activate();
// span is now active on the new thread
```
## OpenTracing Cross Process Propagation
Spans are associated across processes in a trace via the `Tracer.extract` and `Tracer.inject` methods.
```java
// On the start of a new trace in an application, associate incoming request with existing traces.
SpanContext spanCtx = tracer.extract(Format.Builtin.HTTP_HEADERS, someTextMapInstance);
ActiveSpan currentSpan = tracer.buildSpan("componentTracking").asChildOf(spanCtx).startActive();
```
```java
// When making an external call propagate the trace by injecting it into the carrier...
tracer.inject(currentSpan.context(), Format.Builtin.HTTP_HEADERS, someTextMapInstance);
```