logforth_append_fastrace/
lib.rs1#![cfg_attr(docsrs, feature(doc_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 = record.payload().to_owned();
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 fn exit(&self) -> Result<(), Error> {
78 Ok(())
81 }
82}
83
84struct KvCollector {
85 kv: Vec<(String, String)>,
86}
87
88impl Visitor for KvCollector {
89 fn visit(&mut self, key: Key, value: Value) -> Result<(), Error> {
90 self.kv.push((key.to_string(), value.to_string()));
91 Ok(())
92 }
93}