mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
999f43474e
Normal rate monitoring should be preformed on parent HTB classes/queues. SFQ classes are dynamically allocated (as queues fill) and given random names and this messes up charts.
173 lines
4.7 KiB
Perl
Executable File
173 lines
4.7 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
# -*- perl -*-
|
|
# Wildcard plugin to monitor QoS queues.
|
|
#
|
|
# Requirements:
|
|
# - tc program installed and in path
|
|
#
|
|
# Parameters supported:
|
|
#
|
|
# config
|
|
# autoconf
|
|
# suggest
|
|
#
|
|
# Configurable variables
|
|
#
|
|
# tc - Override default program
|
|
# ignore_queue<n> - Queue with handle <n> not be plotted
|
|
# label_name<n> - Queue with handle <n> as defined label
|
|
# update_rate - Custom update_rate, to be used with async
|
|
# graph_data_size - Custom graph_data_size, to be used with async & custom update_rate
|
|
#
|
|
# Magic markers:
|
|
#%# family=manual
|
|
#%# capabilities=autoconf suggest
|
|
|
|
use strict;
|
|
|
|
my $TC = $ENV{'tc'} || 'tc';
|
|
|
|
if ($ARGV[0] and $ARGV[0] eq 'suggest') {
|
|
my $text = `egrep '^ *(eth|wlan|ath|ra)[0-9]+:' /proc/net/dev | cut -f1 -d:`;
|
|
print $text;
|
|
exit;
|
|
}
|
|
|
|
$0 =~ /qos_(.+)*$/;
|
|
my $IFACE = $1;
|
|
exit 2 unless defined $IFACE;
|
|
|
|
if ( exists $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
|
|
# Now see if "tc" can run
|
|
my $text = `$TC qdisc show dev $IFACE`;
|
|
if ($?) {
|
|
if ($? == -1) {
|
|
print "no (program $TC not found)\n";
|
|
} else {
|
|
print "no (program $TC died)\n";
|
|
}
|
|
exit 1;
|
|
}
|
|
print "yes\n";
|
|
exit 0;
|
|
}
|
|
|
|
my %queues;
|
|
my $qdisc;
|
|
my $queue;
|
|
my $handle;
|
|
my $one;
|
|
my $sent;
|
|
my $count;
|
|
my $haschild;
|
|
|
|
#open(TEXT, "$TC -s qdisc show dev $IFACE|");
|
|
#while (! eof(TEXT)) {
|
|
# ($qdisc, $queue, $handle) = split(" ", <TEXT>);
|
|
# if ($qdisc eq "backlog") {
|
|
# ($qdisc, $queue, $handle) = split(" ", <TEXT>);
|
|
# }
|
|
# ($one, $sent) = split(" ", <TEXT>);
|
|
# $handle =~ s/://;
|
|
# $queues{$handle} = {
|
|
# queue => $queue,
|
|
# handle => $handle,
|
|
# sent => $sent
|
|
# };
|
|
#}
|
|
|
|
my @class = `$TC -s class show dev $IFACE`;
|
|
my( $name, $id1, $id2, $type, $rate, $parent);
|
|
for( my $x = 0; $x < scalar(@class); $x++ ) {
|
|
if($class[$x] =~ m/^class/i ) {
|
|
( $name, $id1, $id2, $type, $parent) = ( $class[$x] =~ m/^class\s+(\w+)\s+(\d+):(\d+)\s+(\w+)\s([^\s]+)/i );
|
|
if($type && $type eq "parent") {
|
|
$x++;
|
|
( $rate ) = ( $class[$x] =~ m/Sent\s+(\d+)\s+/i );
|
|
$handle = "$name"."${id1}_${id2}";
|
|
$queues{$handle} = {
|
|
queue => $name,
|
|
handle => "${id1}_${id2}",
|
|
id => "${id1}:${id2}",
|
|
sent => $rate,
|
|
parent => $parent
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( exists $ARGV[0] and $ARGV[0] eq 'config' ) {
|
|
print "graph_title QoS queue on $IFACE\n";
|
|
print "graph_args --base 1000\n";
|
|
print "graph_vlabel bits per \${graph_period}\n";
|
|
print "graph_category network\n";
|
|
print "graph_info This graph shows the QoS queue of the $IFACE network interface.\n";
|
|
print "update_rate $ENV{update_rate}\n" if $ENV{update_rate};
|
|
print "graph_data_size $ENV{graph_data_size}\n" if $ENV{graph_data_size};
|
|
print "graph_order ";
|
|
foreach my $key (sort by_handle keys %queues) {
|
|
$haschild = 0;
|
|
foreach my $key2 (sort by_handle keys %queues) {
|
|
if($queues{$key}->{id} eq $queues{$key2}->{parent}) {
|
|
$haschild = 1;
|
|
last;
|
|
}
|
|
}
|
|
if($haschild == 1) {
|
|
$queues{$key}->{leaf} = 0;
|
|
next;
|
|
}
|
|
$queues{$key}->{leaf} = 1;
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, " ";
|
|
}
|
|
print "\n";
|
|
$count = 0;
|
|
foreach my $key (sort by_handle keys %queues) {
|
|
if($queues{$key}->{leaf} == 0) { next; }
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".label ";
|
|
if (exists $ENV{"label_name$queues{$key}->{handle}"}) {
|
|
print $ENV{"label_name$queues{$key}->{handle}"};
|
|
} else {
|
|
print $queues{$key}->{queue},$queues{$key}->{handle};
|
|
}
|
|
print "\n";
|
|
if (exists $ENV{"max"}) {
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".max ",$ENV{"max"},"\n";
|
|
} elsif (exists $ENV{"max$queues{$key}->{handle}"}) {
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".max ",$ENV{"max$queues{$key}->{handle}"},"\n";
|
|
}
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".type COUNTER\n";
|
|
if($count == 0){
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".draw AREA\n";
|
|
} else {
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".draw STACK\n";
|
|
}
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".cdef ", $queues{$key}->{queue},$queues{$key}->{handle}, ",8,*\n";
|
|
if (exists $ENV{"ignore_queue$queues{$key}->{handle}"}){
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".graph no\n" ;
|
|
} else {
|
|
$count++;
|
|
}
|
|
}
|
|
exit 0;
|
|
}
|
|
|
|
sub by_handle {
|
|
return $a cmp $b;
|
|
}
|
|
|
|
foreach my $key (sort by_handle keys %queues) {
|
|
next if $key =~ /sfq/i;
|
|
$haschild = 0;
|
|
foreach my $key2 (sort by_handle keys %queues) {
|
|
if($queues{$key}->{id} eq $queues{$key2}->{parent}) {
|
|
$haschild = 1;
|
|
last;
|
|
}
|
|
}
|
|
if($haschild == 1) { next; }
|
|
print $queues{$key}->{queue},$queues{$key}->{handle}, ".value ",$queues{$key}->{sent}, "\n";
|
|
}
|
|
#
|
|
# vim:syntax=perl
|