captains_log/
log_filter.rs1use std::{
2 fmt,
3 io::Write,
4 str,
5 sync::atomic::{AtomicUsize, Ordering},
6};
7
8use log::{kv::*, *};
9
10pub struct LogFilter {
23 req_id: u64,
24 req_str: [u8; 16],
25 max_level: AtomicUsize,
26}
27
28impl Clone for LogFilter {
29 fn clone(&self) -> Self {
30 Self {
31 req_id: self.req_id,
32 req_str: self.req_str.clone(),
33 max_level: AtomicUsize::new(self.get_level()),
34 }
35 }
36}
37
38impl LogFilter {
39 pub fn new(req_id: u64) -> Self {
40 let mut s =
41 Self { req_id, max_level: AtomicUsize::new(Level::Trace as usize), req_str: [0u8; 16] };
42 write!(&mut s.req_str[..], "{:016x}", req_id).expect("to hex");
43 s
44 }
45
46 #[inline]
48 pub fn set_level(&self, level: Level) {
49 self.max_level.store(level as usize, Ordering::Relaxed);
50 }
51
52 #[inline]
53 pub fn get_level(&self) -> usize {
54 self.max_level.load(Ordering::Relaxed)
55 }
56
57 #[doc(hidden)]
58 #[inline(always)]
59 pub fn _private_api_log(
60 &self, args: fmt::Arguments, level: Level,
61 &(target, module_path, file, line): &(&str, &str, &str, u32),
62 ) {
63 let record = RecordBuilder::new()
64 .level(level)
65 .target(target)
66 .module_path(Some(module_path))
67 .file(Some(file))
68 .line(Some(line))
69 .key_values(&self)
70 .args(args)
71 .build();
72 logger().log(&record);
73 }
74}
75
76impl log::kv::Source for LogFilter {
77 #[inline(always)]
78 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
79 visitor.visit_pair("req_id".to_key(), unsafe {
80 str::from_utf8_unchecked(&self.req_str).into()
81 })
82 }
83
84 #[inline(always)]
85 fn get<'a>(&'a self, key: Key) -> Option<Value<'a>> {
86 if self.req_id != 0 && key.as_ref() == "req_id" {
87 return Some(unsafe { str::from_utf8_unchecked(&self.req_str).into() });
88 }
89 return None;
90 }
91
92 #[inline(always)]
93 fn count(&self) -> usize {
94 1
95 }
96}