#!/usr/bin/env perl =head1 NAME hhvm_ - Munin plugin to monitor HHVM. =head1 LICENCE This source file is subject to the Open Software License (OSL 3.0) Which is available through the world-wide-web at this URL: http://opensource.org/licenses/osl-3.0.php Copyright (c) 2014 Jeroen Vermeulen - http://www.jeroenvermeulen.eu =head1 USAGE - You need HHVM 3.0 or greater. - The HHVM AdminServer needs to be locally accessible via HTTP. - Since version 3.0 HHVM has no longer a built-in webserver. Not even for the AdminServer. - You will need to configure a special HHVM Admin webserver like Apache or Nginx, and connect it via FastCGI to the HHVM AdminServer Port. More info below. - You can use the HHVM Config setting "AdminServer.Port" or ini variable "hhvm.admin_server.port" to choose that port. For example 8080. - Copy this file to "/usr/share/munin/plugins/hhvm_". - Create a symlink in "/etc/munin/plugins" - By default this script will try to connect to a webserver on 127.0.0.1 port 8081. - You can make it connect to another IP and port by naming the symlink "hhvm_[IP]_[PORT]", for example hhvm_11.22.33.44_8081 - You can also use the plugin config to set "env.host" and "env.port" =head1 ADMIN WEBSERVER CONFIG =head2 NGINX CONFIG server { listen 127.0.0.1:8081 default; location ~ { fastcgi_pass 127.0.0.1:8080; include fastcgi_params; } } =head2 APACHE 2.2 CONFIG FastCgiExternalServer /var/run/hhvm_admin.fcgi -host 127.0.0.1:8080 Listen 127.0.0.1:8081 Alias /check-health /var/run/hhvm_admin.fcgi Alias /status.json /var/run/hhvm_admin.fcgi Alias / /var/run/hhvm_admin.fcgi =head2 APACHE 2.4 CONFIG Listen 127.0.0.1:8081 ProxyPass / fcgi://127.0.0.1:8080/ =cut use warnings; use strict; # use lib $ENV{'MUNIN_LIBDIR'}; use Munin::Plugin; use LWP::Simple; use JSON::PP; sub getJson( $ ); my $script = $0; my $host = '127.0.0.1'; my $port = 8081; my $name = undef; if ( $script =~ /\bhhvm_([a-z0-9\-\.]+)(?:_(\d+))?$/ ) { $host = $1; $name = $host; if ( $2 ) { $port = int( $2 ); } } $host = defined $ENV{'host'} ? $ENV{'host'} : $host; $port = defined $ENV{'port'} ? $ENV{'port'} : $port; $name = defined $name ? $name : $host.':'.$port; my $graphName = $name; $graphName =~ s/[^\w]+/_/g; if ( exists $ARGV[0] && 'config' eq $ARGV[0] ) { print <{'status'}->{'threads'} } ) ); printf( "load.value %d\n", $health->{'load'} ); printf( "queued.value %d\n", $health->{'queued'} ); print "\n"; printf( "multigraph hhvm_%s_sizes\n", $graphName ); printf( "hhbc-roarena-capac.value %d\n", $health->{'hhbc-roarena-capac'} ); printf( "tc-hotsize.value %d\n", $health->{'tc-hotsize'} ); printf( "tc-size.value %d\n", $health->{'tc-size'} ); printf( "tc-profsize.value %d\n", $health->{'tc-profsize'} ); printf( "tc-coldsize.value %d\n", $health->{'tc-coldsize'} ); printf( "tc-frozensize.value %d\n", $health->{'tc-frozensize'} ); printf( "rds.value %d\n", $health->{'rds'} ); printf( "units.value %d\n", $health->{'units'} ); printf( "funcs.value %d\n", $health->{'funcs'} ); } exit 0; sub getJson( $ ) { my ( $url ) = @_; my $json = get( $url ); if ( ! $json ) { die( sprintf( "Could not get json from '%s'.", $url ) ); } my $data = decode_json( $json ); if ( ! $data || 'HASH' ne ref($data) ) { die( sprintf( "Could not decode json from '%s'.", $url ) ); } return $data; }