npm.io
3.1.0 • Published 2d ago

@opentelemetry/sdk-trace

Licence
Apache-2.0
Version
3.1.0
Deps
3
Size
422 kB
Vulns
0
Weekly
0
Stars
3.5K

OpenTelemetry Tracing SDK

NPM Published Version Apache License

This module contains the Trace SDK for opentelemetry-js.

Used standalone, this module provides methods for manual instrumentation of code, offering full control over span creation for client-side JavaScript (browser) and Node.js.

It does not provide automated instrumentation of known libraries, context propagation or distributed-context out-of-the-box.

Installation

npm install --save @opentelemetry/api
npm install --save @opentelemetry/sdk-trace

Usage

const { trace } = require('@opentelemetry/api');
const { TracerProvider } = require('@opentelemetry/sdk-trace');

// A trace is a collection of *spans*. Spans are created with a *Tracer*.
// Tracers are retrieved from a *TracerProvider*. Typically a global
// TracerProvider is registered with the OpenTelemetry API, so that subsequent
// api.trace.getTracer() calls can use it.
trace.setGlobalTracerProvider(new TracerProvider(/* ... */));

// Important: for tracing to track parent/child relationships between spans
// within a process and across services (distributed tracing), requires that
// a *context manager* and a *propagator* be registered. These are handled
// by separate packages. See section below.

// Now retrieve a tracer, and create a span with it.
const tracer = trace.getTracer('default');
const span = tracer.startSpan('a-span-name');

// Set a span attribute
span.setAttribute('key', 'value');

// We must end the spans so they become available for exporting.
span.end();
More complete tracing setup

As mentioned above, a full tracing setup typically requires a context manager for tracing parent/child relationships within a process and propagators for propagating tracing data across processes (distributed tracing). Context managers and propagators are provided by packages other than @opentelemetry/sdk-trace.

Most users should use one of the higher-level packages that provide a more convenient and complete setup of an OpenTelemetry SDK:

However, as a quick overview, the following shows roughly how tracing is setup for Node.js. (Which context manager, and sometimes which propagators, to use depends on the JavaScript runtime.)

const os = require('os');
const { context, propagation, trace } = require('@opentelemetry/api');
const { TracerProvider } = require('@opentelemetry/sdk-trace');
const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks');
const {
  CompositePropagator,
  W3CBaggagePropagator,
  W3CTraceContextPropagator,
} = require('@opentelemetry/core');

const contextManager = new AsyncLocalStorageContextManager();
context.setGlobalContextManager(contextManager);

const propagator = new CompositePropagator({
  propagators: [ new W3CTraceContextPropagator(), new W3CBaggagePropagator() ],
});
propagation.setGlobalPropagator(propagator);

const tracerProvider = new TracerProvider(/* ... */);
trace.setGlobalTracerProvider(tracerProvider);

process.on('SIGTERM', async () => {
  await tracerProvider.shutdown().catch(console.error);
  process.exit(128 + os.constants.signals.SIGTERM);
});
process.once('beforeExit', async () => {
  await tracerProvider.shutdown().catch(console.error);
});

Built-in Samplers

Sampler is used to make decisions on Span sampling.

AlwaysOn Sampler

Samples every trace regardless of upstream sampling decisions.

This is used as a default Sampler

const { AlwaysOnSampler, TracerProvider } = require("@opentelemetry/sdk-trace");

const tracerProvider = new TracerProvider({
  sampler: new AlwaysOnSampler()
});
AlwaysOff Sampler

Doesn't sample any trace, regardless of upstream sampling decisions.

const { AlwaysOffSampler, TracerProvider } = require("@opentelemetry/sdk-trace");

const tracerProvider = new TracerProvider({
  sampler: new AlwaysOffSampler()
});
TraceIdRatioBased Sampler

Samples some percentage of traces, calculated deterministically using the trace ID. Any trace that would be sampled at a given percentage will also be sampled at any higher percentage.

The TraceIDRatioSampler may be used with the ParentBasedSampler to respect the sampled flag of an incoming trace.

const {
  TracerProvider,
  TraceIdRatioBasedSampler,
} = require("@opentelemetry/sdk-trace");

const tracerProvider = new TracerProvider({
  // See details of ParentBasedSampler below
  sampler: new ParentBasedSampler({
    // Trace ID Ratio Sampler accepts a positional argument
    // which represents the percentage of traces which should
    // be sampled.
    root: new TraceIdRatioBasedSampler(0.5)
  });
});
ParentBased Sampler
  • This is a composite sampler. ParentBased helps distinguished between the following cases:
    • No parent (root span).
    • Remote parent with sampled flag true
    • Remote parent with sampled flag false
    • Local parent with sampled flag true
    • Local parent with sampled flag false

Required parameters:

  • root(Sampler) - Sampler called for spans with no parent (root spans)

Optional parameters:

  • remoteParentSampled(Sampler) (default: AlwaysOn)
  • remoteParentNotSampled(Sampler) (default: AlwaysOff)
  • localParentSampled(Sampler) (default: AlwaysOn)
  • localParentNotSampled(Sampler) (default: AlwaysOff)
Parent parent.isRemote() parent.isSampled() Invoke sampler
absent n/a n/a root()
present true true remoteParentSampled()
present true false remoteParentNotSampled()
present false true localParentSampled()
present false false localParentNotSampled()
const {
  AlwaysOffSampler,
  TracerProvider,
  ParentBasedSampler,
  TraceIdRatioBasedSampler,
} = require("@opentelemetry/sdk-trace");

const tracerProvider = new TracerProvider({
  sampler: new ParentBasedSampler({
    // By default, the ParentBasedSampler will respect the parent span's sampling
    // decision. This is configurable by providing a different sampler to use
    // based on the situation. See configuration details above.
    //
    // This will delegate the sampling decision of all root traces (no parent)
    // to the TraceIdRatioBasedSampler.
    // See details of TraceIdRatioBasedSampler above.
    root: new TraceIdRatioBasedSampler(0.5)
  })
});
AlwaysRecord Sampler

Wraps a delegate sampler and upgrades any NOT_RECORD (drop) decision to RECORD, ensuring all spans are recorded without changing the sampling rate. This is useful when you want to count or measure all spans (e.g. via a processor) while still controlling export costs through the delegate sampler.

const {
  TracerProvider,
  ParentBasedSampler,
  TraceIdRatioBasedSampler,
  createAlwaysRecordSampler,
} = require("@opentelemetry/sdk-trace");

const tracerProvider = new TracerProvider({
  // Wraps a 50% TraceIdRatioBased sampler so that dropped spans are still
  // recorded (but not exported by a sampling exporter).
  sampler: createAlwaysRecordSampler(new TraceIdRatioBasedSampler(0.5))
});

Example

See examples/basic-tracer-node for an end-to-end example, including exporting created spans.

License

Apache 2.0 - See LICENSE for more information.

Keywords