js/opentelemetry/sdk

js/opentelemetry/sdk.ts

fino:opentelemetry/sdk - SDK wiring, exporters, resources, and propagation.

This module contains the cross-signal OpenTelemetry SDK surface. Stable application-facing exports are SDK classes, processors, readers, exporters, resources, propagation helpers, and runtime instrumentation classes. The lower-level runtime topic helpers re-exported here are compatibility support for advanced integrations; prefer the task APIs documented in opentelemetry/guide.md for application code.

Use this module to start telemetry collection, configure processors and metric readers, export records to memory or OTLP/HTTP JSON, install runtime instrumentations, manage resources, and propagate trace context through carriers.

OtelSDK.start() is idempotent. flush() drains queued span and log processors, collects observable metrics, and exports reader batches. shutdown() flushes first, then disposes instrumentations and readers. The OTLP exporter defaults to http://127.0.0.1:4318 with signal-specific /v1/traces, /v1/logs, and /v1/metrics paths.

import { BatchSpanProcessor, InMemoryExporter, OtelSDK } from 'fino:opentelemetry/sdk';

const memory = new InMemoryExporter();
const sdk = new OtelSDK({
  exporters: [memory],
  spanProcessors: [new BatchSpanProcessor(memory)],
});
sdk.start();
await sdk.flush();

See OpenTelemetry SDK configuration: https://opentelemetry.io/docs/concepts/sdk-configuration/

Classes

class BatchLogRecordProcessor extends LogRecordProcessor {

A log-record processor that applies attribute limits and exports in batches.

Logs are buffered on onEmit after attributeCountLimit and attributeValueLengthLimit (both unbounded by default) are enforced, then flushed to the exporter in slices of maxExportBatchSize (default 512). Records arriving when the queue is at maxQueueSize (default 2048) are silently dropped. As with the span processor, scheduledDelayMillis of 0 means no automatic flush — call forceFlush() or sdk.flush().

import { BatchLogRecordProcessor, InMemoryExporter, OtelSDK } from 'fino:opentelemetry/sdk';

const exporter = new InMemoryExporter();
const sdk = new OtelSDK({
  logRecordProcessors: [
    new BatchLogRecordProcessor(exporter, { attributeValueLengthLimit: 1024 }),
  ],
}).start();

Constructors

constructor(exporter: OtelExporter, options: { maxQueueSize?: number; maxExportBatchSize?: number; scheduledDelayMillis?: number; attributeCountLimit?: number; attributeValueLengthLimit?: number; } = {})

Constructs a batch log processor around an exporter with optional limits.

Sizing defaults match BatchSpanProcessor; attribute-count and value-length limits default to unbounded (Number.POSITIVE_INFINITY).

Methods

onEmit(log: LogRecord): void

Applies attribute limits and enqueues the record, dropping it if full.

Arms the flush timer when a positive scheduledDelayMillis is configured and none is pending.

async forceFlush(): Promise<void>

Cancels any pending timer and exports the whole queue in batches.

async shutdown(): Promise<void>

Flushes remaining logs; the exporter itself is not closed here.

class BatchSpanProcessor extends SpanProcessor {

A span processor that queues finished spans and exports them in batches.

Spans are buffered on onEnd and flushed to the exporter in slices of maxExportBatchSize (default 512). Once the queue reaches maxQueueSize (default 2048), further spans are dropped and counted in droppedSpanCount. When scheduledDelayMillis is greater than zero a timer flushes the queue after that delay; with the default of 0 no timer is armed and you must call forceFlush() (or sdk.flush()) to export — which is what tests typically want for determinism.

import { BatchSpanProcessor, InMemoryExporter } from 'fino:opentelemetry/sdk';

const exporter = new InMemoryExporter();
const processor = new BatchSpanProcessor(exporter, {
  maxQueueSize: 4096,
  maxExportBatchSize: 256,
  scheduledDelayMillis: 5000,
});

Constructors

constructor(exporter: OtelExporter, options: { maxQueueSize?: number; maxExportBatchSize?: number; scheduledDelayMillis?: number; } = {})

Constructs a batch processor around an exporter with optional sizing.

maxQueueSize defaults to 2048, maxExportBatchSize to 512, and scheduledDelayMillis to 0 (manual flush only).

Getters

get droppedSpanCount(): number

How many spans have been dropped because the queue was full.

Methods

onEnd(span: SpanRecord): void

Enqueues a finished span, dropping it if the queue is at capacity.

When a positive scheduledDelayMillis is configured and no flush is pending, this arms the flush timer.

async forceFlush(): Promise<void>

Cancels any pending timer and exports the whole queue in batches.

Drains the queue in slices of maxExportBatchSize, awaiting each exportSpans call in turn, so it resolves only once everything buffered has been handed to the exporter.

async shutdown(): Promise<void>

Flushes remaining spans; the exporter itself is not closed here.

class InMemoryExporter {

An exporter that retains every span, log, and metric it receives in memory.

This is the exporter to reach for in tests and assertions: nothing leaves the process, and the getFinished* accessors return defensive copies of what has been exported so far. Its export* methods always resolve with a success result, so it never exercises retry or failure paths — pair it with a real exporter if you need to test those.

import { BatchSpanProcessor, InMemoryExporter, OtelSDK } from 'fino:opentelemetry/sdk';

const memory = new InMemoryExporter();
const sdk = new OtelSDK({
  spanProcessors: [new BatchSpanProcessor(memory, { scheduledDelayMillis: 0 })],
}).start();

await sdk.flush();
for (const span of memory.getFinishedSpans()) console.log(span.name);

Methods

async exportSpans(spans: SpanRecord[]): Promise<ExportResult>

Appends the given spans to the in-memory store and resolves with success.

async exportLogs(logs: LogRecord[]): Promise<ExportResult>

Appends the given log records to the in-memory store and resolves with success.

async exportMetrics(metrics: MetricRecord[]): Promise<ExportResult>

Appends the given metric records to the in-memory store and resolves with success.

getFinishedSpans(): SpanRecord[]

Returns a shallow copy of every span exported so far.

The returned array is a snapshot; later exports do not mutate it. Assert against its length and contents after calling sdk.flush().

getFinishedLogs(): LogRecord[]

Returns a shallow copy of every log record exported so far.

getFinishedMetrics(): MetricRecord[]

Returns a shallow copy of every metric record exported so far.

class LogRecordProcessor {

Base class for log-record processors; the no-op default that subclasses override.

A log processor is notified once per emitted log record via onEmit. The base implementation is a null processor. Subclass it to batch or forward logs — see BatchLogRecordProcessor.

import { LogRecordProcessor } from 'fino:opentelemetry/sdk';
import type { LogRecord } from 'fino:opentelemetry';

class ConsoleLogProcessor extends LogRecordProcessor {
  onEmit(log: LogRecord): void {
    console.log(log.severityText, log.body);
  }
}

Methods

onEmit(_log: LogRecord): void

Called for each emitted log record. No-op by default.

async forceFlush(): Promise<void>

Exports anything the processor has buffered. Resolves immediately by default.

async shutdown(): Promise<void>

Flushes and releases resources. Resolves immediately by default.

class ManualMetricReader extends MetricReader {

A metric reader that buffers the latest batch for synchronous collect().

Unlike PeriodicMetricReader, this reader never exports on its own — it holds the most recent batch the SDK delivered and hands it out when you call collect(). This is the building block behind metricsSignal and any pull- based integration (a scrape endpoint, a dashboard poll). Under 'delta' temporality, receiving an empty batch after having seen data emits zeroed copies of the last series so downstream consumers observe the reset.

import { ManualMetricReader, OtelSDK } from 'fino:opentelemetry/sdk';

const reader = new ManualMetricReader({ temporality: 'delta' });
const sdk = new OtelSDK({ metricReaders: [reader] }).start();

await sdk.flush();          // SDK delivers a batch to the reader
const metrics = reader.collect(); // drains and returns it

Methods

receive(metrics: MetricRecord[]): void

Stores the delivered batch for the next collect().

Each call replaces the buffered batch rather than appending. When a delta reader receives an empty batch after previously seeing data, the buffer is filled with zeroed copies of the last series so the reset is visible.

collect(): MetricRecord[]

Returns and clears the buffered batch as cloned records.

The buffer is emptied, so a second call before the next receive() returns an empty array. Records are cloned, so mutating them does not affect SDK state.

class MetricReader {

Base class for metric readers; carries the reader's aggregation temporality.

A metric reader is the sink the SDK delivers aggregated metric batches to. Its temporality'cumulative' (default) or 'delta' — selects which of the SDK's two aggregate stores feeds it, and stamps aggregationTemporality on each record. The base class is a null reader; subclass it to collect (ManualMetricReader) or export on a timer (PeriodicMetricReader).

import { MetricReader } from 'fino:opentelemetry/sdk';

const reader = new MetricReader({ temporality: 'delta' });
console.log(reader.temporality); // 'delta'

Constructors

constructor(options: { temporality?: MetricTemporality; } = {})

Constructs a reader with the given temporality, defaulting to 'cumulative'.

Getters

get temporality(): MetricTemporality

The aggregation temporality this reader reports metrics with.

Methods

record(_metric: MetricRecord): void

Records a single metric. No-op by default.

receive(_metrics: MetricRecord[]): void

Receives a batch of aggregated metrics from the SDK. No-op by default.

async forceFlush(): Promise<void>

Exports anything buffered. Resolves immediately by default.

async shutdown(): Promise<void>

Stops collection and releases resources. Resolves immediately by default.

class OtelSDK {

The cross-signal collection engine that turns runtime telemetry into exports.

An OtelSDK ties together processors, readers, exporters, a sampler, a propagator, metric views, span/log limits, a cardinality limit, and a resource. Once start() runs it subscribes to the runtime metric/log/ observable topics and drives any periodic readers; span recording is driven by instrumentations calling recordSpanStart/recordSpan. Records flow through the pipeline — sampling and limits for spans, limits for logs, views and cardinality capping for metrics — with the configured resource merged in along the way, before reaching processors and readers.

Construction fills in defaults for anything omitted: an OTLP HTTP JSON exporter, one BatchSpanProcessor, no log processors or metric readers, an AlwaysOnSampler, a W3CTraceContextPropagator, no views, an unbounded cardinality limit, empty span limits, and no resource. Multiple exporters are automatically wrapped in a fan-out exporter.

import {
  BatchSpanProcessor,
  InMemoryExporter,
  OtelSDK,
  PeriodicMetricReader,
} from 'fino:opentelemetry/sdk';

const exporter = new InMemoryExporter();
const sdk = new OtelSDK({
  resource: { 'service.name': 'checkout' },
  spanProcessors: [new BatchSpanProcessor(exporter, { scheduledDelayMillis: 0 })],
  metricReaders: [new PeriodicMetricReader(exporter, { intervalMs: 0 })],
}).start();

await sdk.flush();
await sdk.shutdown();

Constructors

constructor(options: { exporters?: OtelExporter[]; instrumentations?: Instrumentation[]; spanProcessors?: SpanProcessor[]; logRecordProcessors?: LogRecordProcessor[]; metricReaders?: MetricReader[]; sampler?: Sampler; propagator?: TextMapPropagator; views?: MetricView[]; metricCardinalityLimit?: number; spanLimits?: SpanLimits; resource?: Resource | Record<string, unknown> | null; } = {})

Constructs an SDK, filling in defaults for any omitted option.

When no exporters are given a single OTLP HTTP JSON exporter is used; when several are given they are wrapped in a fan-out exporter feeding the default BatchSpanProcessor. A plain object passed as resource is normalized into a Resource.

Getters

get propagator(): TextMapPropagator

The configured trace-context propagator, for injecting/extracting carriers.

get resource(): Resource | null

The configured resource merged into emitted records, or null when unset.

Methods

start(): this

Starts collection: subscribes to runtime topics and enables instrumentations.

Idempotent — a second call while already started is a no-op and returns this. Subscribes to the metric, log, and observable-registration topics, arms periodic metric readers, and enables each instrumentation, tracking any returned disposables for shutdown(). Returns the SDK so start() can be chained onto construction.

import { OtelSDK } from 'fino:opentelemetry/sdk';

const sdk = new OtelSDK().start();
recordSpanStart(span: SpanRecord): void

Records the start of a span, applying limits and sampling.

The span is limit-clamped and resource-enriched, then the sampler decides whether to keep it. Dropped spans return immediately; kept spans have their id remembered so the matching recordSpan skips re-sampling, and every span processor's onStart is invoked.

recordSpan(span: SpanRecord): void

Records the end of a span and delivers it to the processors.

If the span was sampled at start its remembered id is consumed and the span is passed straight to each processor's onEnd. A span with no prior recordSpanStart (a direct end) is sampled here first, and dropped if the sampler declines.

recordLog(log: LogRecord): void

Records a log, enriches it with the resource, and emits to log processors.

This is the handler bound to the otel:log:record topic on start(), but it can also be called directly.

recordMetric(metric: MetricRecord): void

Records a metric, applying views, cardinality limits, and aggregation.

The metric is view-shaped and resource-enriched, then dropped if it would introduce a new attribute set beyond the per-instrument cardinality limit. Surviving metrics are accumulated into both the cumulative and delta aggregate stores keyed by series. This is the handler bound to the otel:metric:record topic on start().

async flush(): Promise<void>

Collects observable metrics and drains all processors and readers.

Each registered observable callback is invoked (errors are swallowed and the observable skipped) and its observations recorded. Then, for every reader, the aggregate store matching its temporality is delivered via receive(), and all span processors, log processors, and readers are flushed in parallel. Delta aggregates are cleared afterward so the next window starts fresh.

import { BatchSpanProcessor, InMemoryExporter, OtelSDK } from 'fino:opentelemetry/sdk';

const exporter = new InMemoryExporter();
const sdk = new OtelSDK({
  spanProcessors: [new BatchSpanProcessor(exporter, { scheduledDelayMillis: 0 })],
}).start();

await sdk.flush();
console.log(exporter.getFinishedSpans().length);
async shutdown(): Promise<void>

Flushes, then shuts down processors, readers, and instrumentations.

Runs a final flush(), then shuts down every span processor, log processor, and reader in parallel, disposes all tracked disposables (topic subscriptions and instrumentation handles, errors ignored), clears the sampled-span and aggregate state, and marks the SDK stopped. After this the SDK can be start()ed again.

import { OtelSDK } from 'fino:opentelemetry/sdk';

const sdk = new OtelSDK().start();
await sdk.shutdown();

class PeriodicMetricReader extends MetricReader {

A metric reader that periodically collects aggregates and exports them.

Once OtelSDK.start() wires it up, this reader exports on a fixed interval (intervalMs, default 60000). Each cycle the SDK collects the aggregate store matching the reader's temporality, delivers it via receive(), and the reader exports the buffered batch. A non-positive interval disables the timer, leaving the reader flush-on-demand. Use PeriodicExportingMetricReader as the stable alias for this class.

import { OTLPHttpJsonExporter, OtelSDK, PeriodicMetricReader } from 'fino:opentelemetry/sdk';

const sdk = new OtelSDK({
  metricReaders: [
    new PeriodicMetricReader(new OTLPHttpJsonExporter(), { intervalMs: 15000 }),
  ],
}).start();

Constructors

constructor(exporter: OtelExporter, options: { temporality?: MetricTemporality; intervalMs?: number; } = {})

Constructs a periodic reader around an exporter.

temporality is passed through to MetricReader (default 'cumulative') and intervalMs defaults to 60000.

Methods

_startPeriodicCollection(collectAndFlush: () => Promise<void>): void

Called by OtelSDK.start() to begin the periodic collection cycle.

collectAndFlush is the SDK-supplied callback that collects accumulated metrics, delivers them via receive(), and calls forceFlush() to export. A non-positive interval disables scheduling, and repeated calls are ignored once a timer is active. This is an internal wiring hook, not part of the public reader contract.

import { OTLPHttpJsonExporter, PeriodicMetricReader } from 'fino:opentelemetry/sdk';

const reader = new PeriodicMetricReader(new OTLPHttpJsonExporter(), { intervalMs: 1000 });
reader._startPeriodicCollection(async () => {});
receive(metrics: MetricRecord[]): void

Buffers a batch of aggregated metrics for the next flush.

async forceFlush(): Promise<void>

Exports and clears the buffered metrics; a no-op when empty.

async shutdown(): Promise<void>

Stops the collection timer and flushes any remaining metrics.

class SpanProcessor {

Base class for span processors; the no-op default that subclasses override.

A span processor is the stage the SDK notifies when a span starts (onStart) and ends (onEnd). The base implementation does nothing, which makes it a valid null processor and a convenient superclass. Subclass it to batch, filter, or forward spans — see BatchSpanProcessor.

import { SpanProcessor } from 'fino:opentelemetry/sdk';
import type { SpanRecord } from 'fino:opentelemetry';

class LoggingProcessor extends SpanProcessor {
  onEnd(span: SpanRecord): void {
    console.log('finished span', span.name);
  }
}

Methods

onStart(_span: SpanRecord): void

Called when a span starts, after sampling and limits are applied. No-op by default.

onEnd(_span: SpanRecord): void

Called when a span ends, after limits are applied. No-op by default.

async forceFlush(): Promise<void>

Exports anything the processor has buffered. Resolves immediately by default.

async shutdown(): Promise<void>

Flushes and releases resources. Resolves immediately by default.

class Baggage {

An immutable W3C baggage set — string key/value pairs that propagate alongside trace context.

Every mutating operation (set, delete) returns a new Baggage rather than modifying the receiver, so instances are safe to share across async scopes. toString produces a spec-compliant baggage header value and Baggage.fromString parses one back.

W3C Baggage: https://www.w3.org/TR/baggage/

import { Baggage } from 'internal:opentelemetry/common';

const baggage = new Baggage({ tenant: 'acme' }).set('region', 'us');
baggage.get('tenant');   // 'acme'
baggage.toString();      // 'tenant=acme,region=us'

Constructors

constructor(entries: Record<string, string> = {})

Creates a baggage set from an initial record of entries, defaulting to empty.

const baggage = new Baggage({ tenant: 'acme' });

Methods

get(key: string): string | undefined

Returns the value for a key, or undefined when the key is absent.

new Baggage({ tenant: 'acme' }).get('tenant');  // 'acme'
set(key: string, value: string): Baggage

Returns a new baggage with the key set to the given value, leaving the receiver unchanged.

const base = new Baggage({ tenant: 'acme' });
const next = base.set('region', 'us');  // base still has only tenant
delete(key: string): Baggage

Returns a new baggage without the given key, leaving the receiver unchanged.

Deleting an absent key is a no-op that still returns a fresh copy.

new Baggage({ tenant: 'acme', region: 'us' }).delete('region');
entries()

Returns an iterator over the [key, value] pairs in insertion order.

for (const [key, value] of new Baggage({ tenant: 'acme' }).entries()) {
  console.log(key, value);
}
toString(): string

Serializes the baggage to a W3C baggage header value.

Keys and values are percent-encoded and joined with commas. An empty baggage serializes to the empty string.

new Baggage({ tenant: 'acme', region: 'us' }).toString();  // 'tenant=acme,region=us'
isEmpty(): boolean

True when the baggage contains no entries.

new Baggage().isEmpty(); // true

Static Methods

static fromString(text: string | null | undefined): Baggage

Parses a W3C baggage header into an immutable Baggage value.

Empty, null, or undefined input returns an empty baggage object. Invalid comma segments without = are ignored, and duplicate decoded keys keep the last parsed value.

const baggage = Baggage.fromString('tenant=acme,region=us');

class BaseProvider {

Shared base for the tracer, meter, and logger providers, holding a normalized Resource.

Subclasses inherit resource handling for free: the constructor runs the supplied resource option through normalizeResource so every provider exposes a fully-populated resource (defaults merged in) via the read-only resource getter.

import { BaseProvider } from 'internal:opentelemetry/common';

class TracerProvider extends BaseProvider {}
const provider = new TracerProvider({ resource: { 'service.name': 'api' } });
provider.resource.attributes['service.name'];  // 'api'

Constructors

constructor(options: ProviderOptions = {})

Normalizes the resource option into a Resource, defaulting to the SDK resource.

const provider = new BaseProvider({ resource: { 'service.name': 'api' } });

Getters

get resource(): Resource

The normalized resource describing the entity this provider produces telemetry for.

new BaseProvider().resource.attributes['telemetry.sdk.name'];  // 'fino'

class Resource {

An immutable description of the entity producing telemetry.

Holds a copied attribute map plus optional entity references, a schema URL, and a dropped-attribute count. All state is private and every getter returns a defensive copy, so a Resource cannot be mutated after construction. Prefer normalizeResource to build one with the default SDK attributes merged in.

import { Resource } from 'internal:opentelemetry/common';

const resource = new Resource(
  { 'service.name': 'checkout', 'service.version': '4.2.0' },
  { schemaUrl: 'https://opentelemetry.io/schemas/1.24.0' },
);
resource.attributes['service.name'];  // 'checkout'

Constructors

constructor(attributes: Attributes = {}, options: ResourceOptions = {})

Builds a resource from an attribute map and optional secondary options.

The attributes are shallow-copied, entityRefs are deep-copied with their idKeys normalized to arrays, and a missing schemaUrl becomes null. Both arguments default to empty, so new Resource() yields an attribute-free resource.

const resource = new Resource({ 'service.name': 'api' });

Getters

get attributes(): Attributes

A fresh shallow copy of the resource's attributes.

Mutating the returned object never affects the resource; read the value each time you need it.

const resource = new Resource({ 'service.name': 'api' });
resource.attributes['service.name'];  // 'api'
get droppedAttributesCount(): number

The number of attributes dropped before this resource was constructed, or 0.

new Resource({}, { droppedAttributesCount: 3 }).droppedAttributesCount;  // 3
get entityRefs(): Array<{ schemaUrl?: string; type?: string; idKeys: string[]; }>

A deep copy of the resource's entity references.

Each returned entry carries its own fresh idKeys array, so the internal state stays immutable. Empty when no entity references were supplied.

const resource = new Resource({}, {
  entityRefs: [{ type: 'service', idKeys: ['service.name'] }],
});
resource.entityRefs[0].type;  // 'service'
get schemaUrl(): string | null

The semantic-convention schema URL for this resource, or null if none was set.

new Resource({}, { schemaUrl: 'https://opentelemetry.io/schemas/1.24.0' }).schemaUrl;

class TextMapPropagator {

Base class for text-map propagators — the no-op default that subclasses override.

On its own, inject does nothing and extract always returns null, so the base class is a safe null-object when no propagation format is configured. W3CTraceContextPropagator is the concrete implementation. Both methods accept an optional CarrierApi so a subclass can work with non-object carriers.

import { TextMapPropagator } from 'internal:opentelemetry/common';

class NoopPropagator extends TextMapPropagator {}
new NoopPropagator().extract({});  // null

Methods

inject<TCarrier = CarrierLike>( _carrier: TCarrier, _context: TraceContext | null | undefined, _carrierApi?: CarrierApi<TCarrier> ): void

Injects trace context into a carrier.

The base propagator is a no-op for subclasses to override. It accepts a custom carrier API for non-object carriers and never throws for missing context.

new TextMapPropagator().inject({}, null);
extract<TCarrier = CarrierLike>( _carrier: TCarrier, _carrierApi?: CarrierApi<TCarrier> ): TraceContext | null

Extracts trace context from a carrier.

The base propagator cannot decode any format and always returns null. Subclasses return a TraceContext only when required carrier fields are present and valid.

const context = new TextMapPropagator().extract({});

class W3CTraceContextPropagator extends TextMapPropagator {

Propagator implementing W3C traceparent, tracestate, and baggage headers.

This is the default propagator returned by Propagation.getPropagator. It injects a version-00 traceparent, adds tracestate and baggage when present, and on extraction validates the header strictly (rejecting all-zero IDs, the reserved ff version, and v00 headers with trailing data) while parsing unknown lowercase versions permissively for forward compatibility.

W3C Trace Context: https://www.w3.org/TR/trace-context/

import { W3CTraceContextPropagator } from 'internal:opentelemetry/common';

const propagator = new W3CTraceContextPropagator();
const headers = new Headers();
propagator.inject(headers, {
  traceId: '00000000000000000000000000000001',
  spanId: '0000000000000001',
  traceFlags: 1,
});
const context = propagator.extract(headers);

Methods

inject<TCarrier = CarrierLike>( carrier: TCarrier, context: TraceContext | null | undefined, carrierApi?: CarrierApi<TCarrier> ): void

Writes W3C traceparent and optional tracestate values into a carrier.

Missing traceId or spanId leaves the carrier untouched. traceFlags are masked to one byte and encoded as two lowercase hexadecimal digits.

new W3CTraceContextPropagator().inject({}, { traceId: '0'.repeat(31) + '1', spanId: '0'.repeat(15) + '1' });
extract<TCarrier = CarrierLike>( carrier: TCarrier, carrierApi?: CarrierApi<TCarrier> ): TraceContext | null

Reads W3C trace context from traceparent and optional tracestate.

Returns null for malformed headers, all-zero trace IDs, all-zero span IDs, or v00 headers with trailing data. Unknown versions are parsed permissively for forward compatibility.

const context = new W3CTraceContextPropagator().extract({ traceparent: '00-00000000000000000000000000000001-0000000000000001-01' });

Constants

const PeriodicExportingMetricReader

Stable OpenTelemetry-spec alias for PeriodicMetricReader.

Provided so code written against the standard SDK naming works unchanged; it is the same constructor, not a subclass.

import { OTLPHttpJsonExporter, PeriodicExportingMetricReader } from 'fino:opentelemetry/sdk';

const reader = new PeriodicExportingMetricReader(new OTLPHttpJsonExporter());

const OTEL_SCHEMA_VERSION

Version stamp written into the schemaVersion field of runtime event payloads.

Consumers can branch on this to stay compatible as the internal event shape evolves. It is the runtime's own event-schema version, unrelated to an OTel semantic-convention schemaUrl.

import { OTEL_SCHEMA_VERSION } from 'internal:opentelemetry/common';

if (OTEL_SCHEMA_VERSION >= 1) {
  // handle the current runtime event shape
}

const OTEL_TOPIC_SUFFIXES

The frozen catalog of valid topic suffixes for each signal family.

Maps each family (trace, log, metric, runtime) to the lifecycle/level suffixes it may append to a scoped topic name — for example a trace topic can end in start/end/error, while a log topic ends in a severity like info/warn. Deeply frozen so the vocabulary cannot be mutated at runtime.

import { OTEL_TOPIC_SUFFIXES } from 'internal:opentelemetry/common';

OTEL_TOPIC_SUFFIXES.trace;  // ['start', 'end', 'error', 'event', ...]
OTEL_TOPIC_SUFFIXES.log;    // ['emit', 'debug', 'info', 'warn', 'error']

const Propagation

The process-global propagation facade used to inject and extract trace context.

getPropagator lazily creates a W3CTraceContextPropagator on first use, and setPropagator swaps in a custom one. inject writes the active span's context (from the getter registered via registerActiveSpanContextGetter) when no context is passed explicitly, and extract reads context off an inbound carrier. Both delegate to the current propagator.

import { Propagation } from 'internal:opentelemetry/common';

const headers = new Headers();
Propagation.inject(headers);                 // writes traceparent from active span
const incoming = Propagation.extract(headers);

Methods

getPropagator(): TextMapPropagator
setPropagator(propagator: TextMapPropagator): void
inject<TCarrier = CarrierLike>( carrier: TCarrier, context?: TraceContext | null, carrierApi?: CarrierApi<TCarrier> ): void
extract<TCarrier = CarrierLike>( carrier: TCarrier, carrierApi?: CarrierApi<TCarrier> ): TraceContext | null

Functions

function metricsSignal(reader: ManualMetricReader, options: { intervalMs?: number; } = {}): ReadonlySignal<MetricRecord[]>

Wraps a ManualMetricReader in a cold signal that re-collects on an interval.

The returned signal starts empty, collects once immediately when it gains its first subscriber, then polls reader.collect() every intervalMs (default 1000). Empty collections are skipped, so the signal only updates when there is new metric data. Being cold, the polling timer is only active while the signal has subscribers and is cleared when the last one leaves.

import { ManualMetricReader, OtelSDK, metricsSignal } from 'fino:opentelemetry/sdk';

const reader = new ManualMetricReader();
new OtelSDK({ metricReaders: [reader] }).start();

const metrics = metricsSignal(reader, { intervalMs: 5000 });
const stop = metrics.subscribe((batch) => console.log('metrics', batch.length));
// later: stop();

function bytesEqual(a: Uint8Array, b: Uint8Array): boolean

Compares two byte arrays for equal length and identical contents.

Returns false immediately when the lengths differ, otherwise compares every byte. This is a plain value comparison, not a constant-time one, so it is not suitable for comparing secrets.

import { bytesEqual, hexToBytes } from 'internal:opentelemetry/common';

bytesEqual(hexToBytes('0001', 2), hexToBytes('0001', 2));  // true

function carrierApiFor<TCarrier>( carrier: TCarrier, carrierApi?: CarrierApi<TCarrier> ): CarrierApi<TCarrier>

Returns the caller-supplied CarrierApi if given, otherwise derives one with defaultCarrierApiFor.

This is the entry point propagators use so an explicit strategy always wins over the sniffed default. Passing a custom API lets you propagate through a carrier that does not match CarrierLike.

import { carrierApiFor } from 'internal:opentelemetry/common';

const api = carrierApiFor({} as Record<string, unknown>);

function consumeRequestContext(requestId: string): ActiveTelemetryContext | null

Removes and returns the context previously stashed for a request id, or null.

The entry is deleted whether or not it existed, so a context can be adopted exactly once. Returns null when no context was installed or it was already consumed. Pair with runWithActiveContext to activate the result.

import { consumeRequestContext, runWithActiveContext } from 'internal:opentelemetry/common';

const ctx = consumeRequestContext('req-1');
if (ctx) runWithActiveContext(ctx, () => handleRequest());

function currentActiveTelemetryContext(): ActiveTelemetryContext | undefined

Returns the active telemetry context installed by runWithActiveContext, or undefined.

undefined means no context has been made active in the current async scope — typically outside any instrumented request handler.

import { currentActiveTelemetryContext } from 'internal:opentelemetry/common';

const traceId = currentActiveTelemetryContext()?.traceId;

function defaultCarrierApiFor<TCarrier extends CarrierLike>(carrier: TCarrier): CarrierApi<TCarrier>

Picks a CarrierApi for a carrier by sniffing whether it exposes get/set methods.

When the carrier has both get and set functions (as Headers or a Map does), the returned API routes through them and reads keys via keys() if available. Otherwise it treats the carrier as a plain record, using property access and Object.keys. Callers usually reach this through carrierApiFor.

import { defaultCarrierApiFor } from 'internal:opentelemetry/common';

const api = defaultCarrierApiFor(new Headers());
api.set(new Headers(), 'traceparent', '00-...-01');

function encodeSegment(value: unknown): string

Percent-encodes a value for safe use as a single colon-delimited topic segment.

Stringifies the input then applies encodeURIComponent, so any : or other delimiter inside a scope name or suffix cannot break the otel:... topic grammar. This is the escaping used throughout topicNames/otelTopic.

import { encodeSegment } from 'internal:opentelemetry/common';

encodeSegment('my:service');  // 'my%3Aservice'

function getActiveBaggage(): Baggage

Returns the baggage currently in scope, falling back through context stores to an empty set.

Prefers the dedicated active-baggage store, then the baggage attached to the active telemetry context, and finally a fresh empty Baggage. Always returns a value, so callers never need to null-check.

import { getActiveBaggage } from 'internal:opentelemetry/common';

const tenant = getActiveBaggage().get('tenant');

function hexToBytes(hex: string, size: number): Uint8Array

Decodes a hex string into a fixed-size byte array, left-padding or truncating to fit.

Always returns exactly size bytes: shorter input is zero-padded on the left, longer input is truncated, and any non-hex pair decodes to 0 rather than throwing. Useful for turning a trace/span ID into its binary form for comparison with bytesEqual.

import { hexToBytes } from 'internal:opentelemetry/common';

hexToBytes('0001', 2);  // Uint8Array [0, 1]
hexToBytes('1', 2);     // Uint8Array [0, 1]  (left-padded)

function installRequestContext(requestId: string, context: ActiveTelemetryContext): void

Stashes a trace context under a request id so a handler can later adopt it.

This decouples the point where instrumentation extracts context (on the socket thread) from where the handler runs, without coupling serve to OTel types. Retrieve and remove the entry with consumeRequestContext. The pending map is bounded: entries older than five minutes are evicted on overflow, and if it is still full the oldest entry is dropped, so an id that is never consumed leaks only transiently.

import { installRequestContext } from 'internal:opentelemetry/common';

installRequestContext('req-1', {
  traceId: '0'.repeat(31) + '1',
  spanId: '0'.repeat(15) + '1',
});

function limitAttributeEntries(attributes: Attributes, limits: { attributeCountLimit?: number; attributeValueLengthLimit?: number; }): { attrs: Attributes; dropped: number; }

Applies span-attribute limits, returning the kept attributes and how many were dropped.

Keeps the first attributeCountLimit entries in insertion order (excess counted in dropped) and truncates each kept string value to attributeValueLengthLimit via truncateAttributeValue. An omitted limit is treated as unlimited for that dimension, so with no limits nothing is dropped.

import { limitAttributeEntries } from 'internal:opentelemetry/common';

const { attrs, dropped } = limitAttributeEntries(
  { a: 1, b: 2, c: 3 },
  { attributeCountLimit: 2 },
);
// attrs = { a: 1, b: 2 }, dropped = 1

function mergeAttributes(a?: Attributes, b?: Attributes): Attributes

Shallow-merges two attribute maps into a new object, with the second winning on key conflicts.

Either argument may be omitted; the result is always a fresh object, so neither input is mutated. Keys present in b override the same keys in a.

import { mergeAttributes } from 'internal:opentelemetry/common';

mergeAttributes({ a: 1, b: 2 }, { b: 3 });  // { a: 1, b: 3 }

function normalizeResource(resource?: Resource | Attributes | null): Resource

Coerces any resource-ish input into a Resource with the default SDK attributes merged in.

Accepts an existing Resource, a plain attribute map, or null/undefined. The result always includes the defaults (service.name = unknown_service, telemetry.sdk.name = fino, telemetry.sdk.language = javascript), with the caller's attributes taking precedence. When passed a Resource, its dropped-count, entity refs, and schema URL are preserved.

import { normalizeResource } from 'internal:opentelemetry/common';

const resource = normalizeResource({ 'service.name': 'checkout' });
resource.attributes['telemetry.sdk.name'];  // 'fino'

function normalizeScope( name: string, version?: string, schemaUrl?: string | null, attributes?: Attributes, droppedAttributesCount?: number ): ScopeInfo

Builds a validated ScopeInfo, omitting empty optional fields and copying attributes.

The name is run through requireNonEmptyName (throwing a TypeError when blank). Falsy version, schemaUrl, attributes, and droppedAttributesCount are left off the result entirely rather than set to undefined, and the attributes object is shallow-copied so later mutation of the caller's map does not leak in.

import { normalizeScope } from 'internal:opentelemetry/common';

const scope = normalizeScope('my-app/db', '2.1.0');
// { name: 'my-app/db', version: '2.1.0' }

function nowUnixNano(): number

Returns the current wall-clock time as Unix-epoch nanoseconds.

Combines performance.timeOrigin with performance.now() for sub-millisecond resolution, then scales to nanoseconds — the timestamp unit every record in this module uses. Because the result is a double, it exceeds 2^53 and loses single-nanosecond precision; it is accurate to roughly the microsecond.

import { nowUnixNano } from 'internal:opentelemetry/common';

const span = { startTimeUnixNano: nowUnixNano() };

function otelRuntimeEvent<TPayload extends Record<string, unknown>>(domain: string, operation: string, phase: string, payload: TPayload = {} as TPayload): TPayload & { schemaVersion: number; topic: string; family: string; domain: string; operation: string; phase: string; correlationId: unknown; }

Wraps a runtime event payload with standard envelope fields for publishing.

Merges the caller's payload with schemaVersion (OTEL_SCHEMA_VERSION), the resolved topic, a family of 'runtime', the domain/operation/phase, and a correlationId derived from the first present of requestId, lookupId, connectId, handshakeId, or spanId (else null). Payload keys are spread last, so an explicit topic or correlationId in the payload wins.

import { otelRuntimeEvent, otelRuntimeTopic } from 'internal:opentelemetry/common';
import { topic } from 'internal:opentelemetry/common';

const event = otelRuntimeEvent('dns', 'lookup', 'start', {
  lookupId: 'dns-1',
  hostname: 'example.com',
});
topic(otelRuntimeTopic('dns', 'lookup', 'start')).publish(event);

function otelRuntimeTopic(domain: string, operation: string, phase: string): string

Builds the topic name for a runtime instrumentation event.

Produces otel:runtime:<domain>:<operation>:<phase> with each part percent-encoded — for example ('http.server', 'request', 'start'). These are the topics that the runtime publishes network/DNS/TLS lifecycle events on and that the built-in instrumentations subscribe to.

import { otelRuntimeTopic } from 'internal:opentelemetry/common';

otelRuntimeTopic('dns', 'lookup', 'start');  // 'otel:runtime:dns:lookup:start'

function otelTopic(signal: string, scope: ScopeInfo, ...suffixes: string[]): string

Builds the single versioned topic name for a scoped signal.

Produces otel:<signal>:<scopeSegment>[:<suffixes>], where the scope segment includes @version when the scope is versioned and any suffixes are joined with :. Unlike topicNames this returns exactly one name (the versioned form), which is what publishers and subscribers key on.

import { otelTopic } from 'internal:opentelemetry/common';

otelTopic('trace', { name: 'mysql' }, 'start');  // 'otel:trace:mysql:start'

function publishScoped<TPayload>( signal: SignalName, scope: ScopeInfo, suffixes: string[], payload: TPayload ): void

Publishes one payload to every topic name that topicNames derives for a scope.

Delivers the same payload to both the bare and versioned topic forms so subscribers at either granularity see it. Publication is synchronous through the topic bus.

import { publishScoped } from 'internal:opentelemetry/common';

publishScoped('trace', { name: 'db', version: '2.1.0' }, ['start'], {
  traceId: '00000000000000000000000000000001',
  spanId: '0000000000000001',
});

function randomHex(length: number): string

Generates a cryptographically random lowercase hex string of the given length.

Draws random bytes from crypto.getRandomValues and truncates to exactly length characters, so odd lengths are supported. Used to mint trace and span IDs (32 and 16 hex chars respectively).

import { randomHex } from 'internal:opentelemetry/common';

const traceId = randomHex(32);
const spanId = randomHex(16);

function registerActiveSpanContextGetter(getter: () => TraceContext | null): void

Installs the callback that resolves the currently active span's trace context.

The trace SDK registers a getter here so that Propagation.inject (called without an explicit context) can read the active span without this module depending on the tracer. Registering again replaces the previous getter; until one is set the default returns null.

import { registerActiveSpanContextGetter } from 'internal:opentelemetry/common';

registerActiveSpanContextGetter(() => currentSpan()?.spanContext() ?? null);

function requireNonEmptyName(kind: string, value: unknown): string

Validates and trims a required name string, throwing when it is blank.

Coerces the value to a string, trims surrounding whitespace, and throws a TypeError naming kind if the result is empty. Used to guarantee scopes and instruments always carry a usable name.

import { requireNonEmptyName } from 'internal:opentelemetry/common';

requireNonEmptyName('scope', '  db  ');  // 'db'
requireNonEmptyName('scope', '   ');     // throws TypeError

function requireRecord(kind: string, value: unknown): Record<string, unknown>

Coerces a value to a plain record, tolerating nullish input but rejecting non-objects.

Returns an empty object for null/undefined, returns the value unchanged when it is a non-array object, and throws a TypeError (using kind in the message) for primitives and arrays. Handy for validating optional options bags.

import { requireRecord } from 'internal:opentelemetry/common';

requireRecord('attributes', undefined);        // {}
requireRecord('attributes', { a: 1 });         // { a: 1 }
requireRecord('attributes', [1, 2]);           // throws TypeError

function runWithActiveContext<R>(context: ActiveTelemetryContext, fn: () => R): R

Runs a function with the given telemetry context installed as active for its async scope.

Normalizes the context first: only truthy traceId/spanId/traceState are carried, traceFlags defaults to 1 (sampled) when absent, and a plain baggage object is upgraded to a Baggage. When the context carries baggage it is also installed in the active-baggage store so getActiveBaggage sees it. The function's return value is passed through.

import { runWithActiveContext } from 'internal:opentelemetry/common';

runWithActiveContext(
  { traceId: '0'.repeat(31) + '1', spanId: '0'.repeat(15) + '1' },
  () => handleRequest(),
);

function runWithBaggage<R>(baggage: Baggage, fn: () => R): R

Runs a function with the given baggage active, layering it onto any active telemetry context.

When a telemetry context is already active, its baggage is replaced with the supplied set for the duration of the call; otherwise only the active-baggage store is set. Nested calls override outer baggage within their scope. The function's return value is passed through.

import { runWithBaggage, Baggage, getActiveBaggage } from 'internal:opentelemetry/common';

runWithBaggage(new Baggage({ tenant: 'acme' }), () => {
  getActiveBaggage().get('tenant');  // 'acme'
});

function scopeSegment(scope: ScopeInfo): string

Renders a scope as a topic segment, appending @version when a version is present.

Both name and version are percent-encoded via encodeSegment. A versionless scope yields just the encoded name. This is the versioned form used inside otelTopic; topicNames emits both the bare and versioned forms.

import { scopeSegment } from 'internal:opentelemetry/common';

scopeSegment({ name: 'db', version: '2.1.0' });  // 'db@2.1.0'
scopeSegment({ name: 'db' });                    // 'db'

function snapshotCarrier<TCarrier extends CarrierLike>( carrier: TCarrier, carrierApi?: CarrierApi<TCarrier> ): Record<string, unknown>

Copies every key/value from a carrier into a plain record.

Iterates the carrier's keys through its CarrierApi and materializes them as an ordinary object — useful for capturing a Headers instance as a plain snapshot (for example the injectedHeaders on a SpanRecord).

import { snapshotCarrier } from 'internal:opentelemetry/common';

const headers = new Headers({ traceparent: '00-...-01' });
const plain = snapshotCarrier(headers);  // { traceparent: '00-...-01' }

function topic<T = unknown>(name: string): Topic<T>

Re-exported from topic.topic.

function topicNames(signal: string, scope: ScopeInfo, ...suffixes: string[]): string[]

Computes the set of topic names a scoped signal should be published to.

Always includes the bare otel:<signal>:<name> form; when the scope has a version it also includes the otel:<signal>:<name>@<version> form, so both version-agnostic and version-pinned subscribers receive the event. Any suffixes are appended as a single :-joined, encoded segment. publishScoped fans a payload out across exactly this list.

import { topicNames } from 'internal:opentelemetry/common';

topicNames('trace', { name: 'db', version: '2.1.0' }, 'start');
// ['otel:trace:db:start', 'otel:trace:db@2.1.0:start']

function truncateAttributeValue(value: unknown, limit: number): unknown

Truncates a string attribute value (or the strings inside an array value) to a length limit.

A non-positive or non-finite limit returns the value unchanged. Strings are clipped to limit characters; arrays have their string elements clipped element-wise while non-string elements pass through; all other value types are returned as-is.

import { truncateAttributeValue } from 'internal:opentelemetry/common';

truncateAttributeValue('a very long value', 6);  // 'a very'
truncateAttributeValue(['abcdef', 42], 3);        // ['abc', 42]

Types

type Attributes = Record<string, unknown>

Open-ended key/value map of attributes attached to spans, logs, metrics, and resources.

Values are stored as unknown because the OpenTelemetry data model permits strings, numbers, booleans, and homogeneous arrays of those; validation and truncation happen later in limitAttributeEntries and truncateAttributeValue rather than in the type. An empty object is a valid, attribute-free value.

import type { Attributes } from 'internal:opentelemetry/common';

const attrs: Attributes = {
  'http.request.method': 'GET',
  'http.response.status_code': 200,
  'url.path': '/orders',
};

type CarrierLike = { [key: string]: unknown; get?(key: string): unknown; set?(key: string, value: unknown): unknown; keys?(): Iterable<string>; }

Duck-typed shape a propagation carrier may take — a plain record and/or a Headers-like accessor object.

Propagators read and write context keys through either the indexer or, when present, the optional get/set/keys methods (as a Headers or Map provides). defaultCarrierApiFor inspects a value of this shape and picks the right access strategy, so most callers pass a plain object or a Headers instance directly.

import type { CarrierLike } from 'internal:opentelemetry/common';

const plain: CarrierLike = { traceparent: '00-...-01' };
const headers: CarrierLike = new Headers();

type ScopeInfo = { name: string; version?: string; schemaUrl?: string | null; attributes?: Attributes; droppedAttributesCount?: number; }

Identity of an instrumentation scope — the named library or subsystem that produced a signal.

The name is required and is what topic routing keys off of (see topicNames and otelTopic); version further qualifies the scope in versioned topic names. schemaUrl, attributes, and droppedAttributesCount carry through to exported records unchanged. Construct these with normalizeScope rather than by hand to guarantee a non-empty name.

import type { ScopeInfo } from 'internal:opentelemetry/common';

const scope: ScopeInfo = { name: 'my-app/db', version: '2.1.0' };

type SignalName = 'trace' | 'log' | 'metric'

The three OpenTelemetry signal families this runtime emits.

Used to build topic names and to select per-signal suffix vocabularies in OTEL_TOPIC_SUFFIXES. Runtime instrumentation events use a separate 'runtime' family and are not part of this union.

import type { SignalName } from 'internal:opentelemetry/common';

const signal: SignalName = 'trace';

Interfaces

interface CarrierApi<TCarrier = CarrierLike> {

Strategy object that reads, writes, and enumerates keys on a specific carrier type.

Propagators never touch a carrier directly; they receive a CarrierApi from carrierApiFor/defaultCarrierApiFor so the same inject/extract logic works against plain objects, Headers, Map, or any bespoke transport. Supply a custom implementation when your carrier does not match CarrierLike.

import type { CarrierApi } from 'internal:opentelemetry/common';

const mapApi: CarrierApi<Map<string, string>> = {
  get: (m, k) => m.get(k),
  set: (m, k, v) => void m.set(k, String(v)),
  keys: (m) => [...m.keys()],
};

Methods

get(target: TCarrier, key: string): unknown

get method on CarrierApi.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: CarrierApi['get'] = undefined as never;
set(target: TCarrier, key: string, value: unknown): void

set method on CarrierApi.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: CarrierApi['set'] = undefined as never;
keys(target: TCarrier): string[]

keys method on CarrierApi.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: CarrierApi['keys'] = undefined as never;

interface Disposable {

A teardown handle returned by an instrumentation's enable to undo its patches.

Calling dispose should reverse whatever the instrumentation installed (topic subscriptions, monkey-patches) and must be idempotent. An instrumentation may return one, several, or none of these.

import type { Disposable } from 'internal:opentelemetry/common';

const handle: Disposable = { dispose() { console.log('unhooked'); } };
handle.dispose();

Methods

dispose(): void

dispose method on Disposable.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: Disposable['dispose'] = undefined as never;

interface ExportResult {

The outcome an exporter resolves with after attempting to send a batch.

code is 'success' when the batch was delivered (including partial-success responses that the exporter chose to accept) and 'failure' when it was not. Processors use this to decide whether to retry or drop the batch.

import type { ExportResult } from 'internal:opentelemetry/common';

const result: ExportResult = { code: 'success' };

Properties

code: 'success' | 'failure'

code property on ExportResult.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: ExportResult['code'];

interface Instrumentation {

A pluggable instrumentation that wires runtime events into the SDK when enabled.

enable is called once with the SDK and should install its hooks, optionally returning Disposable(s) so the SDK can later tear them down. Returning nothing means the instrumentation manages its own lifetime.

import type { Instrumentation } from 'internal:opentelemetry/common';

const noop: Instrumentation = {
  enable(sdk) {
    return { dispose() {} };
  },
};

Methods

enable(sdk: OtelSdkLike): void | Disposable | Disposable[]

enable method on Instrumentation.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: Instrumentation['enable'] = undefined as never;

interface OtelExporter {

The contract every telemetry exporter implements to receive batched records.

A processor calls the export* method for its signal with an array of records and awaits an ExportResult. Implementations should resolve (never reject) so the processor can act on the result code, and the optional shutdown should flush and release transport resources.

import type { OtelExporter, ExportResult } from 'internal:opentelemetry/common';

const exporter: OtelExporter = {
  async exportSpans(spans): Promise<ExportResult> {
    console.log(spans.length, 'spans');
    return { code: 'success' };
  },
  async exportLogs() { return { code: 'success' }; },
  async exportMetrics() { return { code: 'success' }; },
};

Methods

exportSpans(spans: SpanRecord[]): Promise<ExportResult>

exportSpans method on OtelExporter.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelExporter['exportSpans'] = undefined as never;
exportLogs(logs: LogRecord[]): Promise<ExportResult>

exportLogs method on OtelExporter.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelExporter['exportLogs'] = undefined as never;
exportMetrics(metrics: MetricRecord[]): Promise<ExportResult>

exportMetrics method on OtelExporter.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelExporter['exportMetrics'] = undefined as never;
shutdown?(): Promise<void>

shutdown method on OtelExporter.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelExporter['shutdown'] = undefined as never;

interface OtelSdkLike {

The minimal SDK surface an Instrumentation needs to record signals and propagate context.

Exposes the active propagator plus record sinks for each signal. recordSpanStart publishes a span's start before it ends, while recordSpan publishes the completed span; recordLog and recordMetric handle the other two signals. Instrumentations depend on this narrow interface rather than the concrete SDK so they stay decoupled from the SDK implementation.

import type { OtelSdkLike, SpanRecord } from 'internal:opentelemetry/common';

function finish(sdk: OtelSdkLike, span: SpanRecord): void {
  span.endTimeUnixNano = Date.now() * 1e6;
  sdk.recordSpan(span);
}

Readonly Properties

readonly propagator: TextMapPropagator

propagator property on OtelSdkLike.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: OtelSdkLike['propagator'];

Methods

recordSpanStart(span: SpanRecord): void

recordSpanStart method on OtelSdkLike.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelSdkLike['recordSpanStart'] = undefined as never;
recordSpan(span: SpanRecord): void

recordSpan method on OtelSdkLike.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelSdkLike['recordSpan'] = undefined as never;
recordLog(log: LogRecord): void

recordLog method on OtelSdkLike.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelSdkLike['recordLog'] = undefined as never;
recordMetric(metric: MetricRecord): void

recordMetric method on OtelSdkLike.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

const member: OtelSdkLike['recordMetric'] = undefined as never;

interface PartialSuccessResult {

The partialSuccess payload an OTLP endpoint returns when it accepts some but not all items.

Each rejected* counter reports how many spans, logs, or data points the backend dropped, and errorMessage explains why. A zero count with an empty message indicates full success. Exporters surface this without treating it as a transport failure.

import type { PartialSuccessResult } from 'internal:opentelemetry/common';

const partial: PartialSuccessResult = {
  rejectedSpans: 2,
  rejectedLogs: 0,
  rejectedDataPoints: 0,
  errorMessage: 'span attribute limit exceeded',
};

Properties

rejectedSpans: number

rejectedSpans property on PartialSuccessResult.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: PartialSuccessResult['rejectedSpans'];
rejectedLogs: number

rejectedLogs property on PartialSuccessResult.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: PartialSuccessResult['rejectedLogs'];
rejectedDataPoints: number

rejectedDataPoints property on PartialSuccessResult.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: PartialSuccessResult['rejectedDataPoints'];
errorMessage: string

errorMessage property on PartialSuccessResult.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: PartialSuccessResult['errorMessage'];

interface ProviderOptions {

Options shared by every signal provider (tracer, meter, logger).

resource describes the entity producing telemetry and may be a Resource, a plain attribute map (normalized via normalizeResource), or null to accept the default resource. Passed to BaseProvider.

import type { ProviderOptions } from 'internal:opentelemetry/common';

const options: ProviderOptions = {
  resource: { 'service.name': 'checkout', 'service.version': '4.2.0' },
};

Properties

resource?: Resource | Attributes | null

resource property on ProviderOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: ProviderOptions['resource'];

interface ResourceOptions {

Secondary options for constructing a Resource beyond its attribute map.

droppedAttributesCount records attributes elided before construction, entityRefs declares OTel entity references (each with a type and identifying key set), and schemaUrl pins the semantic-convention schema. All optional.

import { Resource } from 'internal:opentelemetry/common';
import type { ResourceOptions } from 'internal:opentelemetry/common';

const options: ResourceOptions = {
  schemaUrl: 'https://opentelemetry.io/schemas/1.24.0',
};
const resource = new Resource({ 'service.name': 'api' }, options);

Properties

droppedAttributesCount?: number

droppedAttributesCount property on ResourceOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: ResourceOptions['droppedAttributesCount'];
entityRefs?: Array<{ schemaUrl?: string; type?: string; idKeys?: string[]; }>

entityRefs property on ResourceOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: ResourceOptions['entityRefs'];
schemaUrl?: string | null

schemaUrl property on ResourceOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: ResourceOptions['schemaUrl'];

interface RetryOptions {

Exporter retry policy for transient export failures.

maxAttempts bounds the total number of tries and initialBackoffMillis is the first backoff delay, typically grown exponentially on each retry. Omitting a field falls back to the exporter's built-in default.

import type { RetryOptions } from 'internal:opentelemetry/common';

const retry: RetryOptions = { maxAttempts: 5, initialBackoffMillis: 250 };

Properties

maxAttempts?: number

maxAttempts property on RetryOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RetryOptions['maxAttempts'];
initialBackoffMillis?: number

initialBackoffMillis property on RetryOptions.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RetryOptions['initialBackoffMillis'];

interface RuntimeDnsEvent {

Payload published on the otel:runtime:dns topics for a DNS lookup lifecycle.

lookupId correlates the phases of one lookup and requestId ties it back to the originating HTTP request when known. hop orders multiple lookups within a request. The resolved address/family and any error describe the outcome. Consumed by the DNS instrumentation to build client spans.

import type { RuntimeDnsEvent } from 'internal:opentelemetry/common';

const event: RuntimeDnsEvent = {
  lookupId: 'dns-1',
  hostname: 'example.com',
  address: '93.184.216.34',
  family: 4,
};

Properties

lookupId: string

lookupId property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['lookupId'];
requestId?: string

requestId property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['requestId'];
hop?: number

hop property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['hop'];
hostname?: string

hostname property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['hostname'];
address?: string

address property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['address'];
family?: string | number

family property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['family'];
error?: unknown

error property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['error'];
timeUnixNano?: number

timeUnixNano property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['timeUnixNano'];
resource?: Resource

resource property on RuntimeDnsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeDnsEvent['resource'];

interface RuntimeHttpRequestEvent {

Payload published on the otel:runtime:http.server/fetch topics for an HTTP request lifecycle.

requestId correlates the start, end, and error phases of one request. method, route, url, and headers describe the request; statusCode and error describe the outcome. The HTTP-server and fetch instrumentations subscribe to these and translate them into spans.

import type { RuntimeHttpRequestEvent } from 'internal:opentelemetry/common';

const event: RuntimeHttpRequestEvent = {
  requestId: 'req-1',
  method: 'GET',
  route: '/orders/:id',
  statusCode: 200,
};

Properties

requestId: string

requestId property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['requestId'];
method?: string

method property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['method'];
route?: string

route property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['route'];
url?: string

url property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['url'];
headers?: CarrierLike

headers property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['headers'];
statusCode?: number

statusCode property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['statusCode'];
error?: unknown

error property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['error'];
timeUnixNano?: number

timeUnixNano property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['timeUnixNano'];
resource?: Resource

resource property on RuntimeHttpRequestEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeHttpRequestEvent['resource'];

interface RuntimeSocketEvent {

Payload published on the otel:runtime:socket topics for a TCP/socket connect lifecycle.

connectId correlates the phases of one connection attempt and requestId ties it to the originating request. host, port, and transport describe the peer; hop orders retries; error describes a failed connect. Consumed by the socket instrumentation.

import type { RuntimeSocketEvent } from 'internal:opentelemetry/common';

const event: RuntimeSocketEvent = {
  connectId: 'sock-1',
  host: '10.0.0.5',
  port: 443,
  transport: 'tcp',
};

Properties

connectId: string

connectId property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['connectId'];
requestId?: string

requestId property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['requestId'];
hop?: number

hop property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['hop'];
host?: string

host property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['host'];
port?: number

port property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['port'];
transport?: string

transport property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['transport'];
error?: unknown

error property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['error'];
timeUnixNano?: number

timeUnixNano property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['timeUnixNano'];
resource?: Resource

resource property on RuntimeSocketEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeSocketEvent['resource'];

interface RuntimeTlsEvent {

Payload published on the otel:runtime:tls topics for a TLS handshake lifecycle.

handshakeId correlates the phases of one handshake and requestId ties it to the originating request. hostname/port identify the peer, protocol reports the negotiated TLS version, and error describes a failed handshake. Consumed by the TLS instrumentation.

import type { RuntimeTlsEvent } from 'internal:opentelemetry/common';

const event: RuntimeTlsEvent = {
  handshakeId: 'tls-1',
  hostname: 'example.com',
  port: 443,
  protocol: 'TLSv1.3',
};

Properties

handshakeId: string

handshakeId property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['handshakeId'];
requestId?: string

requestId property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['requestId'];
hop?: number

hop property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['hop'];
hostname?: string

hostname property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['hostname'];
port?: number

port property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['port'];
protocol?: string

protocol property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['protocol'];
error?: unknown

error property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['error'];
timeUnixNano?: number

timeUnixNano property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['timeUnixNano'];
resource?: Resource

resource property on RuntimeTlsEvent.

Omitted optional values default to undefined; required values are expected from the producer before the record is exported or published. Consumers should tolerate missing optional fields in telemetry payloads.

let value: RuntimeTlsEvent['resource'];