Last active
January 5, 2023 06:08
-
-
Save serverwentdown/b92e8fc688e24f1b54df822be770bb5b to your computer and use it in GitHub Desktop.
Munin Sidekiq plugin. Requires `perl-redis`. Install as `sidekiq_APP_NAME`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
=head1 NAME | |
sidekiq - Get Sidekiq queue statistics from a Redis node | |
=head1 APPLICABLE SYSTEMS | |
Any Redis host with a Sidekiq application | |
=head1 CONFIGURATION | |
[sidekiq_redis1] | |
env.server 127.0.0.1:6379 | |
env.key_prefix namespace: | |
[sidekiq_redis2] | |
env.server 127.0.0.2:6379 | |
env.password password | |
env.key_prefix other-namespace: | |
env.database 1 | |
=head1 MAGIC MARKERS | |
#%# family=auto | |
#%# capabilities=autoconf | |
=head1 BUGS | |
None known | |
=head1 LICENSE | |
This program is free software; you can redistribute it and/or | |
modify it under the terms of the GNU General Public License | |
as published by the Free Software Foundation; version 2 dated June, | |
1991. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program; if not, write to the Free Software | |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
=cut | |
use warnings; | |
use strict; | |
use Munin::Plugin; | |
use Redis; | |
# Check that multigraph is available | |
need_multigraph(); | |
# Get the script name | |
my $plugin_name = $Munin::Plugin::me; | |
# Get the instance name | |
my $name; | |
if ($plugin_name =~ /sidekiq_(.+)*$/) { | |
$name = $1; | |
} else { | |
exit 1; | |
} | |
# Redis connection configuration | |
my $key_prefix = $ENV{'key_prefix'} || ''; | |
sub sscan_all { | |
my ($redis, $key) = @_; | |
my $cursor = 0; | |
my @elements = (); | |
do { | |
my @result = $redis->sscan($key, $cursor); | |
$cursor = $result[0]; | |
push(@elements, @{$result[1]}); | |
} while ($cursor != 0); | |
return @elements; | |
} | |
sub redis_connect { | |
# | |
# Set up connection | |
# | |
my $redis = Redis->new( | |
server => $ENV{'server'} || '127.0.0.1:6379', | |
password => $ENV{'password'} || undef, | |
); | |
$redis->select($ENV{'database'} || 0); | |
return $redis; | |
} | |
if (defined($ARGV[0])) { | |
if ($ARGV[0] eq 'autoconf') { | |
# | |
# Test connection | |
# | |
my $redis_test = redis_connect(); | |
print "yes\n"; | |
$redis_test->quit(); | |
exit 0; | |
} | |
if ($ARGV[0] eq 'config') { | |
my $redis = redis_connect(); | |
# | |
# List all queues | |
# | |
my @queues = sscan_all($redis, "${key_prefix}queues"); | |
print "multigraph ${plugin_name}_queues\n"; | |
foreach my $queue (@queues) { | |
my $field = clean_fieldname($queue); | |
print "${field}.label ${queue}\n"; | |
} | |
# Queue breakdown graph | |
print "multigraph ${plugin_name}_queues\n"; | |
print "graph_title Sidekiq task queues ($name)\n"; | |
print "graph_args --base 1000 --lower-limit 0\n"; | |
print "graph_vlabel tasks in queue\n"; | |
print "graph_scale no\n"; | |
print "graph_category sidekiq\n"; | |
#print "graph_total Total\n"; | |
# Queue graph | |
print "multigraph ${plugin_name}_queue\n"; | |
print "graph_title Sidekiq task activity ($name)\n"; | |
print "graph_args --base 1000 --lower-limit 0\n"; | |
print "graph_vlabel tasks in status\n"; | |
print "graph_scale no\n"; | |
print "graph_category sidekiq\n"; | |
#print "graph_total Total\n"; | |
print "queue.label Enqueued\n"; | |
print "queue.info Total number of tasks waiting in queues\n"; | |
print "busy.label Busy\n"; | |
print "busy.info Tasks currently being processed\n"; | |
print "schedule.label Scheduled\n"; | |
print "schedule.info Tasks to be run in the future\n"; | |
print "retry.label Retries\n"; | |
print "retry.info Failed tasks that will be retried in the future\n"; | |
print "dead.label Dead\n"; | |
print "dead.info Failed tasks that will not be retried\n"; | |
# Counter graph | |
print "multigraph ${plugin_name}_count\n"; | |
print "graph_title Sidekiq processed and failed tasks ($name)\n"; | |
print "graph_args --base 1000 --lower-limit 0\n"; | |
print "graph_vlabel tasks / minute\n"; | |
print "graph_scale no\n"; | |
print "graph_category sidekiq\n"; | |
print "graph_period minute\n"; | |
print "processed.type DERIVE\n"; | |
print "processed.min 0\n"; | |
print "processed.label Processed\n"; | |
print "processed.info Tasks sucessfully completed\n"; | |
print "failed.type DERIVE\n"; | |
print "failed.min 0\n"; | |
print "failed.label Failed\n"; | |
print "failed.info Errors raised by failed jobs\n"; | |
exit 0; | |
} | |
} | |
my $redis = redis_connect(); | |
# | |
# Sum the length of all queues, while also doing a per-queue breakdown | |
# | |
my @queues = sscan_all($redis, "${key_prefix}queues"); | |
my $count_queue = 0; | |
print "multigraph ${plugin_name}_queues\n"; | |
foreach my $queue (@queues) { | |
$redis->llen("${key_prefix}queue:${queue}", sub { | |
my $field = clean_fieldname($queue); | |
print "${field}.value $_[0]\n"; | |
$count_queue += $_[0]; | |
}); | |
} | |
$redis->wait_all_responses; | |
# | |
# Sum the length of all processes | |
# | |
my @processes = sscan_all($redis, "${key_prefix}processes"); | |
my $count_busy = 0; | |
foreach my $process (@processes) { | |
$redis->hget("${key_prefix}${process}", "busy", sub { | |
$count_busy += $_[0]; | |
}); | |
} | |
$redis->wait_all_responses; | |
# | |
# Read length of schedule, retry and dead queues | |
# | |
my $count_schedule = $redis->zcard("${key_prefix}schedule"); | |
my $count_retry = $redis->zcard("${key_prefix}retry"); | |
my $count_dead = $redis->zcard("${key_prefix}dead"); | |
# | |
# Render queue graph | |
# | |
print "multigraph ${plugin_name}_queue\n"; | |
print "queue.value $count_queue\n"; | |
print "busy.value $count_busy\n"; | |
print "schedule.value $count_schedule\n"; | |
print "retry.value $count_retry\n"; | |
print "dead.value $count_dead\n"; | |
# | |
# Read processed and failed counter | |
# | |
my $count_processed = $redis->get("${key_prefix}stat:processed"); | |
my $count_failed = $redis->get("${key_prefix}stat:failed"); | |
# | |
# Render counter graph | |
# | |
print "multigraph ${plugin_name}_count\n"; | |
print "processed.value $count_processed\n"; | |
print "failed.value $count_failed\n"; | |
exit 0; | |
# vim: ft=perl ai ts=4 sw=4 et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment