Zum Inhalt springen
Deutsch

OTel-Tracing-Adapter

otelTracer(...) ist der produktionstaugliche Tracer. Er überbrückt das Tracer- Interface des Frameworks zur OpenTelemetry-API, sodass Spans zu dem Backend fließen, das du konfiguriert hast (Jaeger, Tempo, Honeycomb, Datadog, New Relic, Grafana Cloud).

Es ist eine Funktion, keine Klasse — du reichst ihr die @opentelemetry/api-Namespace (via OtelAdapterOptions) und installierst das Ergebnis auf der Tracing-Extension:

import * as otel from '@opentelemetry/api';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { ActorSystem, TracingExtensionId, otelTracer, OtelAdapterOptions } from 'actor-ts';
// 1. Set up the OTel SDK (exports spans to your backend)
const provider = new NodeTracerProvider({
spanProcessors: [new BatchSpanProcessor(
new OTLPTraceExporter({ url: 'https://otel-collector.example.com/v1/traces' }),
)],
});
provider.register();
// 2. Build the framework tracer from the @opentelemetry/api namespace
const system = ActorSystem.create('my-app');
const otelAdapterOptions = OtelAdapterOptions.create()
.withApi(otel)
.withTracerName('actor-ts')
.withTracerVersion('1.0.0');
system.extension(TracingExtensionId).enable(otelTracer(otelAdapterOptions));

Damit fließen die Auto-Spans des Frameworks (einer pro Actor-Nachricht) zu deinem Tracing-Backend, über Cluster-Nodes hinweg mit W3C-traceparent-Kontext verbunden.

otelTracer nimmt ein OtelAdapterOptions — den Builder oder das schlichte Objekt. withApi ist Pflicht: der Adapter delegiert an das, was du übergibst, und dank struktureller Typisierung importiert das Framework @opentelemetry/api nie selbst.

type OtelAdapterOptionsType = {
api: OtelApiLike; // the @opentelemetry/api namespace (required)
tracer?: OtelTracerLike; // pre-built tracer; else api.trace.getTracer(...)
tracerName?: string; // passed to getTracer; default 'actor-ts'
tracerVersion?: string; // passed to getTracer
};

Das OTel-SDK erledigt die Schwerarbeit (Export, Sampling, Batching); der Adapter übersetzt nur zwischen dem Tracer des Frameworks und der OTel-API. Du kannst statt Name/Version auch einen vorgefertigten tracer übergeben:

const otelAdapterOptions = OtelAdapterOptions.create()
.withApi(otel)
.withTracer(otel.trace.getTracer('actor-ts', '1.0.0'));
import { ParentBasedSampler, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-base';
const provider = new NodeTracerProvider({
sampler: new ParentBasedSampler({
root: new TraceIdRatioBasedSampler(0.1), // sample 10 % of traces
}),
});

Für Systeme mit hohem Durchsatz ist Sampling essenziell. Es wird auf dem OTel-SDK konfiguriert, nicht auf dem Adapter:

  • TraceIdRatioBasedSampler(0.1) — 10 % der Traces.
  • AlwaysOnSampler() — jeder Trace (Dev / geringes Volumen).
  • AlwaysOffSampler() — keiner (nur zum Debuggen).
  • ParentBasedSampler(...) — folge der Sampling-Entscheidung des Parents; sampelt stromabwärts eines bereits gesampelten Traces.

Das Framework zeichnet Spans mit voller Rate auf; das SDK entscheidet, welche exportiert werden. Ungesampelte Spans propagieren weiterhin Kontext zur Korrelation, exportieren aber nicht — null Backend-Kosten.

Das OTel-SDK unterstützt viele Exporter:

ExporterBackend
@opentelemetry/exporter-trace-otlp-httpOTLP (Tempo, Jaeger, generische Collectors)
@opentelemetry/exporter-trace-otlp-grpcOTLP via gRPC
@opentelemetry/exporter-jaegerJaeger nativ
@opentelemetry/exporter-zipkinZipkin
Vendor-spezifischDatadog, New Relic, Honeycomb, …

Wähle nach dem bevorzugten Protokoll deines Backends. OTLP-über-HTTP ist am universellsten — funktioniert mit dem OpenTelemetry Collector, der dann an jedes Backend routet.

import { Resource } from '@opentelemetry/resources';
const provider = new NodeTracerProvider({
resource: new Resource({
'service.name': 'my-app',
'service.version': '1.2.3',
'deployment.environment': 'production',
'host.name': process.env.HOSTNAME,
}),
});

Resource-Attribute werden auf jeden Span gestempelt und sind der nützlichste Ort für globalen Kontext (Service-Name, Version, Region, Pod-Name).

Terminal-Fenster
npm install @opentelemetry/api @opentelemetry/sdk-trace-node
# Plus an exporter:
npm install @opentelemetry/exporter-trace-otlp-http

Bring deine eigene SDK-+-Exporter-Kombi mit — das Framework bündelt keines von beidem. Es braucht nur die @opentelemetry/api- Namespace, die du an withApi übergibst.

Das OTel-SDK verbindet Traces, Metriken und Logs über gemeinsamen Kontext — aber das Framework liefert keine OTel-Metrik-Brücke. Nutze für Metriken den Prometheus-Exporter des Frameworks (scrape ihn in einen OpenTelemetry Collector, wenn du ihn in deiner OTLP-Pipeline willst) oder den prom-client-Adapter.

Für Logs gibt es eine OTel-Brücke — otelLogger(...), das Logging-Pendant zu otelTracer, mit derselben Namespace-übergeben-Form.