Skip to content

Commit ac19ddd

Browse files
authored
add kv-logging to async-log (#5)
Signed-off-by: Yoshua Wuyts <[email protected]>
1 parent 6552030 commit ac19ddd

File tree

5 files changed

+82
-29
lines changed

5 files changed

+82
-29
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ readme = "README.md"
1212
edition = "2018"
1313

1414
[dependencies]
15-
log = { version = "0.4.6", features = ["std"] }
16-
backtrace = "0.3.32"
15+
log = { version = "0.4.8", features = ["std", "kv_unstable"] }
16+
backtrace = "0.3.34"
1717
async-log-attributes = { path = "async-log-attributes", version = "1.0.1" }
1818

1919
[dev-dependencies]
20-
env_logger = "0.6.1"
20+
femme = "1.2.0"
2121

2222
[workspace]
2323
members = [

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ use async_log::span;
8989
use log::info;
9090

9191
fn setup_logger() {
92-
let logger = env_logger::Builder::new()
93-
.filter(None, log::LevelFilter::Trace)
94-
.build();
95-
92+
let logger = femme::pretty::Logger::new();
9693
async_log::Logger::wrap(logger, || 12)
9794
.start(log::LevelFilter::Trace)
9895
.unwrap();

examples/trace.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ use async_log::{instrument, span};
22
use log::info;
33

44
fn setup_logger() {
5-
let logger = env_logger::Builder::new()
6-
.filter(None, log::LevelFilter::Trace)
7-
.build();
8-
5+
let logger = femme::pretty::Logger::new();
96
async_log::Logger::wrap(logger, || /* get the task id here */ 0)
107
.start(log::LevelFilter::Trace)
118
.unwrap();
@@ -14,17 +11,17 @@ fn setup_logger() {
1411
fn main() {
1512
setup_logger();
1613

17-
span!("new level, depth={}", 1, {
14+
span!("level {}", 1, {
1815
let x = "beep";
19-
info!("look at this value, x={}", x);
16+
info!("look at this value: {}", x);
2017

21-
span!("new level, depth={}", 2, {
18+
span!("level {}", 2, {
2219
inner("boop");
2320
})
2421
})
2522
}
2623

2724
#[instrument]
2825
fn inner(y: &str) {
29-
info!("another nice value, y={}", y);
26+
info!("another nice value: {}", y);
3027
}

src/lib.rs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,7 @@
8282
//! use log::info;
8383
//!
8484
//! fn setup_logger() {
85-
//! let logger = env_logger::Builder::new()
86-
//! .filter(None, log::LevelFilter::Trace)
87-
//! .build();
88-
//!
85+
//! let logger = femme::pretty::Logger::new();
8986
//! async_log::Logger::wrap(logger, || 12)
9087
//! .start(log::LevelFilter::Trace)
9188
//! .unwrap();
@@ -113,6 +110,8 @@
113110

114111
pub use async_log_attributes::instrument;
115112

113+
use std::fmt::Arguments;
114+
116115
mod backtrace;
117116
mod logger;
118117
mod macros;
@@ -137,7 +136,18 @@ impl Span {
137136
/// You should generally prefer to call `span!` instead of constructing this manually.
138137
pub fn new(args: impl AsRef<str>) -> Self {
139138
let args = args.as_ref();
140-
log::trace!("{}, span_mark=start", args);
139+
struct KeyValues;
140+
impl log::kv::Source for KeyValues {
141+
fn visit<'kvs>(
142+
&'kvs self,
143+
visitor: &mut dyn log::kv::Visitor<'kvs>,
144+
) -> Result<(), log::kv::Error> {
145+
visitor.visit_pair("span_mark".into(), "start".into())?;
146+
Ok(())
147+
}
148+
}
149+
150+
print(log::Level::Trace, format_args!("{}", args), KeyValues {});
141151
Self {
142152
args: args.to_owned(),
143153
}
@@ -146,6 +156,37 @@ impl Span {
146156

147157
impl Drop for Span {
148158
fn drop(&mut self) {
149-
log::trace!("{}, span_mark=end", self.args);
159+
struct KeyValues;
160+
impl log::kv::Source for KeyValues {
161+
fn visit<'kvs>(
162+
&'kvs self,
163+
visitor: &mut dyn log::kv::Visitor<'kvs>,
164+
) -> Result<(), log::kv::Error> {
165+
visitor.visit_pair("span_mark".into(), "end".into())?;
166+
Ok(())
167+
}
168+
}
169+
170+
print(
171+
log::Level::Trace,
172+
format_args!("{}", self.args),
173+
KeyValues {},
174+
);
175+
}
176+
}
177+
178+
fn print(level: log::Level, msg: Arguments<'_>, key_values: impl log::kv::Source) {
179+
if level <= log::STATIC_MAX_LEVEL && level <= log::max_level() {
180+
log::logger().log(
181+
&log::Record::builder()
182+
.args(msg)
183+
.key_values(&key_values)
184+
.level(level)
185+
.target(module_path!())
186+
.module_path(Some(module_path!()))
187+
.file(Some(file!()))
188+
.line(Some(line!()))
189+
.build(),
190+
);
150191
}
151192
}

src/logger.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ where
5252
}
5353

5454
/// Get the thread id. Useful because ThreadId doesn't implement Display.
55-
fn thread_id() -> String {
55+
fn thread_id() -> u64 {
5656
let mut string = format!("{:?}", thread::current().id());
5757
string.replace_range(0..9, "");
5858
string.pop();
59-
string
59+
string.parse().unwrap()
6060
}
6161

6262
impl<L: Log, F> log::Log for Logger<L, F>
@@ -69,12 +69,14 @@ where
6969

7070
fn log(&self, record: &Record<'_>) {
7171
if self.enabled(record.metadata()) {
72-
let curr_id = self.with();
7372
let depth = self.compute_stack_depth(&record);
7473
let symbol = async_log_capture_caller(depth);
7574

76-
let thread_id = format!(", thread_id={}", thread_id());
77-
let task_id = format!(", task_id={}", curr_id);
75+
let key_values = KeyValues {
76+
thread_id: thread_id(),
77+
task_id: self.with(),
78+
kvs: record.key_values(),
79+
};
7880

7981
let (line, filename, fn_name) = if self.backtrace {
8082
match symbol {
@@ -107,15 +109,14 @@ where
107109
self.logger.log(
108110
&log::Record::builder()
109111
.args(format_args!(
110-
"{}{}{}{}{}{}",
112+
"{}{}{}{}",
111113
record.args(),
112114
filename,
113115
line,
114116
fn_name,
115-
task_id,
116-
thread_id
117117
))
118118
.metadata(record.metadata().clone())
119+
.key_values(&key_values)
119120
.level(record.level())
120121
.target(record.target())
121122
.module_path(record.module_path())
@@ -127,3 +128,20 @@ where
127128
}
128129
fn flush(&self) {}
129130
}
131+
132+
struct KeyValues<'a> {
133+
thread_id: u64,
134+
task_id: u64,
135+
kvs: &'a dyn log::kv::Source,
136+
}
137+
impl<'a> log::kv::Source for KeyValues<'a> {
138+
fn visit<'kvs>(
139+
&'kvs self,
140+
visitor: &mut dyn log::kv::Visitor<'kvs>,
141+
) -> Result<(), log::kv::Error> {
142+
self.kvs.visit(visitor)?;
143+
visitor.visit_pair("thread_id".into(), self.thread_id.into())?;
144+
visitor.visit_pair("task_id".into(), self.task_id.into())?;
145+
Ok(())
146+
}
147+
}

0 commit comments

Comments
 (0)