syslog_rs/formatters/
syslog_5424.rs1use std::borrow::Cow;
23
24use chrono::{Local, SecondsFormat};
25
26use crate::{socket::TapType, truncate, truncate_n, Priority, NILVALUE, WSPACE};
27
28use super::{SyslogFormatted, SyslogFormatter};
29
30
31
32#[derive(Debug, Clone)]
33pub struct FormatRfc5424;
34
35impl FormatRfc5424
36{
37 #[inline]
38 pub(crate)
39 fn get_max_msg_length(tap_type: TapType) -> usize
40 {
41 use crate::common;
42
43 match tap_type
44 {
45 TapType::UnPriv | TapType::Priv | TapType::OldLog | TapType::CustomLog =>
46 {
47 if *common::RFC5424_MAX_DGRAM >= common::MAXLINE
48 {
49 return common::MAXLINE;
50 }
51 else
52 {
53 return *common::RFC5424_MAX_DGRAM;
54 };
55 },
56 TapType::NetTcp | TapType::NetTls =>
57 return common::RFC5424_TCP_MAX_PKT_LEN,
58 TapType::NetUdp =>
59 return common::RFC5424_UDP_MAX_PKT_LEN,
60 TapType::LocalFile =>
61 return common::MAXLINE,
62 TapType::None =>
63 return common::MAXLINE,
64 }
65 }
66}
67
68unsafe impl Send for FormatRfc5424 {}
69
70impl SyslogFormatter for FormatRfc5424
71{
72 fn vsyslog1_format<'f>(tap_type: TapType, pri: Priority, progname: &'f str, pid: &'f str, fmt: &'f str) -> SyslogFormatted<'f>
73 {
74 let timedate =
76 Local::now().to_rfc3339_opts(SecondsFormat::Secs, false);
77
78 let hostname: String =
79 nix::unistd::gethostname()
80 .map_or(NILVALUE.into(), |r| r.to_str().map_or(NILVALUE, |v| v).to_string());
81
82 let msg_pri =
84 [
85 "<", pri.bits().to_string().as_str(), ">1"
86 ]
87 .concat();
88
89 let mut msg_pkt =
91 [
92 Cow::Owned(msg_pri),
94 Cow::Borrowed(WSPACE), Cow::Owned(timedate),
96 Cow::Borrowed(WSPACE), Cow::Owned(hostname),
98 Cow::Borrowed(WSPACE), Cow::Borrowed(progname),
100 Cow::Borrowed(WSPACE), Cow::Borrowed(pid),
102 Cow::Borrowed(WSPACE), Cow::Borrowed(NILVALUE),
104 Cow::Borrowed(WSPACE), Cow::Borrowed(NILVALUE),
106 Cow::Borrowed(WSPACE), Cow::Borrowed(WSPACE), ]
110 .to_vec();
111
112 let msg_len = msg_pkt[..msg_pkt.len()-1].iter().map(|v| v.as_bytes().len()).sum::<usize>();
113
114 let msg_space_left = Self::get_max_msg_length(tap_type) - msg_len;
116
117 let msg_payload = truncate_n(fmt, msg_space_left);
118
119 let msg_payload_final =
120 if msg_payload.ends_with("\n") == true
121 {
122 truncate(msg_payload)
123 }
124 else
125 {
126 msg_payload
127 };
128
129 msg_pkt[14] = Cow::Borrowed(msg_payload_final);
131
132 let msg_rng = msg_pkt.len();
133
134 return SyslogFormatted{ msg: msg_pkt, stderr_range: 1..msg_rng };
135 }
136}
137