mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-25 21:54:48 +00:00
PT-2080 Add JSON logging to pt-kill (#543)
* Add JSON output support to pt-kill Introduces new flags `--log-json` and `--log-json-fields` to control JSON output: - `--log-json`: when combined with `--print`, outputs kill information in JSON format instead of plain text, with the same fields as the `kill_log` table when using `--log-dsn` - `--log-json-fields`: when combined with `--log-json`, adds user-defined key-value pairs to the JSON document that is output (such as cluster name or hostname); parameter value is in the format of `key1:value1,key2:value2` * Convert --log-json to write to file, remove dependency on --print, update docs The `--log-json` parameter now takes a file path value, and writes JSON output to this file. The `--print` parameter is now independent and does not need to be specified to use `--log-json`. Docs updated for clarity. * Add chksm to JSON output, make JSON key names consistent - Adds chksm outout to JSON output to make it easier to group similar queries - Moves chksm code so that it is always executed, is accessible within the `log-json` scope, and isn't duplicated - Change JSON key names to consistently use uppercase letters at start of words, change `ts` to `Timestamp` * Update docs to match changed field names * Rename JSON parameter, output to STDOUT, fix tests, add test for --json, bug fix for --query-id - `--json` parameter must now be used in conjunction with `--print`; JSON output replaces normal `--print` output when `--json` is also specified - `--json` output is now sent to STDOUT instead of a specified file, as its new behaviour is to change the output format of `--print` instead of logging to a file - Renamed `--log-json` and `--log-json-fields` parameters to `--json` and `--json-fields` to better represent their new behaviour - Refactored checksum code to prevent test failures when `$query->{'Info'}` is empty - Added test for `--json` and `--json-fields` parameters - Fixed bug where specifying `--query-id` would cause errors when `$query->{'Info'}` is empty * Fix typo: Unkown -> Unknown
This commit is contained in:
100
bin/pt-kill
100
bin/pt-kill
@@ -7373,20 +7373,49 @@ sub main {
|
||||
|
||||
MATCHING_QUERY:
|
||||
foreach my $query ( @queries ) {
|
||||
if ( $o->get('print') ) {
|
||||
my $qinfo = ( $query->{Info} || 'NULL' );
|
||||
if( $o->get('fingerprint') && $qinfo ne 'NULL' ) {
|
||||
$qinfo = $qr->fingerprint($query->{'Info'});
|
||||
}
|
||||
|
||||
my $chksm = '';
|
||||
if ( $qinfo ne 'NULL' ) {
|
||||
my $fp = $qr->fingerprint($query->{'Info'});
|
||||
# $chksm is used by query-id and json
|
||||
$chksm = Transformers::make_checksum($fp);
|
||||
}
|
||||
if ( $o->get('print') ) {
|
||||
if ( $o->get('json') ) {
|
||||
my $reasons = join "\n", map {
|
||||
defined($_) ? $_ : "Unknown reason"
|
||||
} @{ $pl->{_reasons_for_matching}->{$query} };
|
||||
my %jsonOutput = (
|
||||
Timestamp => ts(time),
|
||||
Reason => $reasons,
|
||||
Kill_Error => $EVAL_ERROR,
|
||||
Id => $query->{Id},
|
||||
User => $query->{User},
|
||||
Host => $query->{Host},
|
||||
Db => $query->{db},
|
||||
Command => $query->{Command},
|
||||
Time => $query->{Time},
|
||||
State => $query->{State},
|
||||
Info => $qinfo,
|
||||
Digest => $chksm
|
||||
);
|
||||
if ( $o->get('json-fields') ) {
|
||||
my @logFieldKVs = split(",", $o->get('json-fields'));
|
||||
my %logFields = map { split(":", $_) } @logFieldKVs;
|
||||
%jsonOutput = (%jsonOutput, %logFields);
|
||||
}
|
||||
printf "%s\n", Transformers::hash_to_json(\%jsonOutput);
|
||||
} else {
|
||||
printf "# %s %s %d (%s %d sec) %s\n",
|
||||
ts(time), $o->get('kill-query') ? 'KILL QUERY' : 'KILL',
|
||||
$query->{Id}, ($query->{Command} || 'NULL'), $query->{Time},
|
||||
$qinfo;
|
||||
}
|
||||
}
|
||||
if ( $o->get('query-id') ) {
|
||||
my $fp = $qr->fingerprint($query->{'Info'});
|
||||
my $chksm = Transformers::make_checksum($fp);
|
||||
print "Query ID: 0x$chksm\n";
|
||||
}
|
||||
if ( $o->get('execute-command') ) {
|
||||
@@ -7484,7 +7513,7 @@ sub log_to_table {
|
||||
|
||||
my $ts = Transformers::ts(time());
|
||||
my $reasons = join "\n", map {
|
||||
defined($_) ? $_ : "Unkown reason"
|
||||
defined($_) ? $_ : "Unknown reason"
|
||||
} @{ $pl->{_reasons_for_matching}->{$query} };
|
||||
$log->(
|
||||
$ts, $reasons, $args{eval_error},
|
||||
@@ -7869,6 +7898,67 @@ MAGIC_create_log_table:
|
||||
PRIMARY KEY (kill_id)
|
||||
) DEFAULT CHARSET=utf8
|
||||
|
||||
=item --json
|
||||
|
||||
Prints killed queries as JSON, must be used with L<"--print">. For example:
|
||||
|
||||
--print --json
|
||||
|
||||
The usual plain-text output from L<"--print"> will not be displayed.
|
||||
|
||||
JSON output will be in the format of:
|
||||
|
||||
{
|
||||
"Command": "Query",
|
||||
"Host": "10.0.0.1:9999",
|
||||
"Id": 1234,
|
||||
"Info": "SELECT SLEEP(5)",
|
||||
"State": "User sleep",
|
||||
"Time": 10,
|
||||
"User": "my_user",
|
||||
"Db": "my_db",
|
||||
"Kill_Error": "",
|
||||
"Digest": "58A43A7DA83F58C1",
|
||||
"Reason": "Exceeds busy time\nQuery matches Command spec",
|
||||
"Timestamp": "2022-01-01T00:00:00"
|
||||
}
|
||||
|
||||
=item --json-fields
|
||||
|
||||
type: string
|
||||
|
||||
Specify a list of additional key:value pairs to include in JSON output when
|
||||
using L<"--json">, the value of this parameter must be specified in the
|
||||
format of:
|
||||
|
||||
--json-fields key1:value1,key2:value2
|
||||
|
||||
Any fields specified using L<"--json-fields"> will be included in the
|
||||
L<"--json"> output.
|
||||
|
||||
For example:
|
||||
|
||||
--print --json --json-fields hostname:$(hostname),tag:my_tag
|
||||
|
||||
Will result in JSON records being written to "kill_log.json" using this format:
|
||||
|
||||
{
|
||||
"Command": "Query",
|
||||
"Host": "10.0.0.1:9999",
|
||||
"Id": 1234,
|
||||
"Info": "SELECT SLEEP(5)",
|
||||
"State": "User sleep",
|
||||
"Time": 10,
|
||||
"User": "my_user",
|
||||
"Db": "my_db",
|
||||
"Kill_Error": "",
|
||||
"Digest": "58A43A7DA83F58C1",
|
||||
"Reason": "Exceeds busy time\nQuery matches Command spec",
|
||||
"Timestamp": "2022-01-01T00:00:00",
|
||||
"hostname": "my_host",
|
||||
"tag": "my_tag"
|
||||
}
|
||||
|
||||
=item --password
|
||||
|
||||
short form: -p; type: string
|
||||
|
@@ -9,7 +9,7 @@ BEGIN {
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More tests => 16;
|
||||
use Test::More tests => 17;
|
||||
|
||||
use PerconaTest;
|
||||
use Sandbox;
|
||||
@@ -147,6 +147,16 @@ like(
|
||||
'--query-id'
|
||||
);
|
||||
|
||||
# --json option
|
||||
$output = output(
|
||||
sub { pt_kill::main(@args, "$trunk/t/lib/samples/pl/recset011.txt", qw(--match-all --print --json --json-fields key:value)); }
|
||||
);
|
||||
like(
|
||||
$output,
|
||||
qr/\{"Command"\:"Query","Db"\:"db","Digest"\:"69962191E64980E6","Host"\:"127\.0\.0\.1\:3306","Id"\:"4","Info"\:"\\\/\* fruit\=orange \*\\\/ select 1 from fuits;","Kill_Error"\:"","Reason"\:"","State"\:"statistics","Time"\:"6","Timestamp"\:".*","User"\:"foo","key"\:"value"\}/,
|
||||
'--json'
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Live tests.
|
||||
# #############################################################################
|
||||
|
Reference in New Issue
Block a user