Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

jaeger-client

jaegertracing1.8mApache-2.03.19.0TypeScript support: definitely-typed

Jaeger binding for OpenTracing API for Node.js

readme

Build Status Coverage Status NPM Published Version OpenTracing 1.0 Enabled

Jaeger Bindings for OpenTracing API for Node.js

This is Jaeger's client side instrumentation library for Node.js that implements Javascript OpenTracing API 1.0.

Note that this library is not designed to run in the browser, only in the Node.js-backend servers. For browser-only version, see https://github.com/jaegertracing/jaeger-client-javascript.

See the OpenTracing tutorial for the introduction on using the OpenTracing API and the Jaeger SDK.

Contributing and Developing

Please see CONTRIBUTING.md.

Installation

npm install --save jaeger-client

Initialization

The Tracer defaults to sending spans over UDP to the jaeger-agent running on localhost; the jaeger-agent handles forwarding the spans to the jaeger-collector. When you are instantiating your client instance you can specify the sampler of your choice. The library support the following samplers:

SAMPLER KEY
Constant const
Probabilistic probabilistic
Rate Limiting ratelimiting
Remote remote

More information about sampling can be found here

var initTracer = require('jaeger-client').initTracer;

// See schema https://github.com/jaegertracing/jaeger-client-node/blob/master/src/configuration.js#L37
var config = {
  serviceName: 'my-awesome-service',
};
var options = {
  tags: {
    'my-awesome-service.version': '1.1.2',
  },
  metrics: metrics,
  logger: logger,
};
var tracer = initTracer(config, options);

Environment variables

The tracer can be initialized with values coming from environment variables:

var tracer = initTracerFromEnv(config, options);

None of the env vars are required and all of them can be overridden via properties on the config object.

Property Description
JAEGER_SERVICE_NAME The service name
JAEGER_AGENT_HOST The hostname for communicating with agent via UDP
JAEGER_AGENT_PORT The port for communicating with agent via UDP
JAEGER_AGENT_SOCKET_TYPE The family of socket. Must be either 'udp4' or 'udp6' ('udp4' by default).
JAEGER_ENDPOINT The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces
JAEGER_USER Username to send as part of "Basic" authentication to the collector endpoint
JAEGER_PASSWORD Password to send as part of "Basic" authentication to the collector endpoint
JAEGER_REPORTER_LOG_SPANS Whether the reporter should also log the spans
JAEGER_REPORTER_FLUSH_INTERVAL The reporter's flush interval (ms)
JAEGER_REPORTER_TIMEOUT The reporter's http timeout (ms)
JAEGER_SAMPLER_TYPE The sampler type
JAEGER_SAMPLER_PARAM The sampler parameter (number)
JAEGER_SAMPLER_MANAGER_HOST_PORT The HTTP endpoint when using the remote sampler, i.e. http://jaeger-agent:5778/sampling
JAEGER_SAMPLER_REFRESH_INTERVAL How often the remotely controlled sampler will poll jaeger-agent for the appropriate sampling strategy
JAEGER_TAGS 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
JAEGER_DISABLED Whether the tracer is disabled or not. If true, the default opentracing.NoopTracer is used.

By default, the client sends traces via UDP to the agent at localhost:6832. Use JAEGER_AGENT_HOST and JAEGER_AGENT_PORT to send UDP traces to a different host:port. If JAEGER_ENDPOINT is set, the client sends traces to the endpoint via HTTP, making the JAEGER_AGENT_HOST and JAEGER_AGENT_PORT unused. If JAEGER_ENDPOINT is secured, HTTP basic authentication can be performed by setting the JAEGER_USER and JAEGER_PASSWORD environment variables.

Reporting spans via HTTP

UDP has a hard size limit of 65,507 bytes; if the span is larger than this limit, the tracer will drop the span. To circumvent this, you can configure the tracer to directly send spans to the jaeger-collector over HTTP (skipping the jaeger-agent altogether).

var initTracer = require('jaeger-client').initTracer;

// See schema https://github.com/jaegertracing/jaeger-client-node/blob/master/src/configuration.js#L37
var config = {
  serviceName: 'my-awesome-service',
  reporter: {
    // Provide the traces endpoint; this forces the client to connect directly to the Collector and send
    // spans over HTTP
    collectorEndpoint: 'http://jaeger-collector:14268/api/traces',
    // Provide username and password if authentication is enabled in the Collector
    // username: '',
    // password: '',
  },
};
var options = {
  tags: {
    'my-awesome-service.version': '1.1.2',
  },
  metrics: metrics,
  logger: logger,
};
var tracer = initTracer(config, options);

Metrics and Logging

The metrics and logger objects shown in the above example must satisfy the MetricsFactory and Logger APIs respectively.

Prometheus metrics

This module brings a Prometheus(prom-client) integration to the internal Jaeger metrics.
The way to initialize the tracer with Prometheus metrics:

var PrometheusMetricsFactory = require('jaeger-client').PrometheusMetricsFactory;
var promClient = require('prom-client');

var config = {
  serviceName: 'my-awesome-service',
};
var namespace = config.serviceName;
var metrics = new PrometheusMetricsFactory(promClient, namespace);
var options = {
  metrics: metrics,
};
var tracer = initTracer(config, options);

Usage

The Tracer instance created by initTracer is OpenTracing-1.0 compliant. See opentracing-javascript for usage examples. Ensure that tracer.close() is called on application exit to flush buffered traces.

TChannel Span Bridging

Because tchannel-node does not have instrumentation for OpenTracing, Jaeger-Client exposes methods wrapping tchannel handlers, and encoded channels. An encoded channel is a channel wrapped in either a thrift encoder TChannelAsThrift, or json encoder TChannelAsJson. To wrap a server handler for thrift one can initialize a tchannel bridge, and wrap the encoded handler function with a tracedHandler decorator. The tchannel bridge takes an OpenTracing tracer, and a context factory. The context factory must be a function that returns a context with the methods 'getSpan', and 'setSpan' which retrieve and assign the span to the context respectively.

import { TChannelBridge } from 'jaeger-client';
import Context from 'some-conformant-context';

function contextFactory() {
  return new Context();
}

let bridge = new TChannelBridge(tracer, { contextFactory: contextFactory });
let server = new TChannel({ serviceName: 'server' });
server.listen(4040, '127.0.0.1');
let serverThriftChannel = TChannelAsThrift({
  channel: server,
  entryPoint: path.join(__dirname, 'thrift', 'echo.thrift'), // file path to a thrift file
});

let perProcessOptions = {};
serverThriftChannel.register(
  server,
  'Echo::echo',
  perProcessOptions,
  bridge.tracedHandler((perProcessOptions, req, head, body, callback) => {
    /* Your handler code goes here. */
  })
);

Outbound calls can be made in two ways, shown below.

Using encoded channel to create a request and calling request.send()

import { TChannelBridge } from 'jaeger-client';

let bridge = new TChannelBridge(tracer);
// Create the toplevel client channel.
let client = new TChannel();

// Create the client subchannel that makes requests.
let clientSubChannel = client.makeSubChannel({
  serviceName: 'server',
  peers: ['127.0.0.1:4040'],
});

let encodedThriftChannel = TChannelAsThrift({
  channel: clientSubChannel,
  entryPoint: path.join(__dirname, 'thrift', 'echo.thrift'), // file path to a thrift file
});

// wrap encodedThriftChannel in a tracing decorator
let tracedChannel = bridge.tracedChannel(encodedThriftChannel);

// The encodedThriftChannel's (also true for json encoded channels) request object can call 'send' directly.
let req = tracedChannel.request({
  serviceName: 'server',
  context: context, // must be passed through from the service handler shown above
  headers: { cn: 'echo' },
});

// headers should contain your outgoing tchannel headers if any.
// In this instance 'send' is being called on the request object, and not the channel.
req.send('Echo::echo', headers, { value: 'some-string' });

Using top level channel to create a request and calling encodedChannel.send(request)

let tracedChannel = bridge.tracedChannel(encodedThriftChannel);

// tracedChannel.channel refers to encodedThriftChannel's inner channel which
// is clientSubChannel in this instance.
let req = tracedChannel.channel.request({
  serviceName: 'server',
  headers: { cn: 'echo' },
  context: context, // must be passed through from the service handler shown above
  timeout: someTimeout,
});
// send() can be called directly on the tracing decorator
tracedChannel.send(req, 'Echo::echo', o.headers, { value: 'some-string' }, clientCallback);

Debug Traces (Forced Sampling)

Programmatically

The OpenTracing API defines a sampling.priority standard tag that can be used to affect the sampling of a span and its children:

span.setTag(opentracing_tags.SAMPLING_PRIORITY, 1);

Via HTTP Headers

Jaeger Tracer also understands a special HTTP Header jaeger-debug-id, which can be set in the incoming request, e.g.

curl -H "jaeger-debug-id: some-correlation-id" http://myhost.com

When Jaeger sees this header in the request that otherwise has no tracing context, it ensures that the new trace started for this request will be sampled in the "debug" mode (meaning it should survive all downsampling that might happen in the collection pipeline), and the root span will have a tag as if this statement was executed:

span.setTag('jaeger-debug-id', 'some-correlation-id');

This allows using Jaeger UI to find the trace by this tag.

Trace Buffer

Specify the reporter's flush interval (ms) with config.reporter.flushIntervalMs or JAEGER_REPORTER_FLUSH_INTERVAL. The default is 1000 ms.

Calling .close() on the tracer will properly flush and close composed objects, including the reporter and sampler. This prevents dropped traces in the event of an error or unexpected early termination prior to normal periodic flushing.

tracer.close(cb?)

Zipkin Compatibility

Support for Zipkin's B3 Propagation HTTP headers is provided by the ZipkinB3TextMapCodec, which can be configured instead of the default TextMapCodec.

The new codec can be used by registering it with a tracer instance as both an injector and an extractor:

let codec = new ZipkinB3TextMapCodec({ urlEncoding: true });

tracer.registerInjector(opentracing.FORMAT_HTTP_HEADERS, codec);
tracer.registerExtractor(opentracing.FORMAT_HTTP_HEADERS, codec);

This can prove useful when compatibility with existing Zipkin tracing/instrumentation is desired.

Webpack Compatibility

In order to bundle the library using webpack, e.g. for uploading code to an AWS Lambda function, it is required to copy the Jaeger thrift definition file into the output directory of the bundle:

{
  plugins: [
    new CopyPlugin([
      {
        from: require.resolve('jaeger-client/dist/src/jaeger-idl/thrift/jaeger.thrift'),
        to: 'jaeger-idl/thrift/jaeger.thrift',
      },
      {
        from: require.resolve('jaeger-client/dist/src/thriftrw-idl/agent.thrift'),
        to: 'thriftrw-idl/agent.thrift',
      },
    ]),
  ];
}

License

Apache 2.0 License.

changelog

Changes by Version

3.19.0 (2021-10-31)

  • Simplify bundling udp_sender (#530) -- Thorsten Nadel
  • Add sampling path for tracer sampler config (#532) (#533) -- 飞雪无情
  • Bump opentracing from 0.14.4 to 0.14.5 (#487) -- dependabot
  • Update uuid package to latest stable version (#516) -- Manuel Alejandro de Brito Fontes
  • Allow configuring http client timeout (#465) -- Yuri Shkuro
  • Report HTTP errors when flushing spans (#459) -- Espen Hovlandsdal
  • Fix env parsing of falsy values (#462) -- Gerrit-K
  • Stop testing with Node <v10; upgrade tchannel->4.x (#463) -- Yuri Shkuro
  • Upgrade xorshift@^1.1.1 (#442) -- Oliver Salzburg

3.18.1 (2020-08-14)

  • Always read thrift defs from ./ to better support bundling (#441) - Hendrik Liebau

3.18.0 (2020-04-21)

  • Upgrade to opentracing-javascript 0.14 (#117) - Yuri Shkuro
  • Add OpenTracing methods to get span and trace id (#425) - Sandes de Silva

3.17.2 (2020-02-07)

  • README: Clarify that this library is not designed to work in the browser.

3.17.1 (2019-10-22)

  • [bug fix] Do not apply adaptive sampler to child spans (#410) -- Yuri Shkuro
  • Add toString to reporters (#403) -- Andrea Di Giorgi

3.17.0 (2019-09-23)

  • Add option to support zipkin's shared span id between client and server spans (#399) -- Jonathan Monette
  • Allow specifying 128bit trace IDs via Configuration (#397) -- Aleksei Androsov
  • Add support for UDP over IPv6 (#396) -- Aleksei Androsov

3.16.0 (2019-09-09)

  • Support 128bit traceIDs (#361) - thanks @PaulMiami
  • Support delayed sampling (#380) - thanks @yurishkuro
  • All spans of a trace share sampling state (#377) - thanks @tiffon and @yurishkuro

3.15.0 (2019-05-10)

  • Avoid mutation of user's tags (#348) - Thanks @fapspirit
  • Support false values for the B3 Sampled header (#346) - Thanks @sebnow
  • Fix HTTP sender, consume response data to free up memory (#343) - Thanks @baldmaster
  • Transform IP for int32 representation to dot representation (#340) - Thanks @Etienne-Carriere

3.14.4 (2019-01-24)

  • Hard code version

3.14.3 (2019-01-24)

  • Nothing

3.14.2 (2019-01-24)

  • Actually fix issue where dist/src files were missing

3.14.1 (2019-01-24)

  • Fixed issue where dist/src files were missing

3.14.0 (2019-01-24)

  • Add setProcess method to LoggingReporter (#303) - thanks @isayme
  • Change Zipkin Codec to Not Inject Missing Parent (#305) - thanks @adinunzio84
  • Add missed contextKey option to initTracer (#308) - thanks @yepninja
  • Allow overriding codec's default baggage prefix (#310) - thanks @artemruts
  • Make zipkin codec use case insensetive headers (#309) - thanks @artemruts
  • Fix Span.log to return this (#316) - thanks @doubret
  • Support injecting and extracting into carriers without Object prototypes (#318) - thanks @ggoodman
  • Support canonical env variables (#311) - thanks @yepninja
  • Rename 'jaeger.hostname' tracer tag to 'hostname' (#333) - thanks @verma-varsha
  • Use the ip and hostname tags if provided (#336) - thanks @ledor473
  • Make TchannelBridge use semantic conventions when logging error to the span (#334) - thanks @verma-varsha

3.13.0 (2018-10-08)

3.12.0 (2018-08-10)

  • Rename "throttler-update" metric (#279) - thanks @yknx4
  • Add HTTP Sender (#280) - thanks @keitwb

3.11.0 (2018-07-09)

  • Add throttler (#246)
  • Use throttler for rate limiting (#248)
  • Make metrics consistent with Go/Java clients (#255) - thanks @eundoosong
  • Pass logger/metrics option to remote sampler, reporter (#257) - thanks @eundoosong
  • Update RateLimiter to scale credits on update (#264)
  • Replace Coveralls by Codecov (#269) - thanks @eundoosong
  • Add PrometheusMetricsFactory (#262) - thanks @eundoosong
  • Upgrade flow to v0.75 (#272) - thanks @TLadd
  • Pass object to prom-client metric to fix warning (#274) - thanks @eundoosong

3.10.0 (2018-03-02)

  • Made tracing headers configurable (#217) - thanks @astub
  • Add husky as a dev-dependency (#234)
  • Require Node 6.x for building (#235)

3.9.1 (2018-02-26)

  • Remove husky dependency as a temporary fix for #232

3.9.0 (2018-02-26)

  • RemoteReporter.close() now ensures that the buffer is flushed before invoking the callback (#224, #226) - thanks @MarckK
    • Fix Possible race condition in UDPSender #214
    • Fix Support callback in udpSender.flush #157
    • Fix Change SenderResponse.err to be a message string #32
  • Node 6.x is recommended for development
    • Add .nvmrc to tell husky precommit which Node version to use (#227)
  • Export Configuration class (#221)
  • Add engines field to package.json (#231)

3.8.0 (2018-01-24)

  • Log error when Thrift conversion fails (#184)
  • Throw error if serviceName is not provided (#192)
  • Flush only if process is set (#195)
  • Change default flush interval to 1sec (#196)

3.7.0 (2017-11-21)

  • Add support for Zipkin B3 header propagation (#175)

3.6.0 (2017-11-13)

New features:

  • Save baggage in span logs (#129)
  • Add BaggageRestrictionManager and BaggageSetter (#142)
  • Migrate to Apache license v2 (#159)
  • Randomize rate limiter balance on initialization (#161)

Bug fixes:

  • Trap exceptions from socket.send() (#137) - thanks @frankgreco
  • Use ip tag instead of peer.ipv4 in process (#125)
  • Log only span context (#153)
  • Fix buffer size counting bug and add logging to UDP sender (#151)

3.5.3 (2017-04-24)

  • Fix SamplingStrategyResponse strategyType (#110)

3.5.2 (2017-03-29)

  • Protect from exceptions in decodeURIComponent (#105)
  • Do not url-encode span context (#105)

3.5.1 (2017-03-07)

  • Fix bug where leaky bucket never fills up when creditsPerSecond < itemCost (#104)

3.5.0 (2017-03-06)

3.4.0 (2017-02-20)

  • Allow tags/logs with 'object' values and convert them to JSON (#102)

3.3.1 (2017-02-13)

  • Add TestUtils.getTags(span, ?keys)

3.3.0 (2017-02-09)

  • Make Configuration accept MetricsFactory, not Metrics

3.2.1 (2017-02-08)

  • Make sure initTracer passes options to the tracer
  • Do not wrap single RemoteReporter into CompositeReporter

3.2.0 (2017-02-04)

  • Remove the following dependencies
    • "deep-equal": "^1.0.1",
    • "long": "^3.2.0",
    • "js-yaml": "^3.6.1",
    • "jsonschema": "^1.1.0",
  • Move TestUtil.thriftSpansEqual and Util.combinations functions under tests/lib
  • Remove most methods from TestUtils because the same checks can be done via public API
  • Remove hasLogs method that was not particularly useful in practice because it compared the timestamp
  • Accept external timestamps in milliseconds since epoch (#94)
  • Expose TChannelBridge.inject method (#93)

3.1.0 (2017-02-02)

  • Added support for end to end crossdock integration tests.
  • Fixed bug where "peer.ipv4" tag was not being saved.
  • Fixed bug where tracer tags were being reported twice.
  • Updated sampler config to allow extra customization.

3.0.0 (2017-01-20)

  • Added re-sampling after setOperationName is called. This supports adaptive sampling in the cases where a span is given an operation name after it has been created.

1.3.0 (2016-12-13)

  • Updated tchannel bridge to take a context that provides 'getSpan', and 'setSpan' methods.
  • Added support for adaptive sampling.

1.2.0 (2016-11-15)

  • Tchannel bridge for handlers, and encoded channel requests.
  • Crossdock tchannel testing.
  • Added tests for reporters, samplers, and utils.
  • TestUtils doesn't use lodash anymore.
  • Opentracing now exposed through jaeger-client
  • Fixed bugs involving headers that don't contain any tracer state.

1.1.0 (2016-11-07)

  • Exposed opentracing module from jaeger.
  • Removed 'jaeger' object wrapper from config object.