-
-
Save timo/42cce4904647f6a0fb2f3dc7d29dfe5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use JSON::Fast; | |
my %intervals; | |
my @timestamps; | |
my $ticks-per-sec; | |
my $epoch; | |
my %messages; | |
class StatsAbsorber { | |
has %.statsdata; | |
method collect($obj) { | |
my $objkey = $obj.WHAT.^name; | |
for $obj.Capture.Hash -> (:key($k), :value($v)) { | |
%.statsdata{$objkey}{$k}.push: $v with $v; | |
} | |
} | |
} | |
enum Kind <IStart IStop IAnnotation TStamp>; | |
class Interval {...} | |
class Annotation { | |
has Str $.subject; | |
has Str $.message; | |
has Interval $.owner_interval; | |
method Capture { | |
\(:$.subject, :$.message) | |
} | |
} | |
class Interval { | |
has $.subject; | |
has $.message; | |
has $.endmessage is rw; | |
has @.annotations; | |
has $.starttime; | |
has $.duration is rw; | |
} | |
class Timestamp { | |
has $.message; | |
has $.time; | |
} | |
my $absorber; | |
multi sub MAIN(:$filename = "/dev/stdin") { | |
$absorber = StatsAbsorber.new; | |
for $filename.IO.lines() -> $line { | |
my @parts = $line.words; | |
my $subject = @parts.shift; | |
my $interval_id; | |
my $intervalpart; | |
my $message; | |
my $kind; | |
my $time; | |
when @parts[0] eq 'Calibration:' { | |
$ticks-per-sec = +@parts[1]; | |
succeed; | |
} | |
when @parts[0] eq 'Epoch' { | |
$epoch = +@parts[2]; | |
succeed; | |
} | |
do { | |
$message = $line.substr(my $first_quote = $line.index('"') + 1, $line.rindex('"') - $first_quote); | |
} | |
try $time = +@parts[0] / $ticks-per-sec; | |
if @parts[0] eq '???' || @parts[1] eq '(-' || @parts[1] eq '-)' { | |
$intervalpart = @parts.pop; | |
die "invalid line in telemetry log: $line" unless $intervalpart.starts-with('(') && $intervalpart.ends-with(')'); | |
$interval_id = +$intervalpart.substr(1, *-1); | |
} | |
$kind = IAnnotation if @parts[0] eq '???'; | |
$kind = IStart if @parts[1] eq '(-'; | |
$kind = IStop if @parts[1] eq '-)'; | |
$kind = TStamp if @parts[1] eq '-|-'; | |
with $intervalpart { | |
given $kind { | |
when IStart { | |
%intervals{$interval_id} = new Interval: :$subject, :$message, :starttime($time); | |
} | |
when IStop { | |
given %intervals{$interval_id} { | |
.duration = $time - .starttime; | |
.endmessage = $message unless $message eq .message; | |
$absorber.collect($_); | |
} | |
} | |
when IAnnotation { | |
given %intervals{$interval_id} { | |
.annotations.push: new Annotation: :$subject, :$message, :owner_interval($_); | |
$absorber.collect($_); | |
} | |
} | |
} | |
} | |
without $intervalpart { | |
given $kind { | |
when TStamp { | |
@timestamps.push: my $ts = new Timestamp: :$time, :$message; | |
$absorber.collect($ts); | |
} | |
} | |
} | |
$*ERR.print(".") if ++$ %% 1000; | |
note "" if ++$ %% 60000; | |
} | |
note "done"; | |
note "writing json"; | |
spurt("statsdata.json", $absorber.statsdata.&to-json(:!pretty)); | |
analyze(); | |
} | |
multi sub MAIN("from-json", $filename = "statsdata.json") { | |
$absorber = StatsAbsorber.new: :statsdata(from-json($filename.IO.slurp)); | |
analyze(); | |
} | |
sub analyze() { | |
for $absorber.statsdata.pairs -> (:key($typename), :value($_)) { | |
"$typename stats:".put; | |
for $_.pairs -> (:key($attrname), :value($_)) { | |
" $attrname stats:".put; | |
" $_.elems() entries".put; | |
if .[0] ~~ Str { | |
for .Bag -> (:key($entry), :value($_)) { | |
" $_.fmt("%4d") $entry".put; | |
} | |
} elsif .[0] ~~ Real { | |
my @sorted = .sort; | |
" ".print; | |
@sorted[* div 20, * div 4, * div 2, * * 3 div 4, * * 19 div 20].fmt("%10f").put; | |
} | |
} | |
} | |
} | |
#my @intervals_sorted = %intervals.pairs.sort(*.value.starttime); | |
#for @intervals_sorted -> (:key($k), :value($_)) { | |
#"$k.fmt("%6d"); $_.subject()".put; | |
#"$_.starttime() ($_.duration()): $_.message()".put; | |
#for .annotations { | |
#" $_.message(); $_.subject()".put; | |
#} | |
#} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment