From 1315c5b8d62ca72bb4637337d1afff08f013e5b7 Mon Sep 17 00:00:00 2001 From: pmoranga Date: Wed, 18 Oct 2017 13:04:38 +0200 Subject: [PATCH] Fix call to json node when deeper that 1 level, also added support for wildcard in the middle of the xpath. --- README.md | 5 ++++- check_json.pl | 62 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 480a1ea..d45373a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ check_json -u|--url -a|--attribute [ -c|--critical Example: ``` -./check_json.pl --url http://192.168.5.10:9332/local_stats --attribute '{shares}->{dead_shares}' --warning :5 --critical :10 --perfvars '{shares}->{dead_shares},{shares}->{live_shares},{clients}->{clients_connected}' +./check_json.pl --url http://192.168.5.10:9332/local_stats --attribute '{shares}->{dead_shares}' --warning :5 --critical :10 --perfvars '{shares}->{dead_shares},{shares}->{live_shares},{clients}->{clients_connected}' -o '{shares}->*->{name},' ``` Result: @@ -22,9 +22,12 @@ Result: Check JSON status API OK - dead_shares: 2, live_shares: 12, clients_connected: 234 | dead_shares=2;5;10 live_shares=12 clients_connected=234 ``` +Outputvars: It accepts also wildcards in the middle of the tree. + Requirements ============ Perl JSON package * Debian / Ubuntu : libjson-perl libnagios-plugin-perl libwww-perl +* RHEL / CentOS : perl-Nagios-Plugin perl-JSON perl-HTTP-Parser diff --git a/check_json.pl b/check_json.pl index 55e96ef..d8a43e9 100755 --- a/check_json.pl +++ b/check_json.pl @@ -116,13 +116,20 @@ $np->add_arg( $np->getopts; if ($np->opts->verbose) { (print Dumper ($np))}; +if ($np->opts->hattrib and not $np->opts->hcon) { + $np->nagios_exit(UNKNOWN,"Additional Header attribute provided without Additional Header content"); +} +if ( not $np->opts->hattrib and $np->opts->hcon) { + $np->nagios_exit(UNKNOWN,"Additional Header content provided without Additional Header attribule"); +} + ## GET URL my $ua = LWP::UserAgent->new; $ua->env_proxy; $ua->agent('check_json/0.5'); $ua->default_header('Accept' => 'application/json'); -$ua->default_header($np->opts->hattrib => $np->opts->hcon); +$ua->default_header($np->opts->hattrib => $np->opts->hcon) if ( $np->opts->hattrib and $np->opts->hcon ); $ua->protocols_allowed( [ 'http', 'https'] ); $ua->parse_head(0); $ua->timeout($np->opts->timeout); @@ -153,8 +160,14 @@ my $json_response = decode_json($response->content); if ($np->opts->verbose) { (print Dumper ($json_response))}; my @attributes = split(',', $np->opts->attributes); -my @warning = split(',', $np->opts->warning); -my @critical = split(',', $np->opts->critical); +my @warning; +if ($np->opts->warning) { + @warning = split(',', $np->opts->warning); +} +my @critical; +if ($np->opts->critical) { + @critical = split(',', $np->opts->critical); +} my @divisor = $np->opts->divisor ? split(',',$np->opts->divisor) : () ; my %attributes = map { $attributes[$_] => { warning => $warning[$_] , critical => $critical[$_], divisor => ($divisor[$_] or 0) } } 0..$#attributes; @@ -166,7 +179,7 @@ my $resultTmp; foreach my $attribute (sort keys %attributes){ my $check_value; my $check_value_str = '$check_value = $json_response->'.$attribute; - + if ($np->opts->verbose) { (print Dumper ($check_value_str))}; eval $check_value_str; @@ -232,7 +245,7 @@ if ($np->opts->perfvars) { # make label ascii compatible $label =~ s/[^a-zA-Z0-9_-]//g ; my $perf_value; - $perf_value = $json_response->{$key}; + $perf_value = eval('$json_response->'.$key); if ($np->opts->verbose) { print Dumper ("JSON key: ".$label.", JSON val: " . $perf_value) }; if ( defined($perf_value) ) { # add threshold if attribute option matches key @@ -248,26 +261,57 @@ if ($np->opts->perfvars) { $np->add_perfdata( label => lc $label, value => $perf_value, - ); + ); } } } } +sub process_wildcard{ + my($key,$json_response) = @_; + + if ($np->opts->verbose) { (print "DEBUG: handling wildcard on key ". $key. "\n"); } + my @parts; + my @result; + if ($key !~ /\*/) { + $Data::Dumper::Terse = 1; + $Data::Dumper::Indent = 0; + if ($np->opts->verbose) { (print "DEBUG: Now checking: ". $key. " against: ". Dumper($json_response)."\n")}; + my $output_value = Dumper(eval('$json_response->'.$key)); + $Data::Dumper::Terse = 0; + $Data::Dumper::Indent = 1; + return $output_value; + } else { + @parts = split(/->[\{\[]?\*[\}\]]?->/,$key,2); + my $part1 = $parts[0]; + my $part2 = $parts[1]; + if ($np->opts->verbose) { (print "DEBUG: processing first part before wildcard: ". $part1 . "\n"); } + my $c = eval('$json_response->'.$part1); + return if (! $c); + if ($np->opts->verbose) { (print "DEBUG: process_wildcard: Fount childs: ".Dumper($c)."\n")}; + foreach my $v (values($c)){ + my $r = process_wildcard($part2,$v); + push(@result,$r) if $r; + } + } + return @result; +} + # output some vars in message if ($np->opts->outputvars) { foreach my $key ($np->opts->outputvars eq '*' ? map { "{$_}"} sort keys %$json_response : split(',', $np->opts->outputvars)) { # use last element of key as label my $label = (split('->', $key))[-1]; - # make label ascii compatible + # make label ascii compatible i.e. remove the { and } $label =~ s/[^a-zA-Z0-9_-]//g; my $output_value; - $output_value = $json_response->{$key}; + ## Handle case of wildcard in the middle of the tree: {data}->*->{description} + $output_value = join(", ",process_wildcard($key,$json_response)); push(@statusmsg, "$label: $output_value"); } } $np->nagios_exit( return_code => $result, - message => join(', ', @statusmsg), + message => join('; ', @statusmsg), );