tracing_formatters/
log_layer.rs1use crate::formatter::LogFormatter;
2use crate::get_exec_name;
3use crate::log_value::LogValue;
4use crate::storage::Storage;
5use actix_web::cookie::time::format_description::well_known::Rfc3339;
6use chrono::Utc;
7use core::fmt;
8use std::collections::HashMap;
9use std::io::Write;
10use std::marker::PhantomData;
11use tracing::span::Attributes;
12use tracing::{Event, Id, Subscriber};
13use tracing_subscriber::fmt::MakeWriter;
14use tracing_subscriber::layer::Context;
15use tracing_subscriber::Layer;
16
17const TRACING_COMMON: &'static str = "tracing-log.";
18const TRACING_OVERWRITES: &'static str = "tracing-log.overwrites.";
19
20pub struct LogLayer<W: for<'a> MakeWriter<'a> + 'static, F: LogFormatter + Default> {
21 make_writer: W,
22 version: Option<i32>,
23 hostname: Option<String>,
24 application: Option<String>,
25 proc_id: Option<u32>,
26 phantom: PhantomData<F>,
27}
28
29impl<W: for<'a> MakeWriter<'a> + 'static, F: LogFormatter + Default> LogLayer<W, F> {
30 pub fn new(name: Option<String>, make_writer: W, _: F) -> Self {
31 Self::with_default_fields(name, make_writer, HashMap::new())
32 }
33
34 pub fn with_default_fields(
35 name: Option<String>,
36 make_writer: W,
37 default_fields: HashMap<String, LogValue>,
38 ) -> Self {
39 println!("PROCESS ID: {}", std::process::id());
40 Self {
41 make_writer,
42 version: Option::from(1),
43 proc_id: Option::from(std::process::id()),
44 hostname: Option::from(gethostname::gethostname().to_string_lossy().into_owned()),
45 application: name.or_else(|| get_exec_name()),
46 phantom: Default::default(),
47 }
48 }
49
50 pub fn emit(&self, mut buffer: Vec<u8>) -> Result<(), std::io::Error> {
51 buffer.write_all(b"\n")?;
52 self.make_writer.make_writer().write_all(&buffer)
53 }
54
55 pub fn version(&self) -> &Option<i32> {
56 &self.version
57 }
58
59 pub fn proc_id(&self) -> &Option<u32> {
60 &self.proc_id
61 }
62
63 pub fn hostname(&self) -> &Option<String> {
64 &self.hostname
65 }
66
67 pub fn application(&self) -> &Option<String> {
68 &self.application
69 }
70}
71
72impl<S, W, F> Layer<S> for LogLayer<W, F>
73where
74 S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
75 W: for<'a> MakeWriter<'a> + 'static,
76 F: LogFormatter + Default + 'static,
77{
78 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
79 let current_span = ctx.lookup_current();
81
82 let mut event_visitor = Storage::default();
84 event.record(&mut event_visitor);
85
86 let mut entry = F::from_log_layer(self);
87
88 let _ = self.emit(
89 entry
90 .format_event(¤t_span, event, &event_visitor)
91 .into_bytes(),
92 );
93 }
94
95 fn on_new_span(&self, _attrs: &Attributes, id: &Id, ctx: Context<'_, S>) {
96 let span = ctx.span(id).expect("Span not found, this is a bug");
97 let mut entry = F::from_log_layer(self);
98 let _ = self.emit(entry.format_span(&span, Type::EnterSpan).into_bytes());
99 }
100
101 fn on_close(&self, id: Id, ctx: Context<'_, S>) {
102 let span = ctx.span(&id).expect("Span not found, this is a bug");
103 let mut entry = F::from_log_layer(self);
104 let _ = self.emit(entry.format_span(&span, Type::ExitSpan).into_bytes());
105 }
106}
107
108#[derive(Clone, Debug)]
110pub enum Type {
111 EnterSpan,
112 ExitSpan,
113 Event,
114}
115
116impl fmt::Display for Type {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 let repr = match self {
119 Type::EnterSpan => "START",
120 Type::ExitSpan => "ENDED",
121 Type::Event => "EVENT",
122 };
123 write!(f, "{}", repr)
124 }
125}