log4rs_syslog_net/
rfc5425.rs1use crate::consts::{level_to_severity, Facility, NILVALUE};
2use chrono::SecondsFormat;
3use log::Record;
4use log4rs::encode::writer::simple::SimpleWriter;
5use log4rs::encode::Encode;
6use std::error::Error;
7use std::sync::Arc;
8
9#[derive(Clone, Debug)]
10pub struct Format {
11 facility: Facility,
12 hostname: String,
13 app_name: String,
14 proc_id: String,
15 encoder: Arc<dyn log4rs::encode::Encode>,
16}
17
18impl Default for Format {
19 fn default() -> Self {
20 Format::new()
21 }
22}
23
24impl Format {
25 pub fn new() -> Self {
26 Format {
27 facility: Facility::LOCAL0,
28 hostname: "".to_string(),
29 app_name: "".to_string(),
30 proc_id: format!("{}", std::process::id()),
31 encoder: Arc::new(log4rs::encode::pattern::PatternEncoder::default()),
32 }
33 }
34
35 pub fn encoder<E: Encode>(mut self, encoder: E) -> Self {
36 self.encoder = Arc::new(encoder) as Arc<dyn Encode + 'static>;
37 self
38 }
39
40 pub fn facility(mut self, facility: Facility) -> Self {
41 self.facility = facility;
42 self
43 }
44
45 pub fn hostname<S: Into<String>>(mut self, hostname: S) -> Self {
46 self.hostname = hostname.into();
47 self
48 }
49
50 pub fn app_name<S: Into<String>>(mut self, app_name: S) -> Self {
51 self.app_name = app_name.into();
52 self
53 }
54
55 pub fn proc_id<S: Into<String>>(mut self, proc_id: S) -> Self {
56 self.proc_id = proc_id.into();
57 self
58 }
59}
60
61impl log4rs::encode::Encode for Format {
62 fn encode(
63 &self,
64 w: &mut dyn log4rs::encode::Write,
65 record: &Record<'_>,
66 ) -> Result<(), Box<dyn Error + Sync + Send>> {
67 let priority = self.facility as u8 | level_to_severity(record.level());
68 let msg_id = 0;
69 let struct_data = NILVALUE;
70
71 let mut buf: Vec<u8> = Vec::new();
72 self.encoder.encode(&mut SimpleWriter(&mut buf), record)?;
73 let msg = std::str::from_utf8(&buf).unwrap();
74
75 let msg = format!(
76 "<{}>{} {} {} {} {} {} {} {}\n",
77 priority,
78 1,
79 chrono::Utc::now().to_rfc3339_opts(SecondsFormat::Millis, false),
80 self.hostname,
81 self.app_name,
82 self.proc_id,
83 msg_id,
84 struct_data,
85 msg
86 );
87
88 let rfc_5425 = format!("{} {}", msg.as_bytes().len(), msg);
89
90 w.write_all(rfc_5425.as_bytes())?;
91 Ok(())
92 }
93}