I'm using rust's tracing
and tracing_subscriber
crates with .json()
to enable JSON formatting of logs:
tracing_subscriber::fmt()
.json()
.flatten_event(true)
.finish()
.init();
Consider the following example:
let v: Option<i32> = Some(5);
info!(v); // {"timestamp":"2024-08-12T23:40:48.487599Z","level":"INFO","v":5,"target":"hello_world"}
let v: Option<i32> = None;
info!(v); // {"timestamp":"2024-08-12T23:40:48.487624Z","level":"INFO","target":"hello_world"}
Whilst both produce valid JSON, the v
field is omitted when the v
is None
.
I would like the field to still be printed with "v": null
, so it's clear to a reader that the field would normally be present but has no value.
Does anyone know of a way to do this?
This isn't supported by the provided tracing-subscriber formatters. This goes against the norm. It is intended that subscribers use .record()
using a Visit
implementation to record the fields, but this does not yield None
values (just as it does not yield Empty
fields).
To get this behavior, you would need to use a custom FormatEvent
implementation or a completely different subscriber/layer. Such an implementation would have to look through the event's .field()
s and cross-check that with the values you recorded to see if any were missing.
I looked at using tracing's unstable valuable
feature, but that can't yield null
either (closest analogue is the "unit" variant, but that would output "v": "()"
from the JSON serializer).