| 1 | use std::sync::{Arc, Mutex}; |
| 2 | use tracing::subscriber::with_default; |
| 3 | use tracing_core::span::{Attributes, Record}; |
| 4 | use tracing_core::{span, Event, Level, LevelFilter, Metadata, Subscriber}; |
| 5 | use tracing_log::{LogTracer, NormalizeEvent}; |
| 6 | |
| 7 | struct State { |
| 8 | last_normalized_metadata: Mutex<(bool, Option<OwnedMetadata>)>, |
| 9 | } |
| 10 | |
| 11 | #[derive(PartialEq, Debug)] |
| 12 | struct OwnedMetadata { |
| 13 | name: String, |
| 14 | target: String, |
| 15 | level: Level, |
| 16 | module_path: Option<String>, |
| 17 | file: Option<String>, |
| 18 | line: Option<u32>, |
| 19 | } |
| 20 | |
| 21 | struct TestSubscriber(Arc<State>); |
| 22 | |
| 23 | impl Subscriber for TestSubscriber { |
| 24 | fn enabled(&self, meta: &Metadata<'_>) -> bool { |
| 25 | dbg!(meta); |
| 26 | true |
| 27 | } |
| 28 | |
| 29 | fn max_level_hint(&self) -> Option<LevelFilter> { |
| 30 | Some(LevelFilter::from_level(Level::INFO)) |
| 31 | } |
| 32 | |
| 33 | fn new_span(&self, _span: &Attributes<'_>) -> span::Id { |
| 34 | span::Id::from_u64(42) |
| 35 | } |
| 36 | |
| 37 | fn record(&self, _span: &span::Id, _values: &Record<'_>) {} |
| 38 | |
| 39 | fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {} |
| 40 | |
| 41 | fn event(&self, event: &Event<'_>) { |
| 42 | dbg!(event); |
| 43 | *self.0.last_normalized_metadata.lock().unwrap() = ( |
| 44 | event.is_log(), |
| 45 | event.normalized_metadata().map(|normalized| OwnedMetadata { |
| 46 | name: normalized.name().to_string(), |
| 47 | target: normalized.target().to_string(), |
| 48 | level: *normalized.level(), |
| 49 | module_path: normalized.module_path().map(String::from), |
| 50 | file: normalized.file().map(String::from), |
| 51 | line: normalized.line(), |
| 52 | }), |
| 53 | ) |
| 54 | } |
| 55 | |
| 56 | fn enter(&self, _span: &span::Id) {} |
| 57 | |
| 58 | fn exit(&self, _span: &span::Id) {} |
| 59 | } |
| 60 | |
| 61 | #[test] |
| 62 | fn normalized_metadata() { |
| 63 | LogTracer::init().unwrap(); |
| 64 | let me = Arc::new(State { |
| 65 | last_normalized_metadata: Mutex::new((false, None)), |
| 66 | }); |
| 67 | let state = me.clone(); |
| 68 | |
| 69 | with_default(TestSubscriber(me), || { |
| 70 | log::info!("expected info log" ); |
| 71 | log::debug!("unexpected debug log" ); |
| 72 | let log = log::Record::builder() |
| 73 | .args(format_args!("Error!" )) |
| 74 | .level(log::Level::Info) |
| 75 | .build(); |
| 76 | log::logger().log(&log); |
| 77 | last( |
| 78 | &state, |
| 79 | true, |
| 80 | Some(OwnedMetadata { |
| 81 | name: "log event" .to_string(), |
| 82 | target: "" .to_string(), |
| 83 | level: Level::INFO, |
| 84 | module_path: None, |
| 85 | file: None, |
| 86 | line: None, |
| 87 | }), |
| 88 | ); |
| 89 | |
| 90 | let log = log::Record::builder() |
| 91 | .args(format_args!("Error!" )) |
| 92 | .level(log::Level::Info) |
| 93 | .target("log_tracer_target" ) |
| 94 | .file(Some("server.rs" )) |
| 95 | .line(Some(144)) |
| 96 | .module_path(Some("log_tracer" )) |
| 97 | .build(); |
| 98 | log::logger().log(&log); |
| 99 | last( |
| 100 | &state, |
| 101 | true, |
| 102 | Some(OwnedMetadata { |
| 103 | name: "log event" .to_string(), |
| 104 | target: "log_tracer_target" .to_string(), |
| 105 | level: Level::INFO, |
| 106 | module_path: Some("log_tracer" .to_string()), |
| 107 | file: Some("server.rs" .to_string()), |
| 108 | line: Some(144), |
| 109 | }), |
| 110 | ); |
| 111 | |
| 112 | tracing::info!("test with a tracing info" ); |
| 113 | last(&state, false, None); |
| 114 | }) |
| 115 | } |
| 116 | |
| 117 | fn last(state: &State, should_be_log: bool, expected: Option<OwnedMetadata>) { |
| 118 | let lock = state.last_normalized_metadata.lock().unwrap(); |
| 119 | let (is_log, metadata) = &*lock; |
| 120 | dbg!(&metadata); |
| 121 | assert_eq!(dbg!(*is_log), should_be_log); |
| 122 | assert_eq!(metadata.as_ref(), expected.as_ref()); |
| 123 | } |
| 124 | |