json_log.rs

 1use std::borrow::Cow;
 2
 3use log::{Level, Log, Record};
 4use serde::{Deserialize, Serialize};
 5
 6#[derive(Deserialize, Debug, Serialize)]
 7pub struct LogRecord<'a> {
 8    pub level: usize,
 9    pub module_path: Option<Cow<'a, str>>,
10    pub file: Option<Cow<'a, str>>,
11    pub line: Option<u32>,
12    pub message: Cow<'a, str>,
13}
14
15impl<'a> LogRecord<'a> {
16    pub fn new(record: &'a Record<'a>) -> Self {
17        Self {
18            level: serialize_level(record.level()),
19            module_path: record.module_path().map(Cow::Borrowed),
20            file: record.file().map(Cow::Borrowed),
21            line: record.line(),
22            message: Cow::Owned(record.args().to_string()),
23        }
24    }
25
26    pub fn log(&'a self, logger: &dyn Log) {
27        if let Some(level) = deserialize_level(self.level) {
28            logger.log(
29                &log::Record::builder()
30                    .module_path(self.module_path.as_deref())
31                    .target("remote_server")
32                    .args(format_args!("{}", self.message))
33                    .file(self.file.as_deref())
34                    .line(self.line)
35                    .level(level)
36                    .build(),
37            )
38        }
39    }
40}
41
42fn serialize_level(level: Level) -> usize {
43    match level {
44        Level::Error => 1,
45        Level::Warn => 2,
46        Level::Info => 3,
47        Level::Debug => 4,
48        Level::Trace => 5,
49    }
50}
51
52fn deserialize_level(level: usize) -> Option<Level> {
53    match level {
54        1 => Some(Level::Error),
55        2 => Some(Level::Warn),
56        3 => Some(Level::Info),
57        4 => Some(Level::Debug),
58        5 => Some(Level::Trace),
59        _ => None,
60    }
61}