Implement new JSON data struct in pqd.

This commit is contained in:
Daniel Nichter
2013-05-22 19:40:33 -07:00
parent c99cb3ba58
commit 95474b1669
2 changed files with 274 additions and 45 deletions

View File

@@ -7635,8 +7635,8 @@ use constant PTDEBUG => $ENV{PTDEBUG} || 0;
my $have_json = eval { require JSON };
our $pretty_json = 0;
our $sorted_json = 0;
our $pretty_json = $ENV{PTTEST_PRETTY_JSON} || 0;
our $sorted_json = $ENV{PTTEST_PRETTY_JSON} || 0;
extends qw(QueryReportFormatter);
@@ -7695,14 +7695,99 @@ override query_report => sub {
foreach my $arg ( qw(ea worst orderby groupby) ) {
die "I need a $arg argument" unless defined $arg;
}
my $groupby = $args{groupby};
my $ea = $args{ea};
my $worst = $args{worst};
my $orderby = $args{orderby};
my $groupby = $args{groupby};
my $results = $ea->results();
my @attribs = @{$ea->get_attributes()};
my $q = $self->Quoter;
my $q = $self->Quoter;
my $qr = $self->QueryRewriter;
my $global_data = {
metrics => {},
};
my $global_cnt = $results->{globals}->{$orderby}->{cnt} || 0;
my $global_unq = scalar keys %{$results->{classes}};
my ($qps, $conc) = (0, 0);
if ( $global_cnt && $results->{globals}->{ts}
&& ($results->{globals}->{ts}->{max} || '')
gt ($results->{globals}->{ts}->{min} || '') )
{
eval {
my $min = parse_timestamp($results->{globals}->{ts}->{min});
my $max = parse_timestamp($results->{globals}->{ts}->{max});
my $diff = unix_timestamp($max) - unix_timestamp($min);
$qps = $global_cnt / ($diff || 1);
$conc = $results->{globals}->{$orderby}->{sum} / $diff;
};
}
$global_data->{query_count} = $global_cnt;
$global_data->{unique_query_count} = $global_unq;
$global_data->{queries_per_second} = $qps if $qps;
$global_data->{concurrency} = $conc if $conc;
my %hidden_attrib = (
arg => 1,
fingerprint => 1,
pos_in_log => 1,
ts => 1,
bytes => 1,
);
foreach my $attrib ( grep { !$hidden_attrib{$_} } @attribs ) {
my $type = $ea->type_for($attrib) || 'string';
next if $type eq 'string';
next unless exists $results->{globals}->{$attrib};
my $store = $results->{globals}->{$attrib};
my $metrics = $ea->stats()->{globals}->{$attrib};
my $int = $attrib =~ m/(?:time|wait)$/ ? 0 : 1;
if ( $type eq 'num' ) {
foreach my $m ( qw(sum min max) ) {
if ( $int ) {
$global_data->{metrics}->{$attrib . "_$m"}
= sprintf('%d', $store->{$m} || 0);
}
else { # microsecond
$global_data->{metrics}->{$attrib . "_$m"}
= sprintf('%.6f', $store->{$m} || 0);
}
}
foreach my $m ( qw(pct_95 stddev median) ) {
if ( $int ) {
$global_data->{metrics}->{$attrib . "_$m"}
= sprintf('%d', $metrics->{$m} || 0);
}
else { # microsecond
$global_data->{metrics}->{$attrib . "_$m"}
= sprintf('%.6f', $metrics->{$m} || 0);
}
}
if ( $int ) {
$global_data->{metrics}->{$attrib . "_avg"}
= sprintf('%d', $store->{sum} / $store->{cnt});
}
else {
$global_data->{metrics}->{$attrib . "_avg"}
= sprintf('%.6f', $store->{sum} / $store->{cnt});
}
}
elsif ( $type eq 'bool' ) {
my $store = $results->{globals}->{$attrib};
$global_data->{metrics}->{$attrib . "_cnt"}
= sprintf('%d', $store->{sum});
}
}
my @queries;
foreach my $worst_info ( @$worst ) {
my $item = $worst_info->[0];
my $stats = $ea->results->{classes}->{$item};
@@ -7710,12 +7795,20 @@ override query_report => sub {
my $all_log_pos = $ea->{result_classes}->{$item}->{pos_in_log}->{all};
my $times_seen = sum values %$all_log_pos;
my $distill = $groupby eq 'fingerprint' ? $qr->distill($sample->{arg})
: undef;
my %class = (
sample => $sample->{arg},
attribute => $groupby,
fingerprint => $item,
checksum => make_checksum($item),
cnt => $times_seen,
distillate => $distill,
query_count => $times_seen,
example => {
query => $sample->{arg},
ts => $sample->{ts} ? parse_timestamp($sample->{ts}) : undef,
},
);
my %metrics;
@@ -7731,6 +7824,8 @@ override query_report => sub {
delete $metrics{$attrib};
next;
}
delete $metrics{pos_in_log};
delete $metrics{$attrib}->{cnt};
if ($attrib eq 'ts') {
my $ts = delete $metrics{ts};
@@ -7741,16 +7836,26 @@ override query_report => sub {
$class{ts_min} = $ts->{min};
$class{ts_max} = $ts->{max};
}
elsif ( ($ea->{type_for}->{$attrib} || '') eq 'string' ) {
$metrics{$attrib} = { value => $metrics{$attrib}{max} };
}
elsif ( ($ea->{type_for}->{$attrib} || '') eq 'num' ) {
for my $value ( values %{$metrics{$attrib}} ) {
next unless $value;
$value = sprintf '%.6f', $value;
else {
my $type = $ea->type_for($attrib) || 'string';
if ( $type eq 'string' ) {
$metrics{$attrib} = { value => $metrics{$attrib}{max} };
}
if ( my $pct = $metrics{$attrib}->{pct} ) {
$metrics{$attrib}->{pct} = sprintf('%.2f', $pct);
elsif ( $type eq 'num' ) {
foreach my $value ( values %{$metrics{$attrib}} ) {
next unless defined $value;
if ( $attrib =~ m/_(?:time|wait)$/ ) {
$value = sprintf('%.6f', $value);
}
else {
$value = sprintf('%d', $value);
}
}
}
elsif ( $type eq 'bool' ) {
$metrics{$attrib} = {
yes => sprintf('%d', $metrics{$attrib}->{sum}),
};
}
}
}
@@ -7763,7 +7868,7 @@ override query_report => sub {
my @table_names = $self->QueryParser->extract_tables(
query => $sample->{arg} || '',
default_db => $default_db,
Quoter => $self->Quoter,
Quoter => $q,
);
my @tables;
foreach my $db_tbl ( @table_names ) {
@@ -7790,7 +7895,7 @@ override query_report => sub {
}
}
else {
my $converted = $self->QueryRewriter->convert_to_select(
my $converted = $qr->convert_to_select(
$sample->{arg} || '',
);
if ( $converted && $converted =~ m/^[\(\s]*select/i ) {
@@ -7806,9 +7911,13 @@ override query_report => sub {
};
}
my $json = $self->encode_json(\@queries);
$json .= "\n" if $json !~ /\n\Z/;
return $json . "\n";
my $data = {
global => $global_data,
classes => \@queries,
};
my $json = $self->encode_json($data);
$json .= "\n" unless $json =~ /\n\Z/;
return $json;
};
no Lmo;