Skip to content

Commit

Permalink
Updated access_log_parser library to 0.5.0 and add support for gorout…
Browse files Browse the repository at this point in the history
…er_time and x_cf_routererror fields in Gorouter log format.
  • Loading branch information
Daniel Mikusa committed Aug 4, 2020
1 parent 0d6c2cd commit ece240d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 6 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "top-logs"
version = "1.2.0"
version = "1.3.0"
authors = ["Daniel Mikusa <[email protected]>"]
edition = "2018"
description = "Tops logs is a tool which can be used to parse through access logs to understand usage trends and hunt for problems"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,17 @@ Tops logs is a tool which can be used to parse through access logs to understand
- Top X Client IPs
- Top X X-Forwarded-For Ips
- Response time histogram
- Gorouter time histogram
- Top X Backend Address (Cells & Platform VMs)
- Top X Destination Hosts
- Top X App GUIDs
- Top X x_cf_routererror responses

## Usage

```
$ ./target/release/top-logs -i -f cloud_controller data/cloud_controller/nginx.access.log* -h
top-logs 1.1.0
top-logs 1.3.0
Daniel Mikusa <[email protected]>
Parses various access log formats and prints stats helpful for debugging/troubleshooting.
Expand Down
88 changes: 88 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ pub struct TopInfo {
pub hosts: DefaultHashMap<String, usize>,
pub app_ids: DefaultHashMap<String, usize>,
pub response_times: DefaultHashMap<usize, usize>,
pub gorouter_times: DefaultHashMap<usize, usize>,
pub x_cf_routererrors: DefaultHashMap<String, usize>,
}

impl TopInfo {
Expand Down Expand Up @@ -153,6 +155,8 @@ impl TopInfo {
hosts: DefaultHashMap::new(0),
app_ids: DefaultHashMap::new(0),
response_times: DefaultHashMap::new(0),
gorouter_times: DefaultHashMap::new(0),
x_cf_routererrors: DefaultHashMap::new(0),
}
}

Expand Down Expand Up @@ -393,6 +397,15 @@ impl TopInfo {
.response_time
.map(|t| t.floor() as usize)
.unwrap_or(usize::max_value())] += 1;

// bucket gorouter times
self.gorouter_times[log_entry
.gorouter_time
.map(|t| t.floor() as usize)
.unwrap_or(usize::max_value())] += 1;

// count x_cf_routererror hits
self.x_cf_routererrors[log_entry.x_cf_routererror.unwrap_or("<none>").to_string()] += 1;
}

fn print_map<'a, I, K, V>(iter: I, sort_order: &SortOrder, max: usize)
Expand Down Expand Up @@ -577,5 +590,80 @@ impl TopInfo {

println!();
}

if self.gorouter_times.len() > 0 {
println!("Top Gorouter Times");
let mut keys: Vec<&usize> = self
.gorouter_times
.keys()
.filter(|&k| *k < usize::max_value())
.collect();
keys.sort();

let max_key = **keys.iter().max().unwrap_or(&&0);
let max_width = format!("{}", max_key).len();

println!();

let mut table = Table::new();
table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP);

let mut bucket_val: usize = 0;
let mut bucket_start: usize = 0;

for key in keys {
if bucket_start == 0 {
bucket_start = *key;
}

bucket_val += self.gorouter_times[key];

if bucket_val >= min_response_time_threshold {
table.add_row(Row::new(vec![
cell!(format!(
"{:width$} to {:width$}",
bucket_start,
key + 1,
width = max_width
)),
cell!(bucket_val),
]));
bucket_start = 0;
bucket_val = 0;
}
}

if bucket_val > 0 {
table.add_row(Row::new(vec![
cell!(format!(
"{:width$} to {:width$}",
bucket_start,
max_key + 1,
width = max_width
)),
cell!(bucket_val),
]));
}

if self.gorouter_times.contains_key(&usize::max_value()) {
table.add_row(Row::new(vec![
cell!("<none>"),
cell!(self.gorouter_times.get(&usize::max_value())),
]));
}

table.printstd();

println!();
}

if self.x_cf_routererrors.len() > 0 {
println!("Top '{}' CF Router Errors", self.max_results);
TopInfo::print_map(
self.x_cf_routererrors.iter(),
&SortOrder::ByValue,
self.max_results,
);
}
}
}

0 comments on commit ece240d

Please sign in to comment.