#[cfg(test)]
#[path = "factory_tests.rs"]
mod factory_tests;
use crate::parser::group::ParserGroup;
use crate::parser::regex_parser::RegexParser;
use crate::traits::{LoaderInfo, LoaderType};
pub struct ParserFactory;
impl ParserFactory {
pub fn create_parser_group(info: &LoaderInfo) -> ParserGroup {
let mut group = ParserGroup::new(format!("auto:{}", info.id));
match info.loader_type {
LoaderType::Syslog => {
Self::add_syslog_parsers(&mut group);
}
LoaderType::Otlp => {
}
LoaderType::TextFile | LoaderType::Archive => {
if Self::looks_like_syslog(&info.sample_lines) {
Self::add_syslog_parsers(&mut group);
}
Self::add_common_parsers(&mut group);
}
}
Self::add_fallback_parser(&mut group);
group
}
fn looks_like_syslog(sample_lines: &[String]) -> bool {
let syslog_re = regex::Regex::new(
r"^(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}",
)
.unwrap();
sample_lines.iter().take(5).any(|l| syslog_re.is_match(l))
}
fn add_syslog_parsers(group: &mut ParserGroup) {
if let Ok(p) = RegexParser::new(
"syslog-bsd",
r"^(?P<timestamp>\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})\s+(?P<hostname>\S+)\s+(?P<process>\S+?)(?:\[(?P<pid>\d+)\])?:\s+(?P<message>.*)",
Some("%b %d %H:%M:%S".to_string()),
) {
group.add_parser(Box::new(p));
}
}
fn add_common_parsers(group: &mut ParserGroup) {
if let Ok(p) = RegexParser::new(
"iso-level-msg",
r"^(?P<timestamp>\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\s+(?P<level>TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|CRITICAL)\s+(?P<message>.*)",
None,
) {
group.add_parser(Box::new(p));
}
if let Ok(p) = RegexParser::new(
"iso-bracket-level-msg",
r"^(?P<timestamp>\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\s+\[(?P<level>\w+)\]\s+(?P<message>.*)",
None,
) {
group.add_parser(Box::new(p));
}
if let Ok(p) = RegexParser::new(
"level-iso-msg",
r"^(?P<level>TRACE|DEBUG|INFO|WARN(?:ING)?|ERROR|FATAL|CRITICAL)\s+(?P<timestamp>\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)\s+(?P<message>.*)",
None,
) {
group.add_parser(Box::new(p));
}
}
fn add_fallback_parser(group: &mut ParserGroup) {
if let Ok(p) = RegexParser::new("fallback", r"(?P<message>.+)", None) {
group.add_parser(Box::new(p));
}
}
}