Skip to content

Latest commit

 

History

History
 
 

jaeger-core

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Java Docs

Core

This module provides core tracing functionality for custom instrumentation.

Maven coordinates

<dependency>
    <groupId>io.jaegertracing</groupId>
    <artifactId>jaeger-core</artifactId>
    <version>$jaegerVersion</version>
</dependency>

Note that you'll most likely want to include a higher-level dependency that includes components sending data to a backend, like io.jaegertracing:jaeger-thrift.

Usage

Production

A tracer instance can be obtained via the io.jaegertracing.Configuration object. In the general case, the most appropriate way is to get a tracer that is configured based on environment variables, like:

Tracer tracer = Configuration.fromEnv().getTracer();

If a more complex customization is required, the builder pattern can be used, like:

CodecConfiguration codecConfiguration = new CodecConfiguration()
    .withCodec(Builtin.HTTP_HEADERS, codec1)
    .withCodec(Builtin.HTTP_HEADERS, codec2);

Configuration configuration = new Configuration("foo")
    .withCodec(codecConfiguration);

Tracer tracer = configuration.getTracer();

Multiple calls to Configuration#getTracer() result in the same tracer instance.

For more advanced cases, direct access to io.jaegertracing.internal.JaegerTracer.Builder might be required. Note that this class is not part of the public API and its usage should be avoided.

A tracer instance can be obtained from JaegerTracer.Builder like:

Tracer tracer = new JaegerTracer.Builder("myServiceName").build()

W3C Trace Context propagation

Jaeger Tracer supports W3C Trace Context propagation format.

Example configuration:

w3cCodec = new io.jaegertracing.internal.propagation.TraceContextCodec();
tracer = new JaegerTracer.Builder(serviceName)
  .registerInjector(Format.Builtin.HTTP_HEADERS, w3cCodec)
  .registerExtractor(Format.Builtin.HTTP_HEADERS, w3cCodec)
  ...

B3 propagation

Jaeger Tracer can also work in the environment where B3 propagation is used. This is mostly related to systems instrumented with Zipkin. Once you register B3TextMapCodec, Jaeger can join traces started by other Zipkin instrumented applications. This includes reading headers like X-B3-TraceId. Jaeger B3 implementation automatically propagates baggage and by default it uses baggage- prefix.

Example configuration:

b3Codec = new io.jaegertracing.internal.propagation.B3TextMapCodec();
tracer = new JaegerTracer.Builder(serviceName)
  .registerInjector(Format.Builtin.HTTP_HEADERS, b3Codec)
  .registerExtractor(Format.Builtin.HTTP_HEADERS, b3Codec)
  ...

Configuration via Environment

When obtaining a tracer instance using the io.jaegertracing.Configuration#fromEnv() method, values specified via system properties (-DJAEGER_SERVICE_NAME=foo) will override values specified via environment variables.

The following property names are available:

Property Required Description
JAEGER_SERVICE_NAME yes The service name
JAEGER_AGENT_HOST no The hostname for communicating with agent via UDP
JAEGER_AGENT_PORT no The port for communicating with agent via UDP
JAEGER_ENDPOINT no The traces endpoint, in case the client should connect directly to the Collector, like http://jaeger-collector:14268/api/traces
JAEGER_AUTH_TOKEN no Authentication Token to send as "Bearer" to the endpoint
JAEGER_USER no Username to send as part of "Basic" authentication to the endpoint
JAEGER_PASSWORD no Password to send as part of "Basic" authentication to the endpoint
JAEGER_PROPAGATION no Comma separated list of formats to use for propagating the trace context. Defaults to the standard Jaeger format. Valid values are jaeger, b3, and w3c
JAEGER_REPORTER_LOG_SPANS no Whether the reporter should also log the spans
JAEGER_REPORTER_MAX_QUEUE_SIZE no The reporter's maximum queue size
JAEGER_REPORTER_FLUSH_INTERVAL no The reporter's flush interval (ms)
JAEGER_SAMPLER_TYPE no The sampler type
JAEGER_SAMPLER_PARAM no The sampler parameter (number)
JAEGER_SAMPLER_MANAGER_HOST_PORT no The host name and port when using the remote controlled sampler
JAEGER_TAGS no A comma separated list of name = value tracer level tags, which get added to all reported spans. The value can also refer to an environment variable using the format ${envVarName:default}, where the :default is optional, and identifies a value to be used if the environment variable cannot be found

Setting JAEGER_AGENT_HOST/JAEGER_AGENT_PORT will make the client send traces to the agent via UdpSender. If the JAEGER_ENDPOINT environment variable is also set, the traces are sent to the endpoint, effectively making the JAEGER_AGENT_* vars ineffective.

When the JAEGER_ENDPOINT is set, the HttpSender is used when submitting traces to a remote endpoint, usually served by a Jaeger Collector. If the endpoint is secured, a HTTP Basic Authentication can be performed by setting the related environment vars. Similarly, if the endpoint expects an authentication token, like a JWT, set the JAEGER_AUTH_TOKEN environment variable. If the Basic Authentication environment variables and the Auth Token environment variable are set, Basic Authentication is used.

Obtaining Tracer via TracerResolver

Jaeger's Java Client also provides an implementation of the TracerResolver, allowing a Tracer to be obtained in a vendor neutral manner. This TracerResolver implementation uses the configuration via environment approach described above.

More information about using the TracerResolver can be found here.

Reporting internal metrics via Micrometer

The Jaeger Java Client collects internal metrics and is able to report them via Micrometer. To accomplish that, include the artifact io.jaegertracing:jaeger-micrometer as a dependency to your project. The integration should be done automatically via the service loader.

If you prefer a manual configuration, it can be done with a code similar to this:

MicrometerMetricsFactory metricsReporter = new MicrometerMetricsFactory();
Configuration configuration = new Configuration("myServiceName");
Tracer tracer = configuration
    .getTracerBuilder()
    .withMetricsFactory(metricsReporter)
    .build();

Log Correlation

The Jaeger Java Client supports log correlation by updating the logging context (MDC) with three variables: traceId, spanId, sampled.

To accomplish that, first create the MDCScopeManager using either default MDC field names:

MDCScopeManager scopeManager = new MDCScopeManager.Builder().build()

or with optional custom field names:

MDCScopeManager scopeManager = new MDCScopeManager
                               .Builder()
                               .withMDCTraceIdKey("CustomTraceId")
                               .withMDCSampledKey("customSampled")
                               .withMDCSpanIdKey("customSpanId")
                               .build();

Then instantiate the Jaegar Tracer with the MDCScopeManager:

JaegerTracer tracer = new JaegerTracer.Builder("serviceName")
                      .withScopeManager(scopeManager).build();

In order to have the trace info in the logs, a logging system that offers MDC functionality, such as log4j, needs to be configured with an appender containing a proper PatternLayout.

For example, this log4j2.xml configuration:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout
                    pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg% traceId=%X{traceId} spanId=%X{spanId} sampled=%X{sampled}%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug" additivity="false">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

might produce a log line like this:

[DEBUG] 2020-06-28 22:25:07.152 [main] LogExample - Your log message traceId=729b37ccf9c1549d spanId=729b37ccf9c1549d sampled=false

The Logstash configuration might look like this:

        <appender name="jsonConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LogstashEncoder">
                <includeMdcKeyName>traceId</includeMdcKeyName>
                <includeMdcKeyName>spanId</includeMdcKeyName>
                <includeMdcKeyName>sampled</includeMdcKeyName>
            </encoder>
        </appender>
        <root level="INFO">
            <appender-ref ref="jsonConsoleAppender"/>
        </root>

Development

Especially in unit tests, it's useful to have tracer that is not connected to tracing backend, but collects spans in memory:

Reporter reporter = new InMemoryReporter();
Sampler sampler = new ConstSampler(true);
Tracer tracer = new JaegerTracer.Builder(serviceName)
  .withReporter(reporter)
  .withSampler(sampler)
  .build();

See also: opentracing-java