1 ///! Parsers for rfc 5424 specific formats.
2 use crate::{
3     message::{Protocol, Message},
4     parsers::{appname, digits, hostname, msgid, procid},
5     pri::pri,
6     timestamp::timestamp_3339,
7     structured_data::structured_data,
8 };
9 use nom::{
10     character::complete::{space0, space1},
11     combinator::{rest, map},
12     sequence::tuple,
13     IResult,
14 };
15 
16 /// Parse the version number - just a simple integer.
version(input: &str) -> IResult<&str, u32>17 fn version(input: &str) -> IResult<&str, u32> {
18     digits(input)
19 }
20 
21 /// Parse the message as per RFC5424
parse(input: &str) -> IResult<&str, Message<&str>>22 pub(crate) fn parse(input: &str) -> IResult<&str, Message<&str>> {
23     map(
24         tuple((
25             pri, version, space1, timestamp_3339, space1, hostname, space1, appname, space1, procid,
26             space1, msgid, space0, structured_data, space0, rest,
27         )),
28         |(pri, version, _, timestamp, _, hostname, _, appname, _, procid, _, msgid, _, structured_data, _, msg)| Message {
29             protocol: Protocol::RFC5424(version),
30             facility: pri.0,
31             severity: pri.1,
32             timestamp: Some(timestamp),
33             hostname,
34             appname,
35             procid: procid.map(|p| p.into()),
36             msgid,
37             structured_data,
38             msg
39         },
40     )(input)
41 }
42 
43 #[cfg(test)]
44 mod tests {
45     use super::*;
46     use crate::pri::{SyslogFacility, SyslogSeverity};
47     use chrono::prelude::*;
48 
49     #[test]
parse_5424()50     fn parse_5424() {
51         assert_eq!(
52             parse("<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - message").unwrap(),
53             (
54                 "",
55                 Message {
56                     protocol: Protocol::RFC5424(1),
57                     facility: Some(SyslogFacility::LOG_AUTH),
58                     severity: Some(SyslogSeverity::SEV_CRIT),
59                     timestamp: Some(
60                         FixedOffset::west(0)
61                             .ymd(2003, 10, 11)
62                             .and_hms_milli(22, 14, 15, 3)
63                     ),
64                     hostname: Some("mymachine.example.com"),
65                     appname: Some("su"),
66                     procid: None,
67                     msgid: Some("ID47"),
68                     structured_data: vec![],
69                     msg: "message",
70                 }
71             )
72         )
73     }
74 }
75