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 content for Java's Tracers. #311

Merged
merged 2 commits into from
Jul 5, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 72 additions & 4 deletions content/guides/java/tracers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,75 @@
title: "Java: Tracers"
---

* Setting up your tracer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a small intro here? Something like:

A Tracer is the actual implementation that will record the spans and publish them somewhere. How your application handles the actual Tracer is up to you: either consume it directly throughout your application or store it in the GlobalTracer for easier usage with instrumented frameworks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, will add it.

* Using the Global Tracer
* Accessing the Active Span
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's missing this item: "Accessing the Active Span"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I covered that in the Scopes section (scopes.md, that is)

* Accessing tracer specific features.
#### Setting up your Tracer

A **Tracer** is the actual implementation that will record the **Span**s and publish them somewhere. How your application handles the actual **Tracer** is up to you: either consume it directly throughout your application or store it in the **GlobalTracer** for easier usage with instrumented frameworks.

Different **Tracer** implementations vary in how and what parameters they receive at initialization time, such as:

* Component name for this application's traces.
* Tracing endpoint.
* Tracing credentials.
* Sampling strategy.


For example, initializing the **Tracer** implementation of `Jaeger` might look like this:

```java
import io.opentracing.Tracer;

SamplerConfiguration samplerConfig = new SamplerConfiguration("const", 1);
ReporterConfiguration reporterConfig = new ReporterConfiguration(true, null, null, null, null);
Configuration config = new Configuration(service, samplerConfig, reporterConfig);

// Get the actual OpenTracing-compatible Tracer.
Tracer tracer = config.getTracer();
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be worth mentioning the Tracer Resolver as well. Something like:

If your tracer supports it, the TracerResolver can also be used. With this approach, there's no tracer-specific initialization code in your application: Tracer tracer = TracerResolver.resolveTracer();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes, had forgotten about it ;)


If your **Tracer** supports it, the [TracerResolver](https://github.com/opentracing-contrib/java-tracerresolver) can also be used. With this approach, there's no **Tracer**-specific initialization code in your application:

```java
Tracer tracer = TracerResolver.resolveTracer();
```

Once a **Tracer** instance is obtained, it can be used to manually create **Span**, or pass it to existing instrumentation for frameworks and libraries:

```java
// OpenTracing Redis client. It can be *any* OT-compatible tracer.
Tracer tracer = ...;
new TracingJedis(tracer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice name, I had to double check this was the real name, not a typo :D

```

#### Global Tracer

In order to not force the user to keep around a **Tracer**, the **io.opentracing.util** artifact includes a helper **GlobalTracer** class implementing the **io.opentracing.Tracer** interface, which, as the name implies, acts as as a global instance that can be used from anywhere. It works by forwarding all operations to another underlying **Tracer**, that will get registered at some future point.

By default, the underlying **Tracer** is a no-nop implementation.

```java
import io.opentracing.util.GlobalTracer;

// As part of initialization, pass it as an actual Tracer
// to code that will create Spans in the future.
new TracingJedis(GlobalTracer.get());

// Eventually register it, so all the calls to GlobalTracer.get()
// are forwarded to this object. Registration can happen only once.
Tracer tracer = new CustomTracer(...);
GlobalTracer.register(tracer);
...

// Create a Span as usually. This Span creation will happen
// using your CustomTracer.
Span span = GlobalTracer.get().buildSpan("foo").start();
```

#### Using Tracer specific features

For using **Tracer**-specific features, the instance needs to be casted back to the original type:

```java
((CustomTracer)tracer).customFeature(100);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should add a unwrap(Class<Tracer>) method to the interface, to avoid this cast here... Similar to what JPA has.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes, I wondered about the same. Sounds like we should open an Issue in the java repo to keep track of this potential improvement?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

```

**GlobalTracer** does not expose the original **Tracer**, and thus is not possible to use **Tracer**-specific features through it.