pub mod json;
pub mod logfmt;
pub mod nginx;
use serde_json::Value;
#[derive(Debug)]
pub enum LogEntry {
Structured(Value), Unstructured(String), }
pub fn parse_log_line(line: &str) -> LogEntry {
let trimmed = line.trim();
if trimmed.starts_with('{') && trimmed.ends_with('}') {
if let Ok(json_val) = json::parse_json_line(trimmed) {
return LogEntry::Structured(json_val);
}
}
if (trimmed.starts_with(|c: char| c.is_ascii_digit()) || trimmed.starts_with(":"))
&& trimmed.contains(" - - [") {
if let Some(nginx_val) = nginx::parse_nginx_line(trimmed) {
return LogEntry::Structured(nginx_val);
}
}
if trimmed.contains('=') {
if let Ok(logfmt_val) = logfmt::parse_logfmt_line(trimmed) {
if let Some(map) = logfmt_val.as_object() {
if !map.is_empty() {
let total_keys = map.len();
let null_value_keys = map.values().filter(|v| v.is_null()).count();
if null_value_keys < total_keys / 2 {
return LogEntry::Structured(logfmt_val);
}
}
}
}
}
LogEntry::Unstructured(line.to_string())
}