Compare commits
No commits in common. "42c318a1b84710df7dc6a7cfcd7878c08d2d966e" and "bcacc8b6644b8b84c3f91bb70f1896d68ffde4a8" have entirely different histories.
42c318a1b8
...
bcacc8b664
1 changed files with 57 additions and 68 deletions
115
src/main.rs
115
src/main.rs
|
@ -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,
|
|
||||||
service,
|
|
||||||
entry,
|
|
||||||
} = parse_line(&line)?;
|
|
||||||
if !blacklist.contains(service) {
|
if !blacklist.contains(service) {
|
||||||
db.execute(
|
db.execute(
|
||||||
&insert_statement,
|
&insert_statement,
|
||||||
&[&prio, &ip, &rcvtime, &logtime, &service, &entry],
|
&[&prio, &ip, &now, &date, &service, &log],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue