syslog_rs/formatters/
syslog_3146.rs1use std::borrow::Cow;
17
18use chrono::Local;
19
20use crate::{CBRACE_SEM, OBRACE, Priority, RFC3164_MAX_PAYLOAD_LEN, SyslogMsgPriFac, WSPACE, truncate, truncate_n};
21
22use super::{SyslogFormatted, SyslogFormatter};
23
24
25
26#[derive(Debug, Clone)]
27#[repr(transparent)]
28pub struct FormatRfc3146(Cow<'static, str>);
29
30unsafe impl Send for FormatRfc3146 {}
31
32impl From<String> for FormatRfc3146
33{
34 fn from(value: String) -> FormatRfc3146
35 {
36 return Self(Cow::Owned(value));
37 }
38}
39
40impl From<&'static str> for FormatRfc3146
41{
42 fn from(value: &'static str) -> FormatRfc3146
43 {
44 return FormatRfc3146(Cow::Borrowed(value));
45 }
46}
47
48
49
50impl SyslogFormatter for FormatRfc3146
51{
52 fn vsyslog1_format(&self, _max_msg_size: usize, prifac: SyslogMsgPriFac, progname: &str, pid: Option<&str>) -> SyslogFormatted
53 {
54 let timedate = Local::now().format("%h %e %T").to_string();
56
57 let msg_payload = truncate_n(&self.0, RFC3164_MAX_PAYLOAD_LEN);
58
59 let msg_payload_final =
60 if msg_payload.ends_with("\n") == true
61 {
62 truncate(&msg_payload)
63 }
64 else
65 {
66 &msg_payload
67 };
68
69 let msg_pri =
71 [
72 "<", prifac.get_val().to_string().as_str(), ">"
73 ]
74 .concat();
75
76 let msg_pid =
77 if let Some(p) = pid
78 {
79 [OBRACE, p, CBRACE_SEM].concat()
80 }
81 else
82 {
83 [""].concat()
84 };
85
86 let msg_pkt =
87 [
88 timedate.as_str(),
92 WSPACE, progname,
96 msg_pid.as_str(),
98 WSPACE, msg_payload_final
100 ]
101 .concat();
102
103
104 return
105 SyslogFormatted
106 {
107 msg_header: Some(msg_pri),
108 msg_payload: msg_pkt,
109 full_msg: None
110 };
111 }
112}
113
114#[cfg(test)]
115mod test_rfc3146
116{
117 use crate::LogFacility;
118
119 use super::*;
120
121 #[test]
122 fn test_1()
123 {
124 let msg = FormatRfc3146::from("test string!");
125 let prifac = SyslogMsgPriFac::set_facility(Priority::LOG_ERR, LogFacility::LOG_DAEMON);
126 let mut res = msg.vsyslog1_format(1024, prifac, "testprog", Some("102"));
127
128 assert_eq!(res.msg_header.as_ref().map(|f| f.as_str()), Some("<27>"));
129
130 let fullmsg = res.get_full_msg();
131
132 println!("{}", fullmsg);
133
134 assert_eq!(fullmsg.find("testprog"), Some(20));
135
136 assert_eq!(fullmsg.find("[102]"), Some(28));
137
138 assert_eq!(fullmsg.find("]:"), Some(32));
139
140 assert_eq!(fullmsg.find("test string!"), Some(35));
141 }
142}