Compare commits

..

No commits in common. "42c318a1b84710df7dc6a7cfcd7878c08d2d966e" and "bcacc8b6644b8b84c3f91bb70f1896d68ffde4a8" have entirely different histories.

View file

@ -1,14 +1,18 @@
use chrono::{DateTime, Local}; use std::str::FromStr;
use chrono::{Datelike, Month, NaiveDate, NaiveDateTime, NaiveTime, TimeZone};
use tokio_postgres::{Client, Config, NoTls, Statement};
use tokio::net::{TcpListener, TcpStream};
use std::net::SocketAddr;
use std::sync::Arc;
use structopt::StructOpt;
use std::collections::HashSet;
use futures_util::FutureExt; use futures_util::FutureExt;
use futures_util::StreamExt; use futures_util::StreamExt;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::Arc;
use structopt::StructOpt;
use tokio::net::{TcpListener, TcpStream};
use tokio_postgres::{Client, Config, NoTls, Statement};
type Error = Box<dyn std::error::Error>; type Error = Box<dyn std::error::Error>;
@ -88,6 +92,8 @@ async fn main() -> Result<(), Error> {
} }
} }
use chrono::{DateTime, FixedOffset, Local};
async fn handle_peer_and_error( async fn handle_peer_and_error(
stream: TcpStream, stream: TcpStream,
peer: SocketAddr, peer: SocketAddr,
@ -112,57 +118,44 @@ async fn handle_peer(
let ip = peer.ip(); let ip = peer.ip();
let mut lines = FramedRead::new(stream, LinesCodec::new()); let mut lines = FramedRead::new(stream, LinesCodec::new());
while let Some(line) = lines.next().await.transpose()? { loop {
let ParsedLine { match lines.next().await.transpose()? {
prio, Some(line) => {
rcvtime, let (prio, now, date, service, log) = parse_line(&line)?;
logtime, if !blacklist.contains(service) {
service, db.execute(
entry, &insert_statement,
} = parse_line(&line)?; &[&prio, &ip, &now, &date, &service, &log],
if !blacklist.contains(service) { )
db.execute( .await?;
&insert_statement, }
&[&prio, &ip, &rcvtime, &logtime, &service, &entry], }
) None => break,
.await?;
} }
} }
Ok(()) Ok(())
} }
struct ParsedLine<'a> { /** parses a line, returning
prio: i16, * ( prio
rcvtime: DateTime<Local>, * , time the log was recieved
logtime: DateTime<Local>, * , time the log was written according to logger
// maybe this would be more correct, but i don't want to redo the database rn * , name of the service that wrote the log
//logtime: NaiveDateTime, * , log entry
service: &'a str, * )
entry: &'a str, */
} fn parse_line(
#[test] line: &'_ str,
fn tst_timeparse() { ) -> Result<
let input = "Jul 8 01:20:30"; (
let year = 2022; i16,
let parsed = parse_log_date(year, input).unwrap(); DateTime<Local>,
assert_eq!( DateTime<FixedOffset>,
parsed, &'_ str,
NaiveDateTime::parse_from_str("2022-07-08 01:20:30", "%Y-%m-%d %H:%M:%S").unwrap() &'_ str,
) ),
} Error,
> {
fn parse_log_date(year: i32, input: &'_ str) -> Result<NaiveDateTime, Error> {
let mut parts = input.split(" ").map(|p| p.trim()).filter(|p| p.len() > 0);
let month = Month::from_str(parts.next().ok_or("no month")?)
.map_err(|e| format!("month parsing error: {:?}", e))?;
let day: u32 = parts.next().ok_or("no day")?.parse()?;
let date =
NaiveDate::from_ymd_opt(year, month.number_from_month(), day).ok_or("invalid day+moth")?;
let time = NaiveTime::parse_from_str(parts.next().ok_or("no time")?, "%H:%M:%S")?;
Ok(NaiveDateTime::new(date, time))
}
fn parse_line(line: &'_ str) -> Result<ParsedLine<'_>, Error> {
let mut prio_and_remainder = line.splitn(2, '>'); let mut prio_and_remainder = line.splitn(2, '>');
let prio = prio_and_remainder let prio = prio_and_remainder
.next() .next()
@ -177,11 +170,13 @@ fn parse_line(line: &'_ str) -> Result<ParsedLine<'_>, Error> {
.expect("splitn should always return a second part"); .expect("splitn should always return a second part");
let (date, line) = line.split_at(16); let (date, line) = line.split_at(16);
let rcvtime = chrono::Local::now(); // we need to prepend the current year and timezone, as that is not stated in the logfile
// we need to prepend the current year and add timezone, as that is not stated in the logfile let now = chrono::Local::now();
let logtime = parse_log_date(rcvtime.date_naive().year(), date) let mut base = format!("{}", now.format("%Y %z "));
.map_err(|e| format!("could not parse logtime {}{} {}", date, line, e))?; base.push_str(date);
let logtime = TimeZone::from_local_datetime(&Local, &logtime).unwrap();
let date = DateTime::parse_from_str(&base, "%Y %z %b %e %H:%M:%S ")
.map_err(|e| format!("could not parse {}{} {}", date, line, e))?;
let mut parts = line.splitn(2, ':'); let mut parts = line.splitn(2, ':');
@ -192,12 +187,6 @@ fn parse_line(line: &'_ str) -> Result<ParsedLine<'_>, Error> {
.ok_or("could not split pid from service")? .ok_or("could not split pid from service")?
.trim(); .trim();
let entry = parts.next().ok_or("could not parse logfile")?.trim(); let log = parts.next().ok_or("could not parse logfile")?.trim();
Ok(ParsedLine { Ok((prio, now, date, service, log))
prio,
rcvtime,
logtime,
service,
entry,
})
} }