Problem
The Deserializer trait signature is:
pub trait Deserializer: DynClone + Send + Sync {
fn parse(&self, bytes: Bytes, log_namespace: LogNamespace) -> vector_common::Result<SmallVec<[Event; 1]>>;
}
log_namespace is a logs-specific concept baked into a generic interface used for all signal types (logs, metrics, traces). Every implementor — including metrics and traces deserializers — is forced to accept a parameter that may be meaningless or incorrect for their signal type.
Background
This was discovered while working on OpenTelemetry HTTP source header enrichment for metrics and traces (#24942).
When use_otlp_decoding.traces = true, OtlpDeserializer::parse is called with the user-configured log_namespace. Internally it delegates to ProtobufDeserializer::parse, which under LogNamespace::Legacy injects a timestamp into the event body. For traces this is surprising behavior — log_namespace semantics for traces have never been defined, and log_namespace by name implies it only applies to logs.
Scope of change
There are 11 Deserializer implementors all referencing log_namespace:
BytesDeserializer
JsonDeserializer
NativeJsonDeserializer
NativeDeserializer
AvroDeserializer
GelfDeserializer
InfluxdbDeserializer
SyslogDeserializer
VrlDeserializer
ProtobufDeserializer — uses it for Legacy timestamp injection
OtlpDeserializer — passes it through to sub-deserializers
Plus the trait definition in lib/codecs/src/decoding/format/mod.rs and the wrapper in lib/codecs/src/decoding/mod.rs.
Ideas
- Remove
log_namespace argument from the Deserializer trait signature. Add post-parse enrichment for logs.
- Introduce
LogDeserializer for deserializers that work on logs exclusively (log_namespace makes sense there)
This separates log-specific concerns from the generic decoding interface.
Problem
The
Deserializertrait signature is:log_namespaceis a logs-specific concept baked into a generic interface used for all signal types (logs, metrics, traces). Every implementor — including metrics and traces deserializers — is forced to accept a parameter that may be meaningless or incorrect for their signal type.Background
This was discovered while working on OpenTelemetry HTTP source header enrichment for metrics and traces (#24942).
When
use_otlp_decoding.traces = true,OtlpDeserializer::parseis called with the user-configuredlog_namespace. Internally it delegates toProtobufDeserializer::parse, which underLogNamespace::Legacyinjects a timestamp into the event body. For traces this is surprising behavior —log_namespacesemantics for traces have never been defined, andlog_namespaceby name implies it only applies to logs.Scope of change
There are 11
Deserializerimplementors all referencinglog_namespace:BytesDeserializerJsonDeserializerNativeJsonDeserializerNativeDeserializerAvroDeserializerGelfDeserializerInfluxdbDeserializerSyslogDeserializerVrlDeserializerProtobufDeserializer— uses it for Legacy timestamp injectionOtlpDeserializer— passes it through to sub-deserializersPlus the trait definition in
lib/codecs/src/decoding/format/mod.rsand the wrapper inlib/codecs/src/decoding/mod.rs.Ideas
log_namespaceargument from theDeserializertrait signature. Add post-parse enrichment for logs.LogDeserializerfor deserializers that work on logs exclusively (log_namespace makes sense there)This separates log-specific concerns from the generic decoding interface.