Recording-Tracer
RecordingTracer ist das Test-Pendant zu
OtelTracerAdapter.
Anstatt Spans zu exportieren, speichert er sie im Speicher —
Tests asserten auf die aufgezeichneten Spans.
import { TestKit, RecordingTracer, TracingExtensionId } from 'actor-ts';
const tracer = new RecordingTracer();const tk = TestKit.create();tk.system.extension(TracingExtensionId).configure({ tracer });
// ... Actor ausführen ...ref.tell({ kind: 'process' });await probe.expectMsg(...);
// Auf aufgezeichnete Spans asserten:const spans = tracer.recordedSpans();expect(spans).toHaveLength(1);expect(spans[0].name).toBe('actor.receive');expect(spans[0].attributes['actor.path']).toContain('worker');Was er aufzeichnet
Abschnitt betitelt „Was er aufzeichnet“Jeder RecordedSpan:
interface RecordedSpan { name: string; context: SpanContext; parent?: SpanContext; attributes: Record<string, AttributeValue>; events: Array<{ name: string; attrs: ... }>; status: { status: 'ok' | 'error'; message?: string }; startTimeMs: number; endTimeMs: number; ended: boolean; kind: SpanKind;}Du siehst, welche Attribute gesetzt wurden, wann der Span gestartet + beendet wurde, seine Art, seinen Parent (zum Verifizieren von Kausalitätsketten) und seinen Endstatus.
Die API
Abschnitt betitelt „Die API“class RecordingTracer implements Tracer { // ... volles Tracer-Interface ...
recordedSpans(): RecordedSpan[]; // alle Spans, inkl. unbeendeter finishedSpans(): RecordedSpan[]; // Spans, bei denen end() aufgerufen wurde reset(): void; // aufgezeichneten Zustand leeren}recordedSpans gibt jeden Span zurück, den der Tracer erzeugen
sollte. finishedSpans filtert auf die, die beendet wurden —
nützlich, um „Span gestartet und nie beendet”-Bugs zu erkennen.
Übliche Assertion-Muster
Abschnitt betitelt „Übliche Assertion-Muster“„Hat das Framework die Nachricht dieses Actors auto-gespan’d?”
Abschnitt betitelt „„Hat das Framework die Nachricht dieses Actors auto-gespan’d?”“ref.tell({ kind: 'work' });await probe.expectMsg(...);
const spans = tracer.finishedSpans();const receive = spans.find(s => s.name === 'actor.receive' && s.attributes['actor.path']?.includes('worker'));expect(receive).toBeDefined();expect(receive!.status.status).toBe('ok');„Hat mein Custom-Span mit den richtigen Attributen gefeuert?”
Abschnitt betitelt „„Hat mein Custom-Span mit den richtigen Attributen gefeuert?”“const orderSpan = tracer.finishedSpans().find(s => s.name === 'place-order');expect(orderSpan).toBeDefined();expect(orderSpan!.attributes['order.id']).toBe('o-1');expect(orderSpan!.attributes['order.amount']).toBe(42);„Haben sich die Spans korrekt verkettet?”
Abschnitt betitelt „„Haben sich die Spans korrekt verkettet?”“const spans = tracer.finishedSpans();const parent = spans.find(s => s.name === 'http-request');const child = spans.find(s => s.name === 'db-query');
expect(child!.parent?.traceId).toBe(parent!.context.traceId);Nützlich zum Verifizieren der Trace-Kausalität — Parent- Kontext korrekt an Child-Spans propagiert.
Zwischen Tests zurücksetzen
Abschnitt betitelt „Zwischen Tests zurücksetzen“beforeEach(() => tracer.reset());Ohne Reset akkumulieren aufgezeichnete Spans über Tests hinweg. Reset bei jedem Test, um Assertions nur auf die Spans des aktuellen Tests zu halten.
Performance
Abschnitt betitelt „Performance“Aufzeichnen ist billig — Anhängen an ein Array. Aber Spans
akkumulieren im Speicher. Bei langen Test-Läufen periodisch
reset, um Speicher-Wachstum zu vermeiden.
Wann NICHT nutzen
Abschnitt betitelt „Wann NICHT nutzen“Wo es weitergeht
Abschnitt betitelt „Wo es weitergeht“- Tracer-API — das Interface, das dies implementiert.
- OTel-Adapter — die Produktions-Alternative.
- Actor-Tracing — was das Framework auto-span’d, beobachtbar via diesen Tracer.
- TestKit — kombiniere mit dem Recording-Tracer für assertions-freundliche Tests.
Die RecordingTracer-API-
Referenz deckt die volle Oberfläche ab.