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