• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(feature = "env-filter")]
2 
3 mod per_layer;
4 
5 use tracing::{self, subscriber::with_default, Level};
6 use tracing_mock::{expect, layer, subscriber};
7 use tracing_subscriber::{
8     filter::{EnvFilter, LevelFilter},
9     prelude::*,
10     Registry,
11 };
12 
13 #[test]
level_filter_event()14 fn level_filter_event() {
15     let filter: EnvFilter = "info".parse().expect("filter should parse");
16     let (subscriber, finished) = subscriber::mock()
17         .event(expect::event().at_level(Level::INFO))
18         .event(expect::event().at_level(Level::WARN))
19         .event(expect::event().at_level(Level::ERROR))
20         .only()
21         .run_with_handle();
22     let subscriber = subscriber.with(filter);
23 
24     with_default(subscriber, || {
25         tracing::trace!("this should be disabled");
26         tracing::info!("this shouldn't be");
27         tracing::debug!(target: "foo", "this should also be disabled");
28         tracing::warn!(target: "foo", "this should be enabled");
29         tracing::error!("this should be enabled too");
30     });
31 
32     finished.assert_finished();
33 }
34 
35 #[test]
same_name_spans()36 fn same_name_spans() {
37     let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace"
38         .parse()
39         .expect("filter should parse");
40     let (subscriber, finished) = subscriber::mock()
41         .new_span(
42             expect::span()
43                 .named("foo")
44                 .at_level(Level::TRACE)
45                 .with_fields(expect::field("bar")),
46         )
47         .new_span(
48             expect::span()
49                 .named("foo")
50                 .at_level(Level::TRACE)
51                 .with_fields(expect::field("baz")),
52         )
53         .only()
54         .run_with_handle();
55     let subscriber = subscriber.with(filter);
56     with_default(subscriber, || {
57         tracing::trace_span!("foo", bar = 1);
58         tracing::trace_span!("foo", baz = 1);
59     });
60 
61     finished.assert_finished();
62 }
63 
64 #[test]
level_filter_event_with_target()65 fn level_filter_event_with_target() {
66     let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse");
67     let (subscriber, finished) = subscriber::mock()
68         .event(expect::event().at_level(Level::INFO))
69         .event(expect::event().at_level(Level::DEBUG).with_target("stuff"))
70         .event(expect::event().at_level(Level::WARN).with_target("stuff"))
71         .event(expect::event().at_level(Level::ERROR))
72         .event(expect::event().at_level(Level::ERROR).with_target("stuff"))
73         .only()
74         .run_with_handle();
75     let subscriber = subscriber.with(filter);
76 
77     with_default(subscriber, || {
78         tracing::trace!("this should be disabled");
79         tracing::info!("this shouldn't be");
80         tracing::debug!(target: "stuff", "this should be enabled");
81         tracing::debug!("but this shouldn't");
82         tracing::trace!(target: "stuff", "and neither should this");
83         tracing::warn!(target: "stuff", "this should be enabled");
84         tracing::error!("this should be enabled too");
85         tracing::error!(target: "stuff", "this should be enabled also");
86     });
87 
88     finished.assert_finished();
89 }
90 
91 #[test]
level_filter_event_with_target_and_span_global()92 fn level_filter_event_with_target_and_span_global() {
93     let filter: EnvFilter = "info,stuff[cool_span]=debug"
94         .parse()
95         .expect("filter should parse");
96 
97     let cool_span = expect::span().named("cool_span");
98     let (layer, handle) = layer::mock()
99         .enter(&cool_span)
100         .event(
101             expect::event()
102                 .at_level(Level::DEBUG)
103                 .in_scope(vec![cool_span.clone()]),
104         )
105         .exit(cool_span)
106         .enter("uncool_span")
107         .exit("uncool_span")
108         .only()
109         .run_with_handle();
110 
111     let subscriber = Registry::default().with(filter).with(layer);
112 
113     with_default(subscriber, || {
114         {
115             let _span = tracing::info_span!(target: "stuff", "cool_span").entered();
116             tracing::debug!("this should be enabled");
117         }
118 
119         tracing::debug!("should also be disabled");
120 
121         {
122             let _span = tracing::info_span!("uncool_span").entered();
123             tracing::debug!("this should be disabled");
124         }
125     });
126 
127     handle.assert_finished();
128 }
129 
130 #[test]
not_order_dependent()131 fn not_order_dependent() {
132     // this test reproduces tokio-rs/tracing#623
133 
134     let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse");
135     let (subscriber, finished) = subscriber::mock()
136         .event(expect::event().at_level(Level::INFO))
137         .event(expect::event().at_level(Level::DEBUG).with_target("stuff"))
138         .event(expect::event().at_level(Level::WARN).with_target("stuff"))
139         .event(expect::event().at_level(Level::ERROR))
140         .event(expect::event().at_level(Level::ERROR).with_target("stuff"))
141         .only()
142         .run_with_handle();
143     let subscriber = subscriber.with(filter);
144 
145     with_default(subscriber, || {
146         tracing::trace!("this should be disabled");
147         tracing::info!("this shouldn't be");
148         tracing::debug!(target: "stuff", "this should be enabled");
149         tracing::debug!("but this shouldn't");
150         tracing::trace!(target: "stuff", "and neither should this");
151         tracing::warn!(target: "stuff", "this should be enabled");
152         tracing::error!("this should be enabled too");
153         tracing::error!(target: "stuff", "this should be enabled also");
154     });
155 
156     finished.assert_finished();
157 }
158 
159 #[test]
add_directive_enables_event()160 fn add_directive_enables_event() {
161     // this test reproduces tokio-rs/tracing#591
162 
163     // by default, use info level
164     let mut filter = EnvFilter::new(LevelFilter::INFO.to_string());
165 
166     // overwrite with a more specific directive
167     filter = filter.add_directive("hello=trace".parse().expect("directive should parse"));
168 
169     let (subscriber, finished) = subscriber::mock()
170         .event(expect::event().at_level(Level::INFO).with_target("hello"))
171         .event(expect::event().at_level(Level::TRACE).with_target("hello"))
172         .only()
173         .run_with_handle();
174     let subscriber = subscriber.with(filter);
175 
176     with_default(subscriber, || {
177         tracing::info!(target: "hello", "hello info");
178         tracing::trace!(target: "hello", "hello trace");
179     });
180 
181     finished.assert_finished();
182 }
183 
184 #[test]
span_name_filter_is_dynamic()185 fn span_name_filter_is_dynamic() {
186     let filter: EnvFilter = "info,[cool_span]=debug"
187         .parse()
188         .expect("filter should parse");
189     let (subscriber, finished) = subscriber::mock()
190         .event(expect::event().at_level(Level::INFO))
191         .enter(expect::span().named("cool_span"))
192         .event(expect::event().at_level(Level::DEBUG))
193         .enter(expect::span().named("uncool_span"))
194         .event(expect::event().at_level(Level::WARN))
195         .event(expect::event().at_level(Level::DEBUG))
196         .exit(expect::span().named("uncool_span"))
197         .exit(expect::span().named("cool_span"))
198         .enter(expect::span().named("uncool_span"))
199         .event(expect::event().at_level(Level::WARN))
200         .event(expect::event().at_level(Level::ERROR))
201         .exit(expect::span().named("uncool_span"))
202         .only()
203         .run_with_handle();
204     let subscriber = subscriber.with(filter);
205 
206     with_default(subscriber, || {
207         tracing::trace!("this should be disabled");
208         tracing::info!("this shouldn't be");
209         let cool_span = tracing::info_span!("cool_span");
210         let uncool_span = tracing::info_span!("uncool_span");
211 
212         {
213             let _enter = cool_span.enter();
214             tracing::debug!("i'm a cool event");
215             tracing::trace!("i'm cool, but not cool enough");
216             let _enter2 = uncool_span.enter();
217             tracing::warn!("warning: extremely cool!");
218             tracing::debug!("i'm still cool");
219         }
220 
221         let _enter = uncool_span.enter();
222         tracing::warn!("warning: not that cool");
223         tracing::trace!("im not cool enough");
224         tracing::error!("uncool error");
225     });
226 
227     finished.assert_finished();
228 }
229 
230 #[test]
method_name_resolution()231 fn method_name_resolution() {
232     #[allow(unused_imports)]
233     use tracing_subscriber::layer::{Filter, Layer};
234 
235     let filter = EnvFilter::new("hello_world=info");
236     filter.max_level_hint();
237 }
238 
239 // contains the same tests as the first half of this file
240 // but using EnvFilter as a `Filter`, not as a `Layer`
241 mod per_layer_filter {
242     use super::*;
243 
244     #[test]
level_filter_event()245     fn level_filter_event() {
246         let filter: EnvFilter = "info".parse().expect("filter should parse");
247         let (layer, handle) = layer::mock()
248             .event(expect::event().at_level(Level::INFO))
249             .event(expect::event().at_level(Level::WARN))
250             .event(expect::event().at_level(Level::ERROR))
251             .only()
252             .run_with_handle();
253 
254         let _subscriber = tracing_subscriber::registry()
255             .with(layer.with_filter(filter))
256             .set_default();
257 
258         tracing::trace!("this should be disabled");
259         tracing::info!("this shouldn't be");
260         tracing::debug!(target: "foo", "this should also be disabled");
261         tracing::warn!(target: "foo", "this should be enabled");
262         tracing::error!("this should be enabled too");
263 
264         handle.assert_finished();
265     }
266 
267     #[test]
same_name_spans()268     fn same_name_spans() {
269         let filter: EnvFilter = "[foo{bar}]=trace,[foo{baz}]=trace"
270             .parse()
271             .expect("filter should parse");
272         let (layer, handle) = layer::mock()
273             .new_span(
274                 expect::span()
275                     .named("foo")
276                     .at_level(Level::TRACE)
277                     .with_fields(expect::field("bar")),
278             )
279             .new_span(
280                 expect::span()
281                     .named("foo")
282                     .at_level(Level::TRACE)
283                     .with_fields(expect::field("baz")),
284             )
285             .only()
286             .run_with_handle();
287 
288         let _subscriber = tracing_subscriber::registry()
289             .with(layer.with_filter(filter))
290             .set_default();
291 
292         tracing::trace_span!("foo", bar = 1);
293         tracing::trace_span!("foo", baz = 1);
294 
295         handle.assert_finished();
296     }
297 
298     #[test]
level_filter_event_with_target()299     fn level_filter_event_with_target() {
300         let filter: EnvFilter = "info,stuff=debug".parse().expect("filter should parse");
301         let (layer, handle) = layer::mock()
302             .event(expect::event().at_level(Level::INFO))
303             .event(expect::event().at_level(Level::DEBUG).with_target("stuff"))
304             .event(expect::event().at_level(Level::WARN).with_target("stuff"))
305             .event(expect::event().at_level(Level::ERROR))
306             .event(expect::event().at_level(Level::ERROR).with_target("stuff"))
307             .only()
308             .run_with_handle();
309 
310         let _subscriber = tracing_subscriber::registry()
311             .with(layer.with_filter(filter))
312             .set_default();
313 
314         tracing::trace!("this should be disabled");
315         tracing::info!("this shouldn't be");
316         tracing::debug!(target: "stuff", "this should be enabled");
317         tracing::debug!("but this shouldn't");
318         tracing::trace!(target: "stuff", "and neither should this");
319         tracing::warn!(target: "stuff", "this should be enabled");
320         tracing::error!("this should be enabled too");
321         tracing::error!(target: "stuff", "this should be enabled also");
322 
323         handle.assert_finished();
324     }
325 
326     #[test]
level_filter_event_with_target_and_span()327     fn level_filter_event_with_target_and_span() {
328         let filter: EnvFilter = "stuff[cool_span]=debug"
329             .parse()
330             .expect("filter should parse");
331 
332         let cool_span = expect::span().named("cool_span");
333         let (layer, handle) = layer::mock()
334             .enter(cool_span.clone())
335             .event(
336                 expect::event()
337                     .at_level(Level::DEBUG)
338                     .in_scope(vec![cool_span.clone()]),
339             )
340             .exit(cool_span)
341             .only()
342             .run_with_handle();
343 
344         let _subscriber = tracing_subscriber::registry()
345             .with(layer.with_filter(filter))
346             .set_default();
347 
348         {
349             let _span = tracing::info_span!(target: "stuff", "cool_span").entered();
350             tracing::debug!("this should be enabled");
351         }
352 
353         tracing::debug!("should also be disabled");
354 
355         {
356             let _span = tracing::info_span!("uncool_span").entered();
357             tracing::debug!("this should be disabled");
358         }
359 
360         handle.assert_finished();
361     }
362 
363     #[test]
not_order_dependent()364     fn not_order_dependent() {
365         // this test reproduces tokio-rs/tracing#623
366 
367         let filter: EnvFilter = "stuff=debug,info".parse().expect("filter should parse");
368         let (layer, finished) = layer::mock()
369             .event(expect::event().at_level(Level::INFO))
370             .event(expect::event().at_level(Level::DEBUG).with_target("stuff"))
371             .event(expect::event().at_level(Level::WARN).with_target("stuff"))
372             .event(expect::event().at_level(Level::ERROR))
373             .event(expect::event().at_level(Level::ERROR).with_target("stuff"))
374             .only()
375             .run_with_handle();
376 
377         let _subscriber = tracing_subscriber::registry()
378             .with(layer.with_filter(filter))
379             .set_default();
380 
381         tracing::trace!("this should be disabled");
382         tracing::info!("this shouldn't be");
383         tracing::debug!(target: "stuff", "this should be enabled");
384         tracing::debug!("but this shouldn't");
385         tracing::trace!(target: "stuff", "and neither should this");
386         tracing::warn!(target: "stuff", "this should be enabled");
387         tracing::error!("this should be enabled too");
388         tracing::error!(target: "stuff", "this should be enabled also");
389 
390         finished.assert_finished();
391     }
392 
393     #[test]
add_directive_enables_event()394     fn add_directive_enables_event() {
395         // this test reproduces tokio-rs/tracing#591
396 
397         // by default, use info level
398         let mut filter = EnvFilter::new(LevelFilter::INFO.to_string());
399 
400         // overwrite with a more specific directive
401         filter = filter.add_directive("hello=trace".parse().expect("directive should parse"));
402 
403         let (layer, finished) = layer::mock()
404             .event(expect::event().at_level(Level::INFO).with_target("hello"))
405             .event(expect::event().at_level(Level::TRACE).with_target("hello"))
406             .only()
407             .run_with_handle();
408 
409         let _subscriber = tracing_subscriber::registry()
410             .with(layer.with_filter(filter))
411             .set_default();
412 
413         tracing::info!(target: "hello", "hello info");
414         tracing::trace!(target: "hello", "hello trace");
415 
416         finished.assert_finished();
417     }
418 
419     #[test]
span_name_filter_is_dynamic()420     fn span_name_filter_is_dynamic() {
421         let filter: EnvFilter = "info,[cool_span]=debug"
422             .parse()
423             .expect("filter should parse");
424         let cool_span = expect::span().named("cool_span");
425         let uncool_span = expect::span().named("uncool_span");
426         let (layer, finished) = layer::mock()
427             .event(expect::event().at_level(Level::INFO))
428             .enter(cool_span.clone())
429             .event(
430                 expect::event()
431                     .at_level(Level::DEBUG)
432                     .in_scope(vec![cool_span.clone()]),
433             )
434             .enter(uncool_span.clone())
435             .event(
436                 expect::event()
437                     .at_level(Level::WARN)
438                     .in_scope(vec![uncool_span.clone()]),
439             )
440             .event(
441                 expect::event()
442                     .at_level(Level::DEBUG)
443                     .in_scope(vec![uncool_span.clone()]),
444             )
445             .exit(uncool_span.clone())
446             .exit(cool_span)
447             .enter(uncool_span.clone())
448             .event(
449                 expect::event()
450                     .at_level(Level::WARN)
451                     .in_scope(vec![uncool_span.clone()]),
452             )
453             .event(
454                 expect::event()
455                     .at_level(Level::ERROR)
456                     .in_scope(vec![uncool_span.clone()]),
457             )
458             .exit(uncool_span)
459             .only()
460             .run_with_handle();
461 
462         let _subscriber = tracing_subscriber::registry()
463             .with(layer.with_filter(filter))
464             .set_default();
465 
466         tracing::trace!("this should be disabled");
467         tracing::info!("this shouldn't be");
468         let cool_span = tracing::info_span!("cool_span");
469         let uncool_span = tracing::info_span!("uncool_span");
470 
471         {
472             let _enter = cool_span.enter();
473             tracing::debug!("i'm a cool event");
474             tracing::trace!("i'm cool, but not cool enough");
475             let _enter2 = uncool_span.enter();
476             tracing::warn!("warning: extremely cool!");
477             tracing::debug!("i'm still cool");
478         }
479 
480         {
481             let _enter = uncool_span.enter();
482             tracing::warn!("warning: not that cool");
483             tracing::trace!("im not cool enough");
484             tracing::error!("uncool error");
485         }
486 
487         finished.assert_finished();
488     }
489 
490     #[test]
multiple_dynamic_filters()491     fn multiple_dynamic_filters() {
492         // Test that multiple dynamic (span) filters only apply to the layers
493         // they're attached to.
494         let (layer1, handle1) = {
495             let span = expect::span().named("span1");
496             let filter: EnvFilter = "[span1]=debug".parse().expect("filter 1 should parse");
497             let (layer, handle) = layer::named("layer1")
498                 .enter(span.clone())
499                 .event(
500                     expect::event()
501                         .at_level(Level::DEBUG)
502                         .in_scope(vec![span.clone()]),
503                 )
504                 .exit(span)
505                 .only()
506                 .run_with_handle();
507             (layer.with_filter(filter), handle)
508         };
509 
510         let (layer2, handle2) = {
511             let span = expect::span().named("span2");
512             let filter: EnvFilter = "[span2]=info".parse().expect("filter 2 should parse");
513             let (layer, handle) = layer::named("layer2")
514                 .enter(span.clone())
515                 .event(
516                     expect::event()
517                         .at_level(Level::INFO)
518                         .in_scope(vec![span.clone()]),
519                 )
520                 .exit(span)
521                 .only()
522                 .run_with_handle();
523             (layer.with_filter(filter), handle)
524         };
525 
526         let _subscriber = tracing_subscriber::registry()
527             .with(layer1)
528             .with(layer2)
529             .set_default();
530 
531         tracing::info_span!("span1").in_scope(|| {
532             tracing::debug!("hello from span 1");
533             tracing::trace!("not enabled");
534         });
535 
536         tracing::info_span!("span2").in_scope(|| {
537             tracing::info!("hello from span 2");
538             tracing::debug!("not enabled");
539         });
540 
541         handle1.assert_finished();
542         handle2.assert_finished();
543     }
544 }
545