Accept mulitple input files
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use crate::models::{LogEntry, SMTPSession};
|
||||
use chrono::{Datelike, NaiveDateTime};
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, path::Path, time::SystemTime};
|
||||
use anyhow::Context;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref LOG_LINE_RE: Regex = Regex::new(
|
||||
@@ -9,8 +10,22 @@ lazy_static::lazy_static! {
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
fn get_log_year(file_path: Option<&str>) -> Option<i32> {
|
||||
file_path.and_then(|path| {
|
||||
let metadata = std::fs::metadata(path).ok()?;
|
||||
let modified = metadata.modified().ok()?;
|
||||
let datetime: chrono::DateTime<chrono::Local> = modified.into();
|
||||
Some(datetime.year())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn parse_log_file(contents: &str) -> anyhow::Result<Vec<SMTPSession>> {
|
||||
parse_log_file_with_path(contents, None)
|
||||
}
|
||||
|
||||
pub fn parse_log_file_with_path(contents: &str, file_path: Option<&str>) -> anyhow::Result<Vec<SMTPSession>> {
|
||||
let mut sessions: HashMap<String, SMTPSession> = HashMap::new();
|
||||
let log_year = get_log_year(file_path).unwrap_or_else(|| chrono::Local::now().year());
|
||||
|
||||
for line in contents.lines() {
|
||||
if let Some(captures) = LOG_LINE_RE.captures(line) {
|
||||
@@ -22,13 +37,19 @@ pub fn parse_log_file(contents: &str) -> anyhow::Result<Vec<SMTPSession>> {
|
||||
let message = captures["message"].to_string();
|
||||
|
||||
// Create a timestamp string in the format that chrono can parse
|
||||
let year = chrono::Local::now().year();
|
||||
let timestamp_str = format!("{} {} {} {}", year, month, day, time);
|
||||
let timestamp = match NaiveDateTime::parse_from_str(×tamp_str, "%Y %b %d %H:%M:%S") {
|
||||
let timestamp_str = format!("{} {} {} {}", log_year, month, day, time);
|
||||
let mut timestamp = match NaiveDateTime::parse_from_str(×tamp_str, "%Y %b %d %H:%M:%S") {
|
||||
Ok(ts) => ts,
|
||||
Err(_) => continue, // Skip lines with invalid timestamps
|
||||
};
|
||||
|
||||
// Handle year rollover (if log entry is from next year but file is from previous year)
|
||||
if timestamp.month() == 1 && log_year != chrono::Local::now().year() {
|
||||
if let Some(prev_year_timestamp) = timestamp.with_year(log_year + 1) {
|
||||
timestamp = prev_year_timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
let entry = LogEntry {
|
||||
timestamp,
|
||||
hostname,
|
||||
|
||||
Reference in New Issue
Block a user