Metrics.pm 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package Trog::Log::Metrics;
  2. use 5.040;
  3. use re '/aasx';
  4. use Trog::SQLite;
  5. use Trog::Log;
  6. =head1 Trog::Log::Metrics
  7. A means for acquiring time-series representations of the data recorded by Trog::Log::DBI,
  8. and for reasoning about the various things that it's Urchin-compatible data can give you.
  9. =cut
  10. =head2 requests_per(ENUM period{second,minute,hour,day,month,year}, INTEGER num_periods, [TIME_T before], INTEGER[] @codes)
  11. Returns a data structure of the following form
  12. {
  13. labels => [TIME_STR, TIME_STR, ...],
  14. data => [INT, INT,...]
  15. }
  16. Describing the # of requests for the requested $num_periods $period(s) before $before.
  17. 'month' and 'year' are approximations for performance reasons; 30 day and 365 day periods.
  18. Optionally filter by response code(s).
  19. =cut
  20. sub requests_per ( $period, $num_periods, $before, @codes ) {
  21. $before ||= time;
  22. # Build our periods in seconds.
  23. state %period2time = (
  24. second => 1,
  25. minute => 60,
  26. hour => 3600,
  27. day => 86400,
  28. week => 604800,
  29. month => 2592000,
  30. year => 31356000,
  31. );
  32. my $interval = $period2time{$period};
  33. die "Invalid time interval passed." unless $interval;
  34. my @input;
  35. my $whereclause = '';
  36. if (@codes) {
  37. my $bind = join( ',', ( map { '?' } @codes ) );
  38. $whereclause = "WHERE code IN ($bind)";
  39. push( @input, @codes );
  40. }
  41. push( @input, $interval, $before, $num_periods );
  42. ## no critic(ValuesAndExpressions::PreventSQLInjection)
  43. my $query = "SELECT count(*) FROM all_requests $whereclause GROUP BY date / ? HAVING date < ? LIMIT ?";
  44. my @results = map { $_->[0] } @{ Trog::Log::_dbh()->selectall_arrayref( $query, undef, @input ) };
  45. my $np = @results < $num_periods ? @results : $num_periods;
  46. my @labels = reverse map { "$_ $period(s) ago" } ( 1 .. $np );
  47. return {
  48. labels => \@labels,
  49. data => \@results,
  50. };
  51. }
  52. 1;