diff options
| author | Paul Buetow <paul@buetow.org> | 2023-02-26 14:47:24 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2023-02-26 14:47:24 +0200 |
| commit | 7c31ae967dde77be3c734d43d985b279ff172424 (patch) | |
| tree | 3bd0e8ec19f7103c2878ec569fb3879b874a0bdc | |
| parent | 819a87d817d8905523a44d52c274fe879af6408c (diff) | |
initial human outputing
| -rw-r--r-- | src/guprecords.raku | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/guprecords.raku b/src/guprecords.raku index 571f90a..976a83c 100644 --- a/src/guprecords.raku +++ b/src/guprecords.raku @@ -3,26 +3,25 @@ use v6.d; subset Nat of Int where * >= 0; - subset Cat of Str where * eq any <host os os-major uname>; subset SubCat of Str where * eq any <boots uptime downtime lifespan meta-score>; - subset HostOnlyCat of Cat where * eq 'host'; subset BasicSubCat of SubCat where * ne any <downtime lifespan>; +our Nat constant DAY = 1 * 24 * 3600; +our Nat constant MONTH = 30 * DAY; + class Epoch { - our Nat constant DAY = 1 * 24 * 3600; - our Nat constant MONTH = 30 * DAY; has Nat $.value is required; submethod new (Nat $value) { self.bless(:$value) } - method duration returns Str { + method human-duration returns Str { my DateTime \dt .= new(Instant.from-posix: $!value); "{dt.year-1970} years, {dt.month} months, {dt.day} days"; } - method date returns Str { + method human-date returns Str { DateTime.new(Instant.from-posix: $!value).yyyy-mm-dd; } @@ -38,6 +37,8 @@ class Aggregate { has Nat $.last-seen; has Nat $.boots; + method new (Str $name) { self.bless(:$name) } + method add-record(Str:D :$uptime is readonly, Str:D :$boot-time is readonly) { my Int $last-seen = $uptime + $boot-time; $!uptime += $uptime; @@ -48,7 +49,7 @@ class Aggregate { } method meta-score returns Nat { - Nat((($!uptime * 2) + ($!boots * Epoch.DAY) + (self.is-active ?? Epoch.MONTH !! 0))/1000000) + Nat((($!uptime * 2) + ($!boots * DAY) + (self.is-active ?? MONTH !! 0))/1000000) } method is-active(Nat:D \limit = 90) returns Bool { @@ -59,7 +60,7 @@ class Aggregate { class HostAggregate is Aggregate { method lifespan returns Nat { $.last-seen - $.first-boot } method downtime returns Nat { self.lifespan - $.uptime } - method meta-score returns Nat { self.downtime + callsame } + method meta-score returns Nat { Nat(self.downtime / 1000000) + callsame } } class Aggregator { @@ -70,7 +71,7 @@ class Aggregator { die "Record file for {$host} already processed - duplicate inputs?" if %!aggregates<host>{$host}:exists; - %!aggregates<host>{$host} = HostAggregate.new: :name($host); + %!aggregates<host>{$host} = HostAggregate.new($host); for $file.IO.lines -> Str $line { self!add-line(:$line, :$host) } } @@ -80,9 +81,9 @@ class Aggregator { my Str $uname = $os.split(' ').first; my Str $os-major = "$uname {$os.split(' ')[1].split('.').first}..."; - %!aggregates<os>{$os} //= Aggregate.new: :name($os); - %!aggregates<uname>{$uname} //= Aggregate.new: :name($uname); - %!aggregates<os-major>{$os-major} //= Aggregate.new: :name($os-major); + %!aggregates<os>{$os} //= Aggregate.new($os); + %!aggregates<uname>{$uname} //= Aggregate.new($uname); + %!aggregates<os-major>{$os-major} //= Aggregate.new($os-major); for %!aggregates<host>{$host}, %!aggregates<os>{$os}, %!aggregates<uname>{$uname}, %!aggregates<os-major>{$os-major} { @@ -94,15 +95,24 @@ class Aggregator { class Reporter { has Cat $.cat is required; has SubCat $.sub-cat is required; + has Nat $.first is required; has Hash %.aggregates; method report { - for self.sort-by($!sub-cat) -> $what { - $what.raku.say; - $what.is-active.say; + say "Top {$.first} {$.sub-cat}'s by {$.cat}:\n"; + my Nat $count = 0; + + for self.sort-by($!sub-cat) -> Aggregate $what { + self!pretty-say($what, $count+1); + last if ++$count == $.first; } } + method !pretty-say(Aggregate:D \what, Nat:D \position) { + my Str \active = what.is-active ?? ' (still active)' !! ''; + say "{position}. {what.name}{active}:\n\t{self.human-str($.sub-cat, what)}"; + } + multi method sort-by('uptime') { self.sort-by: *.uptime } multi method sort-by('boots') { self.sort-by: *.boots } multi method sort-by('meta-score') { self.sort-by: *.meta-score } @@ -110,11 +120,18 @@ class Reporter { multi method sort-by(Code:D $sort-by) { %!aggregates{$!cat}.values.sort(&$sort-by).reverse; } + + multi method human-str('uptime', Aggregate:D $what) { "Uptime: {Epoch.new($what.uptime).human-duration}" } + multi method human-str('boots', Aggregate:D $what) { "Number of boots: {$what.boots}" } + multi method human-str('meta-score', Aggregate:D $what) { "Meta score: {$what.meta-score}" } } class HostReporter is Reporter { multi method sort-by('downtime') { self.sort-by: *.downtime } multi method sort-by('lifespan') { self.sort-by: *.lifespan } + + multi method human-str('downtime', Aggregate:D $what) { "Downtime: {Epoch.new($what.downtime).human-duration}" } + multi method human-str('lifespan', Aggregate:D $what) { "Lifespan: {Epoch.new($what.lifespan).human-duration}" } } sub do-it(Str:D \stats-dir, Reporter:D \reporter) { @@ -128,14 +145,17 @@ multi MAIN( Str :$stats-dir is required, #= The uptimed raw record input dir. HostOnlyCat :$cat = 'host', #= Category, one of host, os os-major and uname. SubCat :$sub-cat = 'uptime', #= Sort by one of boots uptime downtime and lifespan. + Nat :$first = 13, #= Only show top N entries. ) { - do-it($stats-dir, HostReporter.new(:$cat, :$sub-cat)); + do-it($stats-dir, HostReporter.new(:$cat, :$sub-cat, :$first)); } multi MAIN( Str :$stats-dir is required, Cat :$cat, BasicSubCat :$sub-cat = 'uptime', + Nat :$first = 13, ) { - do-it($stats-dir, Reporter.new(:$cat, :$sub-cat)); + do-it($stats-dir, Reporter.new(:$cat, :$sub-cat, :$first)); } + |
