1mod event_recorder;
2mod fields;
3pub mod format;
4pub mod logstash;
5mod span_recorder;
6
7use crate::logstash::LogstashFormat;
8use span_recorder::SpanRecorder;
9use std::io::Write;
10use std::marker::PhantomData;
11use tracing_core::span::{Attributes, Id, Record};
12use tracing_core::{Event, Level, Subscriber};
13use tracing_subscriber::fmt::MakeWriter;
14use tracing_subscriber::layer::Context;
15use tracing_subscriber::registry::LookupSpan;
16
17pub struct Layer<S, E = LogstashFormat, W = fn() -> std::io::StdoutLock<'static>> {
18 record_separator: Vec<u8>,
19 make_writer: W,
20 event_format: E,
21 _inner: PhantomData<S>,
22}
23
24impl<S> Default for Layer<S> {
25 fn default() -> Self {
26 Self {
27 record_separator: vec![b'\n'],
28 make_writer: || std::io::stdout().lock(),
29 event_format: Default::default(),
30 _inner: Default::default(),
31 }
32 }
33}
34
35impl<S, E, W> Layer<S, E, W>
36where
37 E: format::FormatEvent + 'static,
38 S: Subscriber + for<'a> LookupSpan<'a>,
39 W: for<'writer> MakeWriter<'writer> + 'static,
40{
41 pub fn record_separator(self, separator: impl Into<Vec<u8>>) -> Layer<S, E, W> {
42 Layer {
43 record_separator: separator.into(),
44 ..self
45 }
46 }
47
48 pub fn event_format<E2>(self, event_format: E2) -> Layer<S, E2, W>
49 where
50 E2: format::FormatEvent + 'static,
51 {
52 Layer {
53 event_format,
54 record_separator: self.record_separator,
55 make_writer: self.make_writer,
56 _inner: self._inner,
57 }
58 }
59
60 pub fn with_writer<W2>(self, make_writer: W2) -> Layer<S, E, W2>
61 where
62 W2: for<'writer> MakeWriter<'writer> + 'static,
63 {
64 Layer {
65 make_writer,
66 event_format: self.event_format,
67 record_separator: self.record_separator,
68 _inner: self._inner,
69 }
70 }
71
72 fn write_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
73 let mut serializer = serde_json::Serializer::new(self.make_writer.make_writer());
74 self.event_format
75 .format_event(&mut serializer, event, ctx)
76 .unwrap();
77 let mut inner = serializer.into_inner();
78 inner.write_all(&self.record_separator).unwrap();
79 }
80}
81
82impl<S, E, W> tracing_subscriber::Layer<S> for Layer<S, E, W>
83where
84 S: Subscriber + for<'a> LookupSpan<'a>,
85 E: format::FormatEvent + 'static,
86 W: for<'writer> MakeWriter<'writer> + 'static,
87{
88 fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
89 let span = ctx.span(id).expect("Span not found, this is a bug");
90
91 let mut extensions = span.extensions_mut();
92
93 if extensions.get_mut::<E::R>().is_none() {
94 let mut recorder = self.event_format.span_recorder();
95 recorder.record_span(attrs);
96
97 extensions.insert(recorder);
98 }
99 }
100
101 fn on_record(&self, id: &Id, record: &Record<'_>, ctx: Context<'_, S>) {
102 let span = ctx.span(id).expect("Span not found, this is a bug");
103 let mut extensions = span.extensions_mut();
104
105 if let Some(fields) = extensions.get_mut::<E::R>() {
106 fields.merge(record);
107 }
108 }
109
110 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
111 self.write_event(event, ctx);
112 }
113}
114
115#[derive(Copy, Clone)]
116pub enum LoggerName {
117 Event,
118 Span,
119}
120
121#[derive(Copy, Clone)]
122pub enum DisplayLevelFilter {
123 Off,
124 All,
125 Level(Level),
126 Event,
127}
128
129impl DisplayLevelFilter {
130 pub const ERROR: DisplayLevelFilter = Self::from_level(Level::ERROR);
131 pub const WARN: DisplayLevelFilter = Self::from_level(Level::WARN);
132 pub const INFO: DisplayLevelFilter = Self::from_level(Level::INFO);
133 pub const DEBUG: DisplayLevelFilter = Self::from_level(Level::DEBUG);
134 pub const TRACE: DisplayLevelFilter = Self::from_level(Level::TRACE);
135
136 #[inline]
137 const fn from_level(level: Level) -> DisplayLevelFilter {
138 DisplayLevelFilter::Level(level)
139 }
140
141 #[inline]
142 pub fn is_enabled(&self, event: &Event, span_level: &Level) -> bool {
143 let filter_level = match self {
144 DisplayLevelFilter::Level(level) => level,
145 DisplayLevelFilter::Event => event.metadata().level(),
146 DisplayLevelFilter::All => return true,
147 DisplayLevelFilter::Off => return false,
148 };
149 filter_level >= span_level
150 }
151}