diff options
author | Byron Jones <bjones@mozilla.com> | 2014-03-04 09:38:49 +0100 |
---|---|---|
committer | Byron Jones <bjones@mozilla.com> | 2014-03-04 09:38:49 +0100 |
commit | faf2fc5dbead69f0de0df51af85561f1203dee45 (patch) | |
tree | 7e323a20361165348a3f8a564c9e1d22df820a1c /Bugzilla/Metrics/Reporter.pm | |
parent | 9193214274889f2b7636146e72d8200e9bfaeb7b (diff) | |
download | bugzilla-faf2fc5dbead69f0de0df51af85561f1203dee45.tar.gz bugzilla-faf2fc5dbead69f0de0df51af85561f1203dee45.tar.xz |
Bug 956230: improve instrumentation of bugzilla's internals
Diffstat (limited to 'Bugzilla/Metrics/Reporter.pm')
-rw-r--r-- | Bugzilla/Metrics/Reporter.pm | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/Bugzilla/Metrics/Reporter.pm b/Bugzilla/Metrics/Reporter.pm new file mode 100644 index 000000000..42d2c3abc --- /dev/null +++ b/Bugzilla/Metrics/Reporter.pm @@ -0,0 +1,101 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Metrics::Reporter; + +use strict; +use warnings; + +use Bugzilla::Constants; +use File::Slurp; +use File::Temp; +use JSON; + +# most reporters should detach from the httpd process. +# reporters which do not detach will block completion of the http response. +use constant DETACH => 1; + +# class method to start the delivery script in the background +sub background { + my ($class, $collector) = @_; + + # we need to remove parent links to avoid looped structures, which + # encode_json chokes on + _walk_timers($collector->{root}, sub { delete $_[0]->{parent} }); + + # serialisation + my $json = encode_json({ env => $collector->{env}, times => $collector->{root} }); + + # write to temp filename + my $fh = File::Temp->new( UNLINK => 0 ); + if (!$fh) { + warn "Failed to create temp file: $!\n"; + return; + } + binmode($fh, ':utf8'); + print $fh $json; + close($fh) or die "$fh : $!"; + my $filename = $fh->filename; + + # spawn delivery worker + my $command = bz_locations()->{'cgi_path'} . "/metrics.pl '$class' '$filename' &"; + system($command); +} + +# run the reporter immediately +sub foreground { + my ($class, $collector) = @_; + my $reporter = $class->new({ hashref => { env => $collector->{env}, times => $collector->{root} } }); + $reporter->report(); +} + +sub new { + my ($invocant, $args) = @_; + my $class = ref($invocant) || $invocant; + + # load from either a json_filename or hashref + my $self; + if ($args->{json_filename}) { + $self = decode_json(read_file($args->{json_filename}, binmode => ':utf8')); + unlink($args->{json_filename}); + } + else { + $self = $args->{hashref}; + } + bless($self, $class); + + # remove redundant data + $self->walk_timers(sub { + my ($timer) = @_; + $timer->{start_time} = delete $timer->{first_time}; + delete $timer->{children} + if exists $timer->{children} && !scalar(@{ $timer->{children} }); + }); + + return $self; +} + +sub walk_timers { + my ($self, $callback) = @_; + _walk_timers($self->{times}, $callback, undef); +} + +sub _walk_timers { + my ($timer, $callback, $parent) = @_; + $callback->($timer, $parent); + if (exists $timer->{children}) { + foreach my $child (@{ $timer->{children} }) { + _walk_timers($child, $callback, $timer); + } + } +} + +sub report { + die "abstract method call"; +} + +1; |