Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

+ perf_elastic_search.pl for ES stats to graphite

This script can actually output in grpahite or cacti format and records
basic statistics collected from ElasticSearch itself.
  • Loading branch information...
commit 799533315a851a129deb430b3fb7938e922a3d94 1 parent 8b059f1
@reyjrar authored
Showing with 259 additions and 0 deletions.
  1. +259 −0 bin/perf_elastic_search.pl
View
259 bin/perf_elastic_search.pl
@@ -0,0 +1,259 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+BEGIN {
+ delete $ENV{$_} for qw(http_proxy https_proxy);
+};
+
+use JSON;
+use LWP::Simple qw( get );
+use IO::Socket::INET;
+use Getopt::Long;
+use Pod::Usage;
+
+#------------------------------------------------------------------------#
+# Argument Collection
+my %opt;
+GetOptions(\%opt,
+ 'format:s',
+ 'carbon-server:s',
+ 'carbon-port:i',
+ 'host=s',
+ 'help|h',
+ 'manual|m',
+ 'verbose|v',
+ 'debug|d',
+);
+
+#------------------------------------------------------------------------#
+# Documentations!
+pod2usage(1) if $opt{help};
+pod2usage(-exitstatus => 0, -verbose => 2) if $opt{manual};
+
+#------------------------------------------------------------------------#
+# Argument Sanitazation
+my %_formats = (
+ carbon => 'graphite',
+ graphite => 'graphite',
+ cacti => 'cacti',
+);
+ # Force graphite if carbon-server specified
+if( exists $opt{'carbon-server'} and length $opt{'carbon-server'} ) {
+ $opt{format} = 'graphite';
+}
+# Validate Format
+if( exists $opt{format} and length $opt{format} ) {
+ if( exists $_formats{$opt{format}} ) {
+ $opt{format} = $_formats{$opt{format}};
+ }
+ else {
+ delete $opt{format};
+ }
+}
+# Merge options into config
+my %cfg = (
+ format => 'graphite',
+ %opt,
+);
+
+#------------------------------------------------------------------------#
+# Format Routines
+my $time = time;
+my %_formatter = (
+ cacti => sub {
+ local $_ = shift;
+ s/\./_/g;
+ s/\s/:/;
+ s/$/\n/;
+ $_;
+ },
+ graphite => sub {
+ local $_ = shift;
+ s/^/es.$cfg{host}./;
+ s/$/ $time\n/;
+ $_;
+ },
+);
+
+#------------------------------------------------------------------------#
+# Carbon Socket Creation
+my $carbon_socket;
+if( exists $cfg{'carbon-server'} and length $cfg{'carbon-server'} ) {
+ $carbon_socket = IO::Socket::INET->new(
+ PeerAddr => $cfg{'carbon-server'},
+ PeerPort => $cfg{'carbon-port'} || 2003,
+ Proto => 'tcp',
+ );
+ die "unable to connect to carbon server: $!" unless defined $carbon_socket && $carbon_socket->connected;
+}
+
+#------------------------------------------------------------------------#
+# Collect and Decode the Cluster Statistics
+my $json = get("http://search-02:9200/_cluster/nodes/stats");
+my $data = JSON->new->decode( $json );
+my $node_data = parse_stats( $data );
+
+#------------------------------------------------------------------------#
+# Send output to appropriate channels
+foreach my $stat ( @{ $node_data } ) {
+ my $output = format_output( $stat );
+ if( defined $carbon_socket && $carbon_socket->connected) {
+ $carbon_socket->send( $output );
+ print STDERR $output if $cfg{verbose};
+ }
+ else {
+ print $output;
+ }
+}
+
+
+#------------------------------------------------------------------------#
+# Generate Node Statistics Hash
+sub parse_stats {
+ my $data = shift;
+
+ my $node_id;
+ my @nodes;
+ foreach my $id (keys %{ $data->{nodes} }) {
+ if( $data->{nodes}{$id}{name} eq $cfg{host} ) {
+ $node_id = $id;
+ last;
+ }
+ else {
+ push @nodes, $data->{nodes}{$id}{name};
+ }
+ }
+ die "no information found for $cfg{host}, nodes found: ", join(', ', @nodes), "\n" unless exists $data->{nodes}{$node_id};
+ my $node = $data->{nodes}{$node_id};
+
+ my @stats = ();
+ # Transport Details
+ push @stats,
+ "transport.rx_bytes $node->{transport}{rx_size_in_bytes}",
+ "transport.rx_count $node->{transport}{rx_count}",
+ "transport.tx_bytes $node->{transport}{tx_size_in_bytes}",
+ "transport.tx_count $node->{transport}{tx_count}",
+ "transport.server_open $node->{transport}{server_open}",
+ ;
+ # HTTP Details
+ push @stats,
+ "http.open $node->{http}{current_open}",
+ "http.total $node->{http}{total_opened}",
+ ;
+ # JVM Garbage Collectors;
+ push @stats,
+ "jvm.gc.count $node->{jvm}{gc}{collection_count}",
+ "jvm.gc.time_ms $node->{jvm}{gc}{collection_time_in_millis}",
+ ;
+ foreach my $collector (keys %{ $node->{jvm}{gc}{collectors} } ) {
+ my $col = $node->{jvm}{gc}{collectors}{$collector};
+ my $prefix = "jvm.gc.collector.$collector";
+ push @stats,
+ "$prefix.count $col->{collection_count}",
+ "$prefix.time_ms $col->{collection_time_in_millis}",
+ ;
+ }
+ # JVM Memory Usage
+ my %_mem = ( used_bytes => 'used_in_bytes', committed_bytes => 'committed_in_bytes' );
+ foreach my $heap (qw(heap non_heap)) {
+ while( my ($gm,$em) = each %_mem ) {
+ my $val = $node->{jvm}{mem}{"${heap}_${em}"};
+ push @stats,
+ "jvm.mem.$heap.$gm $val";
+ }
+ }
+ # JVM Threads
+ push @stats,
+ "jvm.threads $node->{jvm}{threads}{count}",
+ ;
+ # OS Information
+ push @stats,
+ "process.openfds $node->{process}{open_file_descriptors}",
+ ;
+ return \@stats;
+}
+
+#------------------------------------------------------------------------#
+# Formatters
+sub format_output {
+ my $line = shift;
+ if( exists $_formatter{$cfg{format}} ) {
+ return $_formatter{$cfg{format}}->( $line );
+ }
+ else {
+ warn "call to undefined formatter($cfg{format})";
+ return "$line\n";
+ }
+}
+
+
+__END__
+
+=head1 NAME
+
+perf_elastic_search.pl - Check Elastic Search Performance
+
+=head1 SYNOPSIS
+
+perf_elastic_search.pl --format=graphite --host [host] [options]
+
+Options:
+
+ --help print help
+ --manual print full manual
+ --host|-H Host to poll for statistics
+ --format stats Format (graphite or cacti) (Default: graphite)
+ --carbon-server Send Graphite stats to Carbon Server (Automatically sets format=graphite)
+ --carbon-port Port for to use for Carbon (Default: 2003)
+ --verbose Send additional messages to STDERR
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<help>
+
+Print this message and exit
+
+=item B<manual>
+
+Print this message and exit
+
+=item B<host>
+
+Required, the host to check
+
+=item B<format>
+
+stats format:
+
+ graphite Use format for graphite/carbon (default)
+ cacti For use with Cacti
+
+=item B<carbon-server>
+
+Send stats to the carbon server specified. This automatically forces --format=graphite
+and does not produce stats on STDOUT
+
+=item B<carbon-port>
+
+Use this port for the carbon server, useless without --carbon-server
+
+=item B<verbose>
+
+Verbose stats, to not interfere with cacti, output goes to STDERR
+
+=back
+
+=head1 DESCRIPTION
+
+This is a plugin to poll elasticsearch for performance data and stats it in a relevant
+format for your monitoring infrastructure.
+
+=head1 AUTHOR
+
+Brad Lhotsky <brad.lhotsky@gmail.com>
+
+=cut
Please sign in to comment.
Something went wrong with that request. Please try again.