structured logging: Add a list of fields to Metadata
It would be handy to have a list of fields, and some basic metadata about them (name, formatting options, etc) available in Metadata when structured logging is being used.
My desired use case here is something that is currently possible with tracing: In OpenVMM we have implemented a 'tagging' system for events, where by including a field with a known name and a value of tracing::Empty we can filter out the logging of events based on the presence or absence of these tags. See https://github.com/microsoft/openvmm/blob/main/vm/cvm_tracing/src/lib.rs if you're curious as to how this all works. And since tracing::Empty doesn't generate any output these tags are completely transparent to the final produced logs. I'm hoping Value::null() could be used for the same in log?
I guess could be done by visiting the whole record instead of relying on Metadata and enabled? It'd be nice if this could all be handled in enabled though.
Hi @smalis-msft :wave:
log's metadata is simpler than tracing's. It doesn't include a list of key-values that will be present on the resulting log record. The closest feature it has to what you're currently doing is the target, which can be set to an arbitrary string, but is usually the name of the module that generated the event.
log also doesn't have an equivalent of tracing::Empty. If a key is present then it's defined and can be serialized, even if its value is null. If a key is not present then it's undefined.
You could probably implement this as a wrapper over log, by defining macros that accepted your tags, then filtered based on those, then forwarded matching records through to the underlying logger.
If we were to implement something like this in log itself, it might look like this:
- Add an internal
&'a [&'a str]list toMetadatato describe the keys that appear in the macro, and aMetadata::has_key(&self, &str) -> boolmethod to query whether a key is present. - Add a
:metaannotation to thelogmacros for key-values that should be present in the metadata, but not the resulting log record.
1 is exactly what I had in mind, and might be a good addition in general. 2 is an interesting thought, but I think we could also just skip certain fields in our particular implementation of Log to accomplish the same thing without any new crate functionality.
Or perhaps 1 should include a new KeyMetadata struct that can include more than just the name? Either way works.
We try to keep the API surface area here in log small, so as a start I think we could commit to Metadata::has_key using data populated by the macros, and consider expanding that over time. I don't think we should expose a public way to set the keys on MetadataBuilder yet, until we decide on what the metadata API for key values might look like.