rsigma_runtime/input/
mod.rs1use std::borrow::Cow;
11
12use rsigma_eval::{Event, EventValue, JsonEvent, KvEvent, PlainEvent};
13use serde_json::Value;
14
15mod auto;
16#[cfg(feature = "cef")]
17mod cef;
18#[cfg(feature = "evtx")]
19pub mod evtx;
20mod json;
21#[cfg(feature = "logfmt")]
22mod logfmt;
23mod plain;
24mod syslog;
25
26#[cfg(feature = "cef")]
27pub use self::cef::parse_cef;
28pub use self::json::parse_json;
29#[cfg(feature = "logfmt")]
30pub use self::logfmt::parse_logfmt;
31pub use self::syslog::{SyslogConfig, parse_syslog};
32pub use auto::auto_detect;
33pub use plain::parse_plain;
34
35#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum InputFormat {
38 Auto(SyslogConfig),
41 Json,
43 Syslog(SyslogConfig),
45 Plain,
47 #[cfg(feature = "logfmt")]
49 Logfmt,
50 #[cfg(feature = "cef")]
52 Cef,
53}
54
55impl Default for InputFormat {
56 fn default() -> Self {
57 InputFormat::Auto(SyslogConfig::default())
58 }
59}
60
61#[derive(Debug)]
66pub enum EventInputDecoded {
67 Json(JsonEvent<'static>),
68 Kv(KvEvent),
69 Plain(PlainEvent),
70}
71
72impl Event for EventInputDecoded {
73 fn get_field(&self, path: &str) -> Option<EventValue<'_>> {
74 match self {
75 EventInputDecoded::Json(e) => e.get_field(path),
76 EventInputDecoded::Kv(e) => e.get_field(path),
77 EventInputDecoded::Plain(e) => e.get_field(path),
78 }
79 }
80
81 fn any_string_value(&self, pred: &dyn Fn(&str) -> bool) -> bool {
82 match self {
83 EventInputDecoded::Json(e) => e.any_string_value(pred),
84 EventInputDecoded::Kv(e) => e.any_string_value(pred),
85 EventInputDecoded::Plain(e) => e.any_string_value(pred),
86 }
87 }
88
89 fn all_string_values(&self) -> Vec<Cow<'_, str>> {
90 match self {
91 EventInputDecoded::Json(e) => e.all_string_values(),
92 EventInputDecoded::Kv(e) => e.all_string_values(),
93 EventInputDecoded::Plain(e) => e.all_string_values(),
94 }
95 }
96
97 fn to_json(&self) -> Value {
98 match self {
99 EventInputDecoded::Json(e) => e.to_json(),
100 EventInputDecoded::Kv(e) => e.to_json(),
101 EventInputDecoded::Plain(e) => e.to_json(),
102 }
103 }
104}
105
106pub fn parse_line(line: &str, format: &InputFormat) -> Option<EventInputDecoded> {
116 if line.trim().is_empty() {
117 return None;
118 }
119 Some(match format {
120 InputFormat::Auto(syslog_config) => auto_detect(line, syslog_config),
121 InputFormat::Json => parse_json(line)?,
122 InputFormat::Syslog(config) => parse_syslog(line, config),
123 InputFormat::Plain => parse_plain(line),
124 #[cfg(feature = "logfmt")]
125 InputFormat::Logfmt => parse_logfmt(line),
126 #[cfg(feature = "cef")]
127 InputFormat::Cef => parse_cef(line)?,
128 })
129}