logforth_append_fastrace/
lib.rs1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
18
19use std::borrow::Cow;
20
21use jiff::Zoned;
22use logforth_core::Diagnostic;
23use logforth_core::Error;
24use logforth_core::append::Append;
25use logforth_core::kv::Key;
26use logforth_core::kv::Value;
27use logforth_core::kv::Visitor;
28use logforth_core::record::Record;
29
30#[derive(Default, Debug, Clone)]
40#[non_exhaustive]
41pub struct FastraceEvent {}
42
43impl Append for FastraceEvent {
44 fn append(&self, record: &Record, diags: &[Box<dyn Diagnostic>]) -> Result<(), Error> {
45 let message = format!("{}", record.args());
46
47 let mut collector = KvCollector { kv: Vec::new() };
48 record.key_values().visit(&mut collector)?;
49 for d in diags {
50 d.visit(&mut collector)?;
51 }
52
53 fastrace::local::LocalSpan::add_event(fastrace::Event::new(message).with_properties(
54 || {
55 [
56 (Cow::from("level"), Cow::from(record.level().as_str())),
57 (Cow::from("timestamp"), Cow::from(Zoned::now().to_string())),
58 ]
59 .into_iter()
60 .chain(
61 collector
62 .kv
63 .into_iter()
64 .map(|(k, v)| (Cow::from(k), Cow::from(v))),
65 )
66 },
67 ));
68
69 Ok(())
70 }
71
72 fn flush(&self) -> Result<(), Error> {
73 fastrace::flush();
74 Ok(())
75 }
76}
77
78struct KvCollector {
79 kv: Vec<(String, String)>,
80}
81
82impl Visitor for KvCollector {
83 fn visit(&mut self, key: Key, value: Value) -> Result<(), Error> {
84 self.kv.push((key.into_string(), value.to_string()));
85 Ok(())
86 }
87}