1#[macro_use]
2extern crate lazy_static;
3extern crate regex;
4extern crate serde;
5
6#[cfg_attr(test, macro_use)]
8extern crate serde_json;
9
10use serde_json::Value;
11use std::fs::File;
12use std::io;
13use std::io::Write;
14use std::io::{BufRead, BufReader};
15
16pub mod filter;
17pub mod format;
18pub mod line_formats;
19
20use filter::*;
21use format::*;
22
23pub fn read_log(
24 maybe_file_path: Option<&String>,
25 unparsed_filters: Vec<&str>,
26 number_of_lines: Option<&u64>,
27) {
28 let stdin = io::stdin();
29 let reader: Box<dyn BufRead> = match maybe_file_path {
30 Some(file_path) => Box::new(BufReader::new(
31 File::open(file_path).expect("File should exist"),
32 )),
33 None => Box::new(stdin.lock()),
34 };
35
36 let filters = parse_filters(unparsed_filters);
37
38 let mut count: u64 = 0;
39
40 let stdout = io::stdout();
41 let mut stdout_lock = stdout.lock();
42 let mut formatter = Formatter::new();
43 for maybe_line in reader.lines() {
44 if number_of_lines.is_some() && count >= *number_of_lines.unwrap() {
45 return;
46 }
47 let line = maybe_line.expect("Line should exist");
48 let output = match serde_json::from_str::<Value>(line.as_str()) {
49 Err(_e) => Some(formatter.format_not_json(&line)),
50 Ok(v) => {
51 if v.is_object() {
52 if passes_filters(&filters, &v) {
53 Some(formatter.format_message(v))
54 } else {
55 None
56 }
57 } else {
58 Some(formatter.format_not_json(&line))
59 }
60 }
61 };
62
63 if output.is_some() {
64 writeln!(stdout_lock, "{}", output.unwrap()).unwrap_or(());
65 count += 1;
66 }
67 }
68}