In this lesson, you will learn how to bypass standard OpenTelemetry protocol (OTLP) exporters to pipe your application's telemetry directly into proprietary or non-standard downstream systems.
While most observability stacks rely on standardized OTLP, you may occasionally encounter "black box" legacy systems or proprietary message brokers that require data in a specific binary format or a non-standard JSON schema. In Node.js, an exporter is effectively a class that implements the Exporter interface, which provides a export(spans, resultCallback) method.
Instead of pushing data to an HTTP/gRPC endpoint, a custom exporter acts as a bridge, transforming the ReadableSpan objects into your target format before forwarding them.
Implementing a Custom Exporter
To create a custom exporter, you define a class that processes the array of spans. You can then register this with your TracerProvider.
class ProprietaryBinaryExporter {
export(spans, resultCallback) {
try {
// 1. Transform OTel spans into your proprietary schema
const formattedData = spans.map(span => ({
id: span.spanContext().spanId,
custom_payload: Buffer.from(span.name).toString('base64')
}));
// 2. Dispatch to your proprietary endpoint (e.g., a custom TCP socket)
myCustomClient.send(formattedData);
resultCallback({ code: 0 }); // ExportSuccess
} catch (e) {
resultCallback({ code: 1, error: e }); // ExportFailed
}
}
shutdown() { return Promise.resolve(); }
}
// Registering the exporter
const provider = new BasicTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ProprietaryBinaryExporter()));
The key to a successful custom exporter is handling the resultCallback appropriately. Because Node.js is asynchronous and event-driven, your exporter must signal success or failure to the OTel SDK to ensure that spans are either cleared from the buffer or retried. Avoid performing heavy compute or synchronous I/O directly within the export method, as this can block the event loop and introduce latency into your production application. If your formatting logic is CPU-intensive, offload it to a worker thread or process the data in small, non-blocking batches.
Key Takeaway: A custom exporter is simply a transformation layer that maps standard OTel telemetry objects into the specific data structure required by your legacy or proprietary observability infrastructure.