Custom Exporters
setup_telemetry supports injecting custom SpanExporter and MetricReader instances, which bypasses the configuration-based construction. This is the extension point for the following use cases:
- In-memory exporters for testing
- Custom exporters for proprietary backends
- Exporters that require fine-grained configuration that NeMo Lens does not expose
Signature
When provided, these override the config’s exporter field for that signal. You can mix these options by passing a custom span_exporter and letting metrics use the config’s exporter.
Custom Span Exporter
This is how the NeMo Lens test suite captures spans for assertions.
Custom Metric Reader
Write a Custom Exporter
To route telemetry to a backend not supported by OTLP, subclass SpanExporter:
Use the same pattern for MetricReader (refer to the OpenTelemetry documentation).
Custom Exporters and Sampling
Custom exporters plug into the BatchSpanProcessor that NeMo Lens installs. NeMo Lens does no sampling of its own, so a custom exporter receives every span the process produces; configure the OTel SDK’s OTEL_TRACES_SAMPLER if you need to reduce that. If you want a parallel processor, install your own SpanProcessor as shown below:
This approach only works when telemetry is enabled and traces are on, which is what handle.is_exporting reports. When telemetry is disabled, setup_telemetry installs a NoOpTracerProvider, so trace.get_tracer_provider() returns a no-op provider that has no add_span_processor method, and this call raises an AttributeError. Guard this call with if handle.is_exporting::
NeMo Lens does not expose an extension point for custom processors, so if you need one, add it to the provider directly after setup_telemetry returns. This is a lower-level interface, but it is stable within the OpenTelemetry SDK.
Why This API
Before this extension point, connecting NeMo Lens to a non-OTLP backend required subclassing build_providers or monkey-patching internals. Now it is a supported extension point: pass your exporter, and NeMo Lens does the rest.
The design goal is to keep NeMo Lens’s core surface small (OTLP and console are plenty for most users) while letting power users plug in whatever they need without forking NeMo Lens.