From 1f7e1c12e2489d7b6271fe4dc350e4ee25f1f42b Mon Sep 17 00:00:00 2001 From: Brian Fraser Date: Wed, 16 Jan 2013 16:46:40 -0300 Subject: [PATCH] lib/JSONReportFormatter.pm: Change the json output struct to the new spec --- bin/pt-query-digest | 97 +++++++++++++++++--------------------- lib/JSONReportFormatter.pm | 97 +++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 108 deletions(-) diff --git a/bin/pt-query-digest b/bin/pt-query-digest index 0b1b71b5..cd735aa4 100755 --- a/bin/pt-query-digest +++ b/bin/pt-query-digest @@ -7979,50 +7979,14 @@ package JSONReportFormatter; use Mo; use JSON; -use Transformers qw(make_checksum); +use List::Util qw(sum); + +use Transformers qw(make_checksum parse_timestamp); use constant PTDEBUG => $ENV{PTDEBUG} || 0; extends qw(QueryReportFormatter); -has history_metrics => ( - is => 'ro', - isa => 'HashRef', -); - -sub BUILDARGS { - my $class = shift; - my %orig_args = @_; - my $args = $class->SUPER::BUILDARGS(@_); - - my $o = $orig_args{OptionParser}; - - my $sql = $o->read_para_after( - __FILE__, qr/MAGIC_create_review_history/); - - my $pat = $o->read_para_after(__FILE__, qr/MAGIC_history_cols/); - $pat = qr/\ {3}(\w+?)_($pat)\s+/; - - my %metrics; - foreach my $sql_line (split /\n/, $sql) { - my ( $attr, $metric ) = $sql_line =~ $pat; - next unless $attr && $metric; - - $attr = ucfirst $attr if $attr =~ m/_/; - $attr = 'Filesort' if $attr eq 'filesort'; - - $attr =~ s/^Qc_hit/QC_Hit/; # Qc_hit is really QC_Hit - $attr =~ s/^Innodb/InnoDB/g; # Innodb is really InnoDB - $attr =~ s/_io_/_IO_/g; # io is really IO - - $metrics{$attr}{$metric} = 1; - } - - $args->{history_metrics} = \%metrics; - - return $args; -} - override [qw(rusage date hostname files header profile prepared)] => sub { return; }; @@ -8041,33 +8005,58 @@ override query_report => sub { my $ea = $args{ea}; my $worst = $args{worst}; - my $history_metrics = $self->history_metrics; - my @attribs = grep { $history_metrics->{$_} } @{$ea->get_attributes()}; - + my @attribs = @{$ea->get_attributes()}; + my @queries; foreach my $worst_info ( @$worst ) { - my $item = $worst_info->[0]; - my $stats = $ea->results->{classes}->{$item}; - my $sample = $ea->results->{samples}->{$item}; + my $item = $worst_info->[0]; + my $stats = $ea->results->{classes}->{$item}; + my $sample = $ea->results->{samples}->{$item}; + my $all_log_pos = $ea->{result_classes}->{$item}->{pos_in_log}->{all}; + my $times_seen = sum values %$all_log_pos; + + my %class = ( + sample => $sample->{arg}, + fingerprint => $item, + checksum => make_checksum($item), + cnt => $times_seen, + ); + my %metrics; foreach my $attrib ( @attribs ) { $metrics{$attrib} = $ea->metrics( attrib => $attrib, where => $item, ); - - my $needed_metrics = $history_metrics->{$attrib}; - for my $key ( keys %{$metrics{$attrib}} ) { - delete $metrics{$attrib}{$key} - unless $needed_metrics->{$key}; - } } + foreach my $attrib ( keys %metrics ) { + if ( ! grep { $_ } values %{$metrics{$attrib}} ) { + delete $metrics{$attrib}; + next; + } + + if ($attrib eq 'ts') { + my $ts = delete $metrics{ts}; + foreach my $thing ( qw(min max) ) { + next unless defined $ts && defined $ts->{$thing}; + $ts->{$thing} = parse_timestamp($ts->{$thing}); + } + $class{ts_min} = $ts->{min}; + $class{ts_max} = $ts->{max}; + } + elsif ( ($ea->{type_for}->{$attrib} || '') eq 'num' ) { + for my $value ( values %{$metrics{$attrib}} ) { + next unless $value; + $value = sprintf '%.7f', $value; + } + } + } + push @queries, { - sample => $sample, - checksum => make_checksum($item), - %metrics + class => \%class, + attributes => \%metrics, }; } diff --git a/lib/JSONReportFormatter.pm b/lib/JSONReportFormatter.pm index bac1194c..e2cc0a31 100644 --- a/lib/JSONReportFormatter.pm +++ b/lib/JSONReportFormatter.pm @@ -3,50 +3,14 @@ package JSONReportFormatter; use Mo; use JSON; -use Transformers qw(make_checksum); +use List::Util qw(sum); + +use Transformers qw(make_checksum parse_timestamp); use constant PTDEBUG => $ENV{PTDEBUG} || 0; extends qw(QueryReportFormatter); -has history_metrics => ( - is => 'ro', - isa => 'HashRef', -); - -sub BUILDARGS { - my $class = shift; - my %orig_args = @_; - my $args = $class->SUPER::BUILDARGS(@_); - - my $o = $orig_args{OptionParser}; - - my $sql = $o->read_para_after( - __FILE__, qr/MAGIC_create_review_history/); - - my $pat = $o->read_para_after(__FILE__, qr/MAGIC_history_cols/); - $pat = qr/\ {3}(\w+?)_($pat)\s+/; - - my %metrics; - foreach my $sql_line (split /\n/, $sql) { - my ( $attr, $metric ) = $sql_line =~ $pat; - next unless $attr && $metric; - - $attr = ucfirst $attr if $attr =~ m/_/; - $attr = 'Filesort' if $attr eq 'filesort'; - - $attr =~ s/^Qc_hit/QC_Hit/; # Qc_hit is really QC_Hit - $attr =~ s/^Innodb/InnoDB/g; # Innodb is really InnoDB - $attr =~ s/_io_/_IO_/g; # io is really IO - - $metrics{$attr}{$metric} = 1; - } - - $args->{history_metrics} = \%metrics; - - return $args; -} - override [qw(rusage date hostname files header profile prepared)] => sub { return; }; @@ -65,33 +29,58 @@ override query_report => sub { my $ea = $args{ea}; my $worst = $args{worst}; - my $history_metrics = $self->history_metrics; - my @attribs = grep { $history_metrics->{$_} } @{$ea->get_attributes()}; - + my @attribs = @{$ea->get_attributes()}; + my @queries; foreach my $worst_info ( @$worst ) { - my $item = $worst_info->[0]; - my $stats = $ea->results->{classes}->{$item}; - my $sample = $ea->results->{samples}->{$item}; + my $item = $worst_info->[0]; + my $stats = $ea->results->{classes}->{$item}; + my $sample = $ea->results->{samples}->{$item}; + my $all_log_pos = $ea->{result_classes}->{$item}->{pos_in_log}->{all}; + my $times_seen = sum values %$all_log_pos; + + my %class = ( + sample => $sample->{arg}, + fingerprint => $item, + checksum => make_checksum($item), + cnt => $times_seen, + ); + my %metrics; foreach my $attrib ( @attribs ) { $metrics{$attrib} = $ea->metrics( attrib => $attrib, where => $item, ); - - my $needed_metrics = $history_metrics->{$attrib}; - for my $key ( keys %{$metrics{$attrib}} ) { - delete $metrics{$attrib}{$key} - unless $needed_metrics->{$key}; - } } + foreach my $attrib ( keys %metrics ) { + if ( ! grep { $_ } values %{$metrics{$attrib}} ) { + delete $metrics{$attrib}; + next; + } + + if ($attrib eq 'ts') { + my $ts = delete $metrics{ts}; + foreach my $thing ( qw(min max) ) { + next unless defined $ts && defined $ts->{$thing}; + $ts->{$thing} = parse_timestamp($ts->{$thing}); + } + $class{ts_min} = $ts->{min}; + $class{ts_max} = $ts->{max}; + } + elsif ( ($ea->{type_for}->{$attrib} || '') eq 'num' ) { + for my $value ( values %{$metrics{$attrib}} ) { + next unless $value; + $value = sprintf '%.7f', $value; + } + } + } + push @queries, { - sample => $sample, - checksum => make_checksum($item), - %metrics + class => \%class, + attributes => \%metrics, }; }