You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here, the trace id is scoped to a request and should be included in all messages logged in relation to a given request. It therefore makes sense to put it in a span rather than adding it to all events. However, in the out-of-the-box json format produced by tracing-subscriber, such fields are nested inside span or spans fields. Example:
tracing-subscriber already supports flattening the fields, but I was not able to find an equivalent feature for span or spans.
Proposal
Add flatten_span and flatten_spans configuration knobs to SubscriberBuilder to allow flattening span items directly into the top level. In combination with valuable support, this seems like a very flexible configuration allowing one to write logs in a very custom format. Possibly it should be possible to retain the span and spans fields while also flattening into the top level, since some keys may be overwritten during flattening (I suppose that is also the case for flatten_event).
Alternatives
Currently I implement a custom FormatEvent
structCloudRunEventFormat;implCloudRunEventFormat{fnnew() -> CloudRunEventFormat{CloudRunEventFormat}}impl<S,N>FormatEvent<S,N>forCloudRunEventFormatwhereS:Subscriber + for<'lookup>LookupSpan<'lookup>,N:for<'writer>FormatFields<'writer> + 'static,{fnformat_event(&self,ctx:&FmtContext<'_,S,N>,mutwriter:Writer<'_>,event:&Event<'_>,) -> std::fmt::ResultwhereS:Subscriber + for<'a>LookupSpan<'a>,{let meta = event.metadata();letmut s = Vec::<u8>::new();letmut serializer = serde_json::Serializer::new(&mut s);letmut serializer_map = serializer.serialize_map(None).unwrap();let timestamp = chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Millis,true);
serializer_map.serialize_entry("time",×tamp).unwrap();
serializer_map
.serialize_entry("severity",&meta.level().as_serde()).unwrap();ifletSome(leaf_span) = ctx.lookup_current(){for span in leaf_span.scope().from_root(){let ext = span.extensions();let data = ext
.get::<FormattedFields<N>>().expect("Unable to find FormattedFields in extensions; this is a bug");let serde_json::Value::Object(fields) =
serde_json::from_str::<serde_json::Value>(data).unwrap()else{panic!()};for field in fields {
serializer_map.serialize_entry(&field.0,&field.1).unwrap();}}}letmut visitor = tracing_serde::SerdeMapVisitor::new(serializer_map);
event.record(&mut visitor);
visitor.take_serializer().unwrap().end().unwrap();
writer.write_str(std::str::from_utf8(&s).unwrap()).unwrap();writeln!(writer)}}
This custom implementation also renames some fields (level -> severity and timestamp -> time), for which I created a separate feature request: #2671. This direction seems to imply that one would commonly need to implement a custom FormatEvent in order to interact with log ingestion agents, in which case implementing such a custom FormatEvent could probably be made more ergonomic.
The text was updated successfully, but these errors were encountered:
Feature Request
Crates
tracing-subscriber
Motivation
Many GCP services come with an out-of-process agent that will ingest logs written in a specific json format described here https://cloud.google.com/logging/docs/structured-logging. An example would be
Here, the trace id is scoped to a request and should be included in all messages logged in relation to a given request. It therefore makes sense to put it in a span rather than adding it to all events. However, in the out-of-the-box json format produced by
tracing-subscriber
, such fields are nested insidespan
orspans
fields. Example:tracing-subscriber
already supports flattening thefields
, but I was not able to find an equivalent feature forspan
orspans
.Proposal
Add
flatten_span
andflatten_spans
configuration knobs toSubscriberBuilder
to allow flattening span items directly into the top level. In combination withvaluable
support, this seems like a very flexible configuration allowing one to write logs in a very custom format. Possibly it should be possible to retain thespan
andspans
fields while also flattening into the top level, since some keys may be overwritten during flattening (I suppose that is also the case forflatten_event
).Alternatives
Currently I implement a custom
FormatEvent
This custom implementation also renames some fields (
level
->severity
andtimestamp
->time
), for which I created a separate feature request: #2671. This direction seems to imply that one would commonly need to implement a customFormatEvent
in order to interact with log ingestion agents, in which case implementing such a custom FormatEvent could probably be made more ergonomic.The text was updated successfully, but these errors were encountered: