Closed Raniz85 closed 4 years ago
If you're OK with it, how about using an existing json crate? It'll have robust handling of this kind of issue.
For instance, using serde_json
, I think something like the following should work:
fn main() {
let mut dispatch = fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}",
serde_json::to_string(&serde_json::json!(
{
"message": message,
}
)).expect("formatting `serde_json::Value` with string keys never fails")
))
})
.chain(std::io::stdout())
.apply().unwrap();
log::info!("This is a single line and works fine");
log::info!("This is mulitple lines\n and doesn't produce valid JSON");
}
This has the disadvantage of making multiple allocations per message, but it'll be quite robust.
If serde_json
is too heavy weight, then tinyjson
might be better? It has a much lower compile-time cost, and the runtime will probably be slightly faster as well.
fn main() {
let mut dispatch = fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{{\"message\":{}}}",
tinyjson::JsonValue::String(message.to_string()).stringify()
.expect("no inf floats in a string")
))
})
.chain(std::io::stdout())
.apply().unwrap();
log::info!("This is a single line and works fine");
log::info!("This is mulitple lines\n and doesn't produce valid JSON");
}
Let me know what your constraints are, and we might be able to find a better solution?
Using serde_json hadn't occured to me, but that works really well.
Thanks!
Maybe mention this in the docs? :)
I'd originally thought that structured logging would be coming to log
a lot sooner and we'd be able to add builtin json/other serde logging based on that. But I think you might be right - adding documentation for doing this with regular logging would be a good idea.
Key/Value logging seems to have arrived in the log crate now.
https://docs.rs/log/0.4.8/log/struct.Record.html#method.key_values
Oh! I must have not been watching the right issues/etc. I'll have to go back and look at when that happened, and see if there's anything we want to change in fern
based on that.
Thanks!
Looks like it's still unstable right now, but other logging crates have already started integrating into it.
I've opened https://github.com/daboross/fern/issues/63 to do some initial brainstorming for how fern should support this. I probably won't have time to actually do the planning nor implementation soon, but this will track it for the future.
I'm trying to implement JSON logging using fern, but I'm having issues with messages containing newlines.
See this example program:
And the output:
Is there any good way of escaping the newline(s) in the message?