Skip to content

Commit 34d1aaf

Browse files
committed
ops: improve ergonomics of tracing_log_handler
Add DebugJson newtype for wrapping serde::Serialize types with a debug formatter that outputs styled, colorized JSON if stderr is a terminal.
1 parent 5891541 commit 34d1aaf

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ops/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ license.workspace = true
1212
proto-flow = { path = "../proto-flow" }
1313

1414
anyhow = { workspace = true }
15+
colored_json = { workspace = true }
1516
lazy_static = { workspace = true }
1617
regex = { workspace = true }
1718
serde = { workspace = true }

crates/ops/src/decode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ where
134134

135135
Log {
136136
meta: None,
137-
timestamp: Some(proto_flow::as_timestamp(ts.into())),
137+
timestamp: Some(proto_flow::as_timestamp(ts)),
138138
level: level as i32,
139139
message,
140140
fields_json_map: fields

crates/ops/src/lib.rs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use serde::{de::Error, Deserialize, Serialize};
2+
use std::collections::BTreeMap;
23
use std::io::Write;
34

45
pub mod decode;
@@ -91,34 +92,62 @@ where
9192
}
9293
}
9394

94-
// new_tracing_dispatch_handler returns a log handler that
95-
// writes tracing events using the given dispatcher.
96-
pub fn new_tracing_dispatch_handler(
97-
dispatcher: ::tracing::Dispatch,
98-
) -> impl Fn(&Log) + Send + Sync + Clone + 'static {
99-
move |log| ::tracing::dispatcher::with_default(&dispatcher, || tracing_log_handler(log))
100-
}
101-
10295
/// tracing_log_handler is a log handler that writes logs
10396
/// as tracing events.
10497
pub fn tracing_log_handler(
10598
Log {
10699
level,
107-
fields_json_map: fields,
100+
fields_json_map,
108101
message,
109102
..
110103
}: &Log,
111104
) {
105+
let fields = DebugJson(
106+
fields_json_map
107+
.iter()
108+
.map(|(k, v)| {
109+
(
110+
k.clone(),
111+
serde_json::value::RawValue::from_string(v.clone()).unwrap(),
112+
)
113+
})
114+
.collect::<BTreeMap<_, _>>(),
115+
);
116+
112117
match LogLevel::from_i32(*level).unwrap_or_default() {
113-
LogLevel::Trace => ::tracing::trace!(?fields, message),
114-
LogLevel::Debug => ::tracing::debug!(?fields, message),
115-
LogLevel::Info => ::tracing::info!(?fields, message),
116-
LogLevel::Warn => ::tracing::warn!(?fields, message),
117-
LogLevel::Error => ::tracing::error!(?fields, message),
118+
LogLevel::Trace => ::tracing::trace!(message, ?fields),
119+
LogLevel::Debug => ::tracing::debug!(message, ?fields),
120+
LogLevel::Info => ::tracing::info!(message, ?fields),
121+
LogLevel::Warn => ::tracing::warn!(message, ?fields),
122+
LogLevel::Error => ::tracing::error!(message, ?fields),
118123
LogLevel::UndefinedLevel => (),
119124
}
120125
}
121126

127+
/// DebugJson is a new-type wrapper around any Serialize implementation
128+
/// that wishes to support the Debug trait via JSON encoding itself.
129+
/// If stderr is a terminal, it colorizes and styles its output for legibility.
130+
pub struct DebugJson<S: Serialize>(pub S);
131+
132+
impl<S: Serialize> std::fmt::Debug for DebugJson<S> {
133+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134+
use colored_json::{ColorMode, ColoredFormatter, CompactFormatter, Output, Styler};
135+
136+
let value = ColoredFormatter::with_styler(
137+
CompactFormatter {},
138+
// This can be customized, but it's default already matches `jq` 👍.
139+
Styler::default(),
140+
)
141+
.to_colored_json(
142+
&serde_json::to_value(&self.0).unwrap(),
143+
ColorMode::Auto(Output::StdErr),
144+
)
145+
.unwrap();
146+
147+
f.write_str(&value)
148+
}
149+
}
150+
122151
#[cfg(test)]
123152
mod test {
124153
use super::{Log, LogLevel};

0 commit comments

Comments
 (0)