mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-29 09:32:47 +00:00
Implement new JSON data struct in pqd.
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user