Context
OTEL traces export verbose span names and noisy transport spans that clutter observability backends and increase costs:
- gRPC spans use full paths like
/pkg.Service/V0GetStats instead of just V0GetStats
- HTTP transport spans (
ServeHTTP) appear in every trace but provide little value
Proposal
Add a configurable span processor layer between span creation and export that supports:
- Span filtering — drop spans by name or custom criteria before export
- Span transformation — rename spans (e.g., extract method name from gRPC path)
- Extensibility — allow services to provide custom filter/transform logic at runtime
Configuration should be available via:
- Environment variables for common cases (filter list, naming format)
Impact
- Reduced trace volume → lower observability costs
- Cleaner span names → easier trace navigation
- Extensible → services can add custom filtering without forking
- No breaking changes — defaults preserve existing behavior
Files
otel/spanprocessor.go — new SpanProcessor, interfaces, renamedSpan wrapper
otel/spanprocessor_test.go — unit tests
config/config.go — new config fields
initializers.go — wrap BatchSpanProcessor, expose runtime APIs
core.go — pass config to OTLPConfig
Context
OTEL traces export verbose span names and noisy transport spans that clutter observability backends and increase costs:
/pkg.Service/V0GetStatsinstead of justV0GetStatsServeHTTP) appear in every trace but provide little valueProposal
Add a configurable span processor layer between span creation and export that supports:
Configuration should be available via:
Impact
Files
otel/spanprocessor.go— new SpanProcessor, interfaces, renamedSpan wrapperotel/spanprocessor_test.go— unit testsconfig/config.go— new config fieldsinitializers.go— wrap BatchSpanProcessor, expose runtime APIscore.go— pass config to OTLPConfig