44//! using the strategy pattern with the [`LayerBuilder`] trait.
55
66use tracing:: Subscriber ;
7+ use tracing_subscriber:: fmt;
8+ use tracing_subscriber:: fmt:: format:: FmtSpan ;
9+ use tracing_subscriber:: fmt:: time:: { time, uptime, Uptime } ;
710use tracing_subscriber:: { registry:: LookupSpan , Layer } ;
811
9- use crate :: config:: { TracingConfig , WriterConfig } ;
10- use crate :: Error ;
12+ use crate :: config:: { LogTimer , TracingConfig , WriterConfig } ;
13+ use crate :: { Error , FeatureSet } ;
1114
1215/// Trait for building format-specific tracing layers
1316pub trait LayerBuilder : Send + Sync {
@@ -19,6 +22,74 @@ pub trait LayerBuilder: Send + Sync {
1922 S : Subscriber + for < ' a > LookupSpan < ' a > ;
2023}
2124
25+ fn configure_layer < S , N , L , T , W > (
26+ mut layer : fmt:: Layer < S , N , fmt:: format:: Format < L , T > , W > ,
27+ config : & TracingConfig ,
28+ ) -> Result < Box < dyn Layer < S > + Send + Sync + ' static > , Error >
29+ where
30+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
31+ N : for < ' writer > fmt:: FormatFields < ' writer > + Send + Sync + ' static ,
32+ L : Send + Sync + ' static ,
33+ fmt:: format:: Format < L , ( ) > : fmt:: FormatEvent < S , N > ,
34+ fmt:: format:: Format < L , Uptime > : fmt:: FormatEvent < S , N > ,
35+ fmt:: format:: Format < L > : fmt:: FormatEvent < S , N > ,
36+ W : for < ' writer > fmt:: MakeWriter < ' writer > + Send + Sync + ' static ,
37+ {
38+ // NOTE: Destructure to make sure we don’t miss a feature
39+ let FeatureSet {
40+ file_names,
41+ line_numbers,
42+ thread_names,
43+ thread_ids,
44+ timer,
45+ span_events,
46+ target_display,
47+ } = & config. features ;
48+ let span_events = span_events
49+ . as_ref ( )
50+ . map_or ( FmtSpan :: NONE , ToOwned :: to_owned) ;
51+
52+ // Configure features
53+ layer = layer
54+ . with_file ( * file_names)
55+ . with_line_number ( * line_numbers)
56+ . with_thread_names ( * thread_names)
57+ . with_thread_ids ( * thread_ids)
58+ . with_span_events ( span_events)
59+ . with_target ( * target_display) ;
60+
61+ // Configure timer and writer
62+ match timer {
63+ LogTimer :: None => configure_writer ( layer. without_time ( ) , & config. writer ) ,
64+ LogTimer :: Time => configure_writer ( layer. with_timer ( time ( ) ) , & config. writer ) ,
65+ LogTimer :: Uptime => configure_writer ( layer. with_timer ( uptime ( ) ) , & config. writer ) ,
66+ }
67+ }
68+
69+ fn configure_writer < S , N , L , T , W > (
70+ layer : fmt:: Layer < S , N , fmt:: format:: Format < L , T > , W > ,
71+ writer : & WriterConfig ,
72+ ) -> Result < Box < dyn Layer < S > + Send + Sync + ' static > , Error >
73+ where
74+ S : Subscriber + for < ' a > LookupSpan < ' a > ,
75+ N : for < ' writer > fmt:: FormatFields < ' writer > + Send + Sync + ' static ,
76+ L : Send + Sync + ' static ,
77+ T : Send + Sync + ' static ,
78+ fmt:: format:: Format < L , T > : fmt:: FormatEvent < S , N > ,
79+ {
80+ match writer {
81+ WriterConfig :: Stdout => Ok ( Box :: new ( layer. with_writer ( std:: io:: stdout) ) ) ,
82+ WriterConfig :: Stderr => Ok ( Box :: new ( layer. with_writer ( std:: io:: stderr) ) ) ,
83+ WriterConfig :: File ( path) => {
84+ let file = std:: fs:: OpenOptions :: new ( )
85+ . create ( true )
86+ . append ( true )
87+ . open ( path) ?;
88+ Ok ( Box :: new ( layer. with_writer ( file) ) )
89+ }
90+ }
91+ }
92+
2293/// Builder for pretty-formatted logs (development style)
2394#[ derive( Debug , Default , Clone ) ]
2495pub struct PrettyLayerBuilder ;
@@ -31,52 +102,9 @@ impl LayerBuilder for PrettyLayerBuilder {
31102 where
32103 S : Subscriber + for < ' a > LookupSpan < ' a > ,
33104 {
34- let mut layer = tracing_subscriber:: fmt:: layer ( )
35- . pretty ( )
36- . with_timer ( tracing_subscriber:: fmt:: time:: uptime ( ) ) ;
37-
38- // Configure file names
39- if config. features . file_names {
40- layer = layer. with_file ( true ) ;
41- }
42-
43- // Configure line numbers
44- if config. features . line_numbers {
45- layer = layer. with_line_number ( true ) ;
46- }
47-
48- // Configure thread names
49- if config. features . thread_names {
50- layer = layer. with_thread_names ( true ) ;
51- }
52-
53- // Configure thread IDs
54- if config. features . thread_ids {
55- layer = layer. with_thread_ids ( true ) ;
56- }
57-
58- // Configure span events
59- if let Some ( span_events) = & config. features . span_events {
60- layer = layer. with_span_events ( span_events. clone ( ) ) ;
61- }
105+ let layer = tracing_subscriber:: fmt:: layer ( ) . pretty ( ) ;
62106
63- // Configure target display
64- if !config. features . target_display {
65- layer = layer. with_target ( false ) ;
66- }
67-
68- // Configure writer
69- match & config. writer {
70- WriterConfig :: Stdout => Ok ( Box :: new ( layer. with_writer ( std:: io:: stdout) ) ) ,
71- WriterConfig :: Stderr => Ok ( Box :: new ( layer. with_writer ( std:: io:: stderr) ) ) ,
72- WriterConfig :: File ( path) => {
73- let file = std:: fs:: OpenOptions :: new ( )
74- . create ( true )
75- . append ( true )
76- . open ( path) ?;
77- Ok ( Box :: new ( layer. with_writer ( file) ) )
78- }
79- }
107+ configure_layer ( layer, config)
80108 }
81109}
82110
@@ -92,52 +120,9 @@ impl LayerBuilder for JsonLayerBuilder {
92120 where
93121 S : Subscriber + for < ' a > LookupSpan < ' a > ,
94122 {
95- let mut layer = tracing_subscriber:: fmt:: layer ( )
96- . json ( )
97- . with_timer ( tracing_subscriber:: fmt:: time:: uptime ( ) ) ;
98-
99- // Configure file names
100- if config. features . file_names {
101- layer = layer. with_file ( true ) ;
102- }
103-
104- // Configure line numbers
105- if config. features . line_numbers {
106- layer = layer. with_line_number ( true ) ;
107- }
108-
109- // Configure thread names
110- if config. features . thread_names {
111- layer = layer. with_thread_names ( true ) ;
112- }
113-
114- // Configure thread IDs
115- if config. features . thread_ids {
116- layer = layer. with_thread_ids ( true ) ;
117- }
118-
119- // Configure span events (typically disabled in production JSON)
120- if let Some ( span_events) = & config. features . span_events {
121- layer = layer. with_span_events ( span_events. clone ( ) ) ;
122- }
123-
124- // Configure target display
125- if !config. features . target_display {
126- layer = layer. with_target ( false ) ;
127- }
123+ let layer = tracing_subscriber:: fmt:: layer ( ) . json ( ) ;
128124
129- // Configure writer
130- match & config. writer {
131- WriterConfig :: Stdout => Ok ( Box :: new ( layer. with_writer ( std:: io:: stdout) ) ) ,
132- WriterConfig :: Stderr => Ok ( Box :: new ( layer. with_writer ( std:: io:: stderr) ) ) ,
133- WriterConfig :: File ( path) => {
134- let file = std:: fs:: OpenOptions :: new ( )
135- . create ( true )
136- . append ( true )
137- . open ( path) ?;
138- Ok ( Box :: new ( layer. with_writer ( file) ) )
139- }
140- }
125+ configure_layer ( layer, config)
141126 }
142127}
143128
@@ -153,51 +138,9 @@ impl LayerBuilder for FullLayerBuilder {
153138 where
154139 S : Subscriber + for < ' a > LookupSpan < ' a > ,
155140 {
156- let mut layer =
157- tracing_subscriber:: fmt:: layer ( ) . with_timer ( tracing_subscriber:: fmt:: time:: uptime ( ) ) ;
158-
159- // Configure file names
160- if config. features . file_names {
161- layer = layer. with_file ( true ) ;
162- }
163-
164- // Configure line numbers
165- if config. features . line_numbers {
166- layer = layer. with_line_number ( true ) ;
167- }
168-
169- // Configure thread names
170- if config. features . thread_names {
171- layer = layer. with_thread_names ( true ) ;
172- }
141+ let layer = tracing_subscriber:: fmt:: layer ( ) ;
173142
174- // Configure thread IDs
175- if config. features . thread_ids {
176- layer = layer. with_thread_ids ( true ) ;
177- }
178-
179- // Configure span events
180- if let Some ( span_events) = & config. features . span_events {
181- layer = layer. with_span_events ( span_events. clone ( ) ) ;
182- }
183-
184- // Configure target display
185- if !config. features . target_display {
186- layer = layer. with_target ( false ) ;
187- }
188-
189- // Configure writer
190- match & config. writer {
191- WriterConfig :: Stdout => Ok ( Box :: new ( layer. with_writer ( std:: io:: stdout) ) ) ,
192- WriterConfig :: Stderr => Ok ( Box :: new ( layer. with_writer ( std:: io:: stderr) ) ) ,
193- WriterConfig :: File ( path) => {
194- let file = std:: fs:: OpenOptions :: new ( )
195- . create ( true )
196- . append ( true )
197- . open ( path) ?;
198- Ok ( Box :: new ( layer. with_writer ( file) ) )
199- }
200- }
143+ configure_layer ( layer, config)
201144 }
202145}
203146
@@ -213,52 +156,9 @@ impl LayerBuilder for CompactLayerBuilder {
213156 where
214157 S : Subscriber + for < ' a > LookupSpan < ' a > ,
215158 {
216- let mut layer = tracing_subscriber:: fmt:: layer ( )
217- . compact ( )
218- . with_timer ( tracing_subscriber:: fmt:: time:: uptime ( ) ) ;
219-
220- // Configure file names
221- if config. features . file_names {
222- layer = layer. with_file ( true ) ;
223- }
224-
225- // Configure line numbers
226- if config. features . line_numbers {
227- layer = layer. with_line_number ( true ) ;
228- }
229-
230- // Configure thread names
231- if config. features . thread_names {
232- layer = layer. with_thread_names ( true ) ;
233- }
234-
235- // Configure thread IDs
236- if config. features . thread_ids {
237- layer = layer. with_thread_ids ( true ) ;
238- }
239-
240- // Configure span events
241- if let Some ( span_events) = & config. features . span_events {
242- layer = layer. with_span_events ( span_events. clone ( ) ) ;
243- }
244-
245- // Configure target display
246- if !config. features . target_display {
247- layer = layer. with_target ( false ) ;
248- }
159+ let layer = tracing_subscriber:: fmt:: layer ( ) . compact ( ) ;
249160
250- // Configure writer
251- match & config. writer {
252- WriterConfig :: Stdout => Ok ( Box :: new ( layer. with_writer ( std:: io:: stdout) ) ) ,
253- WriterConfig :: Stderr => Ok ( Box :: new ( layer. with_writer ( std:: io:: stderr) ) ) ,
254- WriterConfig :: File ( path) => {
255- let file = std:: fs:: OpenOptions :: new ( )
256- . create ( true )
257- . append ( true )
258- . open ( path) ?;
259- Ok ( Box :: new ( layer. with_writer ( file) ) )
260- }
261- }
161+ configure_layer ( layer, config)
262162 }
263163}
264164
0 commit comments