From 4b57b7f93737fe1ebbfaa6ab20731b4220a8222d Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Sun, 10 Dec 2017 14:59:38 +0100 Subject: Add functionality to parse the requires targets into a HashMap for later use --- src/main.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index c784d7c..f0cac8f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ extern crate serde_derive; extern crate serde_json; extern crate simplelog; +use std::collections::HashMap; use std::process::exit; use std::fs::File; @@ -57,18 +58,26 @@ fn query(data: Json, config: State) -> Result let targets = data.0.targets; debug!("targets: {:?}", targets); let response : Vec = Vec::new(); - let target_collection : Vec<(LogItem, Vec)> = Vec::new(); - let mut target_hash : std::collections::HashMap<&String, (&LogItem, &Vec)> = std::collections::HashMap::new(); + let mut target_hash : HashMap<&String, (&LogItem, Vec)> = HashMap::new(); for li in config.items() { for t in targets.clone() { if li.aliases().contains(&t.target) { - if let Some(&(_, ref mut cnames)) = target_hash.get(&li.alias()) { - cnames.push(t.target.split('.').nth(1).ok_or(Error::from("no capture name found"))?.into()); + if target_hash.contains_key(&li.alias()) { + if let Some(&mut (litem, ref mut cnames)) = target_hash.get_mut(&li.alias()) { + cnames.push(t.target.split('.').nth(1).ok_or(Error::from("no capture name found"))?.into()); + } } else { target_hash.insert( li.alias(), - (&li, &vec![t.target.split('.').nth(1).ok_or(Error::from("no capture name found"))?.into()]) + (&li, vec![ + t.target + .split('.') + .nth(1) + .ok_or(Error::from("no capture name found"))? + .into() + ] + ) ); } } -- cgit v1.2.3 From 579e31c18c99149726d3f7908adb9a120b186425 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Sun, 10 Dec 2017 15:52:47 +0100 Subject: Change type of series to f64 --- src/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api.rs b/src/api.rs index 01feed5..d124174 100644 --- a/src/api.rs +++ b/src/api.rs @@ -38,7 +38,7 @@ pub enum TargetData { #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct Series { pub target: String, - pub datapoints: Vec<[u64; 2]>, + pub datapoints: Vec<[f64; 2]>, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -- cgit v1.2.3 From 16ddbde585f2220eadf55525e082942e7b013df2 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Sun, 10 Dec 2017 17:35:50 +0100 Subject: Impl /query --- src/main.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index f0cac8f..f8014cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,16 +16,15 @@ extern crate rocket_contrib; extern crate serde; #[macro_use] extern crate serde_derive; -#[macro_use] extern crate serde_json; extern crate simplelog; use std::collections::HashMap; -use std::process::exit; use std::fs::File; +use std::io::{BufReader, BufRead}; +use std::process::exit; use clap::{App, Arg}; -use chrono::prelude::*; use rocket::State; use rocket_contrib::Json; use simplelog::{SimpleLogger, LogLevelFilter, Config as LogConfig}; @@ -57,25 +56,32 @@ fn query(data: Json, config: State) -> Result debug!("handling query: {:?}", data.0); let targets = data.0.targets; debug!("targets: {:?}", targets); - let response : Vec = Vec::new(); - let mut target_hash : HashMap<&String, (&LogItem, Vec)> = HashMap::new(); + let mut target_hash : HashMap<&String, (&LogItem, Vec<(String, String)>)> = HashMap::new(); for li in config.items() { for t in targets.clone() { if li.aliases().contains(&t.target) { if target_hash.contains_key(&li.alias()) { - if let Some(&mut (litem, ref mut cnames)) = target_hash.get_mut(&li.alias()) { - cnames.push(t.target.split('.').nth(1).ok_or(Error::from("no capture name found"))?.into()); + if let Some(&mut (_litem, ref mut cnames)) = target_hash.get_mut(&li.alias()) { + cnames.push(( + t.target + .split('.') + .nth(1) + .ok_or(Error::from("no capture name found"))? + .into(), + t.target.clone()) + ); } } else { target_hash.insert( li.alias(), - (&li, vec![ + (&li, vec![( t.target .split('.') .nth(1) .ok_or(Error::from("no capture name found"))? - .into() + .into(), + t.target.clone()) ] ) ); @@ -84,7 +90,56 @@ fn query(data: Json, config: State) -> Result } } + let mut response : Vec = Vec::new(); + for (_alias, &(logitem, ref cns)) in target_hash.iter() { + let mut series_vec = Vec::new(); + for &(_, ref t) in cns.iter() { + series_vec.push(Series{ target : (*t).clone(), datapoints : Vec::new() }); + } + let mut line_iter = BufReader::new( + File::open(logitem.file()) + .chain_err(|| format!("antikoerper log file could not be opened: {}", logitem.file()))? + ).lines(); + while let Some(Ok(line)) = line_iter.next() { + let capture_groups = logitem + .regex() + .captures_iter(&line) + .next() + .ok_or(Error::from("regex did not match"))?; + let timestamp = capture_groups["ts"] + .parse::() + .chain_err(|| "Failed to parse the filestamp")?; + for i in 0..cns.len() { + let captured = capture_groups[ + cns.get(i) + .ok_or(Error::from("out of bounds: capture_groups"))? + .0.as_str() + ].parse::() + .chain_err(|| "failed to parse the capture group")?; + series_vec + .get_mut(i) + .ok_or(Error::from("out of bounds: series_vec"))? + .datapoints + .push([ + captured, + timestamp + ]); + } + } + for series in series_vec.iter() { + response.push(TargetData::Series((*series).clone())); + } + } + + Ok( Json( QueryResponse{ 0 : response } ) ) + /* Series{ + target : *k, + BufReader::new(File::open(li.file())?).lines() + .map(|line| { + //let capture_groups = li.regex().captures_iter(line).first()?; + Err(Error::from("not implemented")) + */ } fn main() { -- cgit v1.2.3 From eb67a0911631d8017a075bb853306d31c418e8a4 Mon Sep 17 00:00:00 2001 From: Mario Krehl Date: Sun, 10 Dec 2017 18:17:38 +0100 Subject: Fix indentation in main.rs --- src/main.rs | 103 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index f8014cc..6bd119c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,24 +64,24 @@ fn query(data: Json, config: State) -> Result if let Some(&mut (_litem, ref mut cnames)) = target_hash.get_mut(&li.alias()) { cnames.push(( t.target - .split('.') - .nth(1) - .ok_or(Error::from("no capture name found"))? - .into(), + .split('.') + .nth(1) + .ok_or(Error::from("no capture name found"))? + .into(), t.target.clone()) - ); + ); } } else { target_hash.insert( li.alias(), (&li, vec![( - t.target + t.target .split('.') .nth(1) .ok_or(Error::from("no capture name found"))? .into(), - t.target.clone()) + t.target.clone()) ] ) ); @@ -89,6 +89,8 @@ fn query(data: Json, config: State) -> Result } } } + let date_from = data.0.range.from.timestamp(); + let date_to = data.0.range.to.timestamp(); let mut response : Vec = Vec::new(); for (_alias, &(logitem, ref cns)) in target_hash.iter() { @@ -99,31 +101,30 @@ fn query(data: Json, config: State) -> Result let mut line_iter = BufReader::new( File::open(logitem.file()) .chain_err(|| format!("antikoerper log file could not be opened: {}", logitem.file()))? - ).lines(); + ).lines(); while let Some(Ok(line)) = line_iter.next() { - let capture_groups = logitem - .regex() - .captures_iter(&line) - .next() - .ok_or(Error::from("regex did not match"))?; - let timestamp = capture_groups["ts"] - .parse::() - .chain_err(|| "Failed to parse the filestamp")?; - for i in 0..cns.len() { - let captured = capture_groups[ - cns.get(i) - .ok_or(Error::from("out of bounds: capture_groups"))? - .0.as_str() - ].parse::() - .chain_err(|| "failed to parse the capture group")?; - series_vec - .get_mut(i) - .ok_or(Error::from("out of bounds: series_vec"))? - .datapoints - .push([ - captured, - timestamp - ]); + if let Some(capture_groups) = logitem.regex().captures_iter(&line).next() { + let timestamp = capture_groups["ts"] + .parse::() + .chain_err(|| "Failed to parse the filestamp")?; + if (timestamp as i64) > date_from && (timestamp as i64) < date_to { + for i in 0..cns.len() { + let captured = capture_groups[ + cns.get(i) + .ok_or(Error::from("out of bounds: capture_groups"))? + .0.as_str() + ].parse::() + .chain_err(|| "failed to parse the capture group")?; + series_vec + .get_mut(i) + .ok_or(Error::from("out of bounds: series_vec"))? + .datapoints + .push([ + captured, + timestamp * 1000.0 + ]); + } + } } } for series in series_vec.iter() { @@ -132,34 +133,26 @@ fn query(data: Json, config: State) -> Result } Ok( Json( QueryResponse{ 0 : response } ) ) - /* Series{ - target : *k, - BufReader::new(File::open(li.file())?).lines() - .map(|line| { - //let capture_groups = li.regex().captures_iter(line).first()?; - - Err(Error::from("not implemented")) - */ } fn main() { let matches = App::new("aklog-server") - .version("0.1.0") - .author("Mario Krehl ") - .about("Presents antikoerper-logfiles to grafana") - .arg(Arg::with_name("config") - .short("c") - .long("config") - .value_name("FILE") - .help("configuration file to use") - .takes_value(true) - .required(true)) - .arg(Arg::with_name("verbosity") - .short("v") - .long("verbose") - .help("sets the level of verbosity") - .multiple(true)) - .get_matches(); + .version("0.1.0") + .author("Mario Krehl ") + .about("Presents antikoerper-logfiles to grafana") + .arg(Arg::with_name("config") + .short("c") + .long("config") + .value_name("FILE") + .help("configuration file to use") + .takes_value(true) + .required(true)) + .arg(Arg::with_name("verbosity") + .short("v") + .long("verbose") + .help("sets the level of verbosity") + .multiple(true)) + .get_matches(); match matches.occurrences_of("verbosity") { 0 => SimpleLogger::init(LogLevelFilter::Warn, LogConfig::default()).unwrap(), -- cgit v1.2.3