Add more to the opentracing quick start guide
This commit is contained in:
parent
232801ab62
commit
6c29e2f658
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue