Skip to content

OpenTelemetry Sink

The OpenTelemetry sink creates a span for each session using your existing @opentelemetry/api tracer. WriteTrack doesn’t bundle the OpenTelemetry SDK — you provide your initialized tracer.

You need @opentelemetry/api v1.0.0 or later (and a configured exporter) already initialized in your application.

Terminal window
npm i @opentelemetry/api @opentelemetry/sdk-trace-web
import { WriteTrack, opentelemetry } from 'writetrack';
import { trace } from '@opentelemetry/api';
// Get your tracer (from your existing OTel setup)
const tracer = trace.getTracer('writetrack');
const tracker = new WriteTrack({
target: textarea,
userId: 'u_abc123',
});
tracker.pipe(
opentelemetry({
tracer,
})
);
tracker.start();
OptionTypeDefaultDescription
tracerOTelTracerInitialized OpenTelemetry tracer Required
spanNamestring'writetrack.session'Custom span name

The sink creates a span and sets the following attributes:

AttributeSourceTypeDescription
writetrack.durationmetadata.durationnumberSession duration in ms
writetrack.keystroke_countsession.events.lengthnumberTotal keystroke events
writetrack.quality_levelquality.qualityLevelstringQuality assessment
writetrack.target_elementmetadata.targetElementstringElement type
writetrack.schema_versionversionstringSchema version
writetrack.user_idmetadata.userIdstringUser ID (if provided)
writetrack.content_idmetadata.contentIdstringContent ID (if provided)

The span status is set to OK (code 1) on success.

tracker.pipe(
opentelemetry({
tracer,
spanName: 'typing.session.captured',
})
);

The span appears in your tracing backend (Jaeger, Zipkin, Honeycomb, Grafana Tempo, etc.) under the tracer name you configured. Filter by:

  • Span name: writetrack.session
  • Attribute: writetrack.quality_level = EXCELLENT
  • Attribute: writetrack.user_id = u_abc123

The span is always ended in a finally block, even if setting attributes fails. Errors are caught and emitted as pipe:error events.

tracker.on('pipe:error', (err, sink) => {
console.error('OpenTelemetry sink failed:', err);
});