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 = Self {
41 req_id,
42 max_level: AtomicUsize::new(Level::Trace as usize),
43 req_str: [0u8; 16],
44 };
45 write!(&mut s.req_str[..], "{:016x}", req_id).expect("to hex");
46 s
47 }
48
49 #[inline]
51 pub fn set_level(&self, level: Level) {
52 self.max_level.store(level as usize, Ordering::Relaxed);
53 }
54
55 #[inline]
56 pub fn get_level(&self) -> usize {
57 self.max_level.load(Ordering::Relaxed)
58 }
59
60 #[doc(hidden)]
61 #[inline(always)]
62 pub fn _private_api_log(
63 &self,
64 args: fmt::Arguments,
65 level: Level,
66 &(target, module_path, file, line): &(&str, &str, &str, u32),
67 ) {
68 let record = RecordBuilder::new()
69 .level(level)
70 .target(target)
71 .module_path(Some(module_path))
72 .file(Some(file))
73 .line(Some(line))
74 .key_values(&self)
75 .args(args)
76 .build();
77 logger().log(&record);
78 }
79}
80
81impl log::kv::Source for LogFilter {
82 #[inline(always)]
83 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
84 visitor.visit_pair("req_id".to_key(), unsafe {
85 str::from_utf8_unchecked(&self.req_str).into()
86 })
87 }
88
89 #[inline(always)]
90 fn get<'a>(&'a self, key: Key) -> Option<Value<'a>> {
91 if self.req_id != 0 && key.as_ref() == "req_id" {
92 return Some(unsafe { str::from_utf8_unchecked(&self.req_str).into() });
93 }
94 return None;
95 }
96
97 #[inline(always)]
98 fn count(&self) -> usize {
99 1
100 }
101}