From d9533d6190385d36038e84f5378bcefbfd74cdb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:22:04 -0700 Subject: [PATCH 01/11] snmp__apc: initial import. This is a simple plugin that makes it possible to monitor the amp drain on APC's PDUs. --- plugins/snmp/snmp__apc | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 plugins/snmp/snmp__apc diff --git a/plugins/snmp/snmp__apc b/plugins/snmp/snmp__apc new file mode 100755 index 00000000..0e9cca13 --- /dev/null +++ b/plugins/snmp/snmp__apc @@ -0,0 +1,104 @@ +#!/usr/bin/perl -w +# -*- perl -*- + +=head1 NAME + +snmp__apc - SNMP plugin to monitor APC metered and managed PDUs. + +=head1 APPLICABLE SYSTEMS + +This has been tested with AP7830 metered PDUs, but should work with +most other PDUs that follow the PowerNet-MIB published by APC. + +=head1 CONFIGURATION + +Most likely you want to use SNMP version 3 to connect to the PDUs, as +they don't support version 2 (only 1 or 3). This can be achieved by +using: + + [snmp_*_apc] + env.version 3 + +Please see 'perldoc Munin::Plugin::SNMP' for further configuration +information. + +=head1 MIB INFORMATION + +This plugin requires the PowerNet-MIB from APC. + +=head1 MAGIC MARKERS + + #%# family=snmpauto + #%# capabilities=snmpconf + +=head1 BUGS + +None known. + +=head1 AUTHOR + +Copyright (C) 2012 Diego Elio Pettenò. + +=head1 LICENSE + +GPLv2 + +=cut + +use strict; +use Munin::Plugin; +use Munin::Plugin::SNMP; + +# This is the data we care about: +# PowerNet-MIB::rPDUIdentModelNumber.0 -> .1.3.6.1.4.1.318.1.1.12.1.5.0 +# PowerNet-MIB::rPDUIdentSerialNumber.0 -> .1.3.6.1.4.1.318.1.1.12.1.6.0 +# PowerNet-MIB::rPDULoadDevNumPhases.0 -> .1.3.6.1.4.1.318.1.1.12.2.1.2.0 +# PowerNet-MIB::rPDULoadPhaseConfigNearOverloadThreshold.phase1 -> .1.3.6.1.4.1.318.1.1.12.2.2.1.1.3.1 +# PowerNet-MIB::rPDULoadPhaseConfigOverloadThreshold.phase1 -> .1.3.6.1.4.1.318.1.1.12.2.2.1.1.4.1 +# PowerNet-MIB::rPDULoadStatusLoad.1 -> .1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.1 + +if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") { + print "index 1.3.6.1.4.1.318.1.1.12.2.2.1.1.1.\n"; + print "require 1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.[1-9]"; # Load +} + +my $oidModelNo = '1.3.6.1.4.1.318.1.1.12.1.5.0'; +my $oidSerialNo = '1.3.6.1.4.1.318.1.1.12.1.6.0'; +my $oidNumPhases = '1.3.6.1.4.1.318.1.1.12.2.1.2.0'; +my $oidNearOverloadThreshold = '1.3.6.1.4.1.318.1.1.12.2.2.1.1.3.'; +my $oidOverloadThreshold = '1.3.6.1.4.1.318.1.1.12.2.2.1.1.4.'; +my $oidPhaseLoad = '1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.'; + +# SNMP needed for both config and fetch. +my $session = Munin::Plugin::SNMP->session(); +my $numPhases = $session->get_single($oidNumPhases); + +if ($ARGV[0] and $ARGV[0] eq "config") { + my ($host,undef,$version) = Munin::Plugin::SNMP->config_session(); + + print "host_name $host\n" unless $host eq 'localhost'; + + my $modelNo = $session->get_single($oidModelNo); + my $serialNo = $session->get_single($oidSerialNo); + + print "graph_title PDU $modelNo ($serialNo)\n"; + print "graph_vlabel Current drained (A)\n"; + print "graph_category Sensors\n"; + + for( my $phaseIndex = 1; $phaseIndex <= $numPhases; $phaseIndex++ ) { + my $nearOverloadThreshold = $session->get_single($oidNearOverloadThreshold . $phaseIndex); + my $overloadThreshold = $session->get_single($oidOverloadThreshold . $phaseIndex); + print "phase$phaseIndex.label Phase $phaseIndex load\n"; + print "phase$phaseIndex.warning $nearOverloadThreshold\n"; + print "phase$phaseIndex.critical $overloadThreshold\n"; + print "phase$phaseIndex.min 0\n"; + } + + exit 0; +} + +for( my $phaseIndex = 1; $phaseIndex <= $numPhases; $phaseIndex++ ) { + # the phaseLoad value is defined in dA — we might as well convert to full Amperes + my $phaseLoad = $session->get_single($oidPhaseLoad . $phaseIndex) / 10.0; + print "phase$phaseIndex.value $phaseLoad\n"; +} From 2fc9c2400b798bacc99fbec051252f8e8d763c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:27:04 -0700 Subject: [PATCH 02/11] ups: remove two older PDU plugins. My plugin uses the same SNMP framework as the official plugins in munin; these use either sh and net-snmp commands, or Net::SNMP directly, and neither seems to be generic enough. --- plugins/ups/apc_pdu_load | 79 ------------------------ plugins/ups/snmp__apcpdu | 128 --------------------------------------- 2 files changed, 207 deletions(-) delete mode 100755 plugins/ups/apc_pdu_load delete mode 100755 plugins/ups/snmp__apcpdu diff --git a/plugins/ups/apc_pdu_load b/plugins/ups/apc_pdu_load deleted file mode 100755 index 111cd037..00000000 --- a/plugins/ups/apc_pdu_load +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# -*- sh -*- - -: << =cut -=head1 NAME - -apc_pdu_load = plugin to show load in Ampere for an apc pdu - -=head1 NOTES - -This is a Munin plugin that shows the load in Ampere for an apc pdu - -=head1 AUTHOR - -Contributed by Alexander Swen - -=head1 LICENSE - -Copyright (c) 2011 Alexander Swen - -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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -=head1 CONFIGURATION -[apc_pdu_load] -env.pdu -env.snmp_community public -env.snmp_version 1 -env.load_oid .1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.1 - -=head1 MAGIC MARKERS - - #%# family=auto - #%# capabilities=autoconf - -=cut - -snmp_version=${snmp_version:-1} -snmp_community=${snmp_community:-public} -load_oid=${load_iod:-.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.1} - -#. $MUNIN_LIBDIR/plugins/plugin.sh - -if [ -z "${pdu}" ]; then - echo "pdu variable not set" - exit 1 -fi - -[ -n "$1" ] && case $1 in - autoconf) - echo yes - exit 0 - ;; - config) - cat << EOF -graph_title PDU load ${pdu} -graph_args -l 0 -graph_scale yes -graph_vlabel Ampere -graph_category ups -load.label load -EOF - exit 0 - ;; -esac - -/usr/bin/snmpget -v ${snmp_version} -c ${snmp_community} ${pdu} ${load_oid}|awk '{sub (/.*: /, "load.value ");print $1" "$2/10}' diff --git a/plugins/ups/snmp__apcpdu b/plugins/ups/snmp__apcpdu deleted file mode 100755 index b6031ccc..00000000 --- a/plugins/ups/snmp__apcpdu +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) 2009 - Rune Nordbøe Skillingstad -# Copyright (c) 2009 - Kai Ove Gran -# -# 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. -# - -# snmp_host_apcpdu - For APC PDUs. Graphs total current throughput. -# -#%# family=snmpauto -#%# capabilities=snmpconf - -use strict; -use Net::SNMP; - -my $DEBUG = $ENV{DEBUG} || 0; -my $host = $ENV{host} || undef; -my $port = $ENV{port} || 161; -my $community = $ENV{community} || "public"; -my $iface = $ENV{interface} || undef; -my $timeout = $ENV{timeout} || 1; -my $snmp_ver = $ENV{version} || 1; - -if($0 =~ /^(?:|.*\/)snmp_([^_]+)_apcpdu$/) { - $host = $1; - if($host =~ /^([^:]+):(\d+)$/) { - $host = $1; - $port = $2; - } -} elsif(!defined($host)) { - die "# Error: couldn't understand what I'm supposed to monitor."; -} - -my @oidsList = ( - '1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.1', - '1.3.6.1.4.1.318.1.1.12.2.2.1.1.3.1', - '1.3.6.1.4.1.318.1.1.12.1.7.0' -); - -if(defined $ARGV[0] and $ARGV[0] eq "snmpconf") { - for(my $i = 0; $i < @oidsList; $i++) { - print "require " . $oidsList[$i] . "[0-9]\n"; - } - exit 0; -} - -my ($session, $error) = Net::SNMP->session( - -hostname => $host, - -community => $community, - -port => $port, - -timeout => $timeout, - -version => $snmp_ver, -); - -if(!defined ($session)) { - die "# Croaking: $error"; -} - -if($ARGV[0] and $ARGV[0] eq "config") { - my $modell = &get_single($session, '1.3.6.1.4.1.318.1.1.4.1.4.0'); - if($modell) { - print "host_name $host\n" unless $host eq 'localhost'; - print "graph_title Current, $modell\n"; - print "graph_args --base 1000 -l 0\n"; - print "graph_vlabel Amps\n"; - print "graph_category Ups\n"; - print "graph_info This graph shows the total throughput of the PDU"; - print "graph_order load threshold rating\n"; - print "load.label Load\n"; - print "load.type GAUGE\n"; - print "load.info Current load in amps.\n"; - print "load.draw LINE2\n"; - print "threshold.label Threshold\n"; - print "threshold.type GAUGE\n"; - print "threshold.info Near overload threshold.\n"; - print "threshold.draw LINE2\n"; - print "rating.label Rating\n"; - print "rating.type GAUGE\n"; - print "rating.info Rating (Max amps).\n"; - print "rating.draw LINE2\n"; - } - exit 0; -} - -my @response = &get_multiple($session, @oidsList); - -printf "load.value %.02f\n", $response[0] / 10; -printf "threshold.value %d\n", $response[1]; -printf "rating.value %d\n", $response[2]; - - -sub get_multiple { - my $handle = shift; - my @oids = @_; - - my @result; - foreach my $oid (@oids) { - push(@result, &get_single($handle,$oid)); - } - chomp @result; - return @result; -} - -sub get_single { - my ($handle, $oid) = @_; - - my $response = $handle->get_request ($oid); - if(!defined $response->{$oid}) { - print "# No response\n" if $DEBUG; - return ""; - } else { - print "# Got response \"".$response->{$oid}."\"\n" if $DEBUG; - return $response->{$oid}; - } -} From 7da1b039c2dd409effedc25f98e39eabbc2e7e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:33:00 -0700 Subject: [PATCH 03/11] Put order in SNMP plugins by moving all of them together in snmp/ This makes it easier to find what should be used for SNMP monitoring. --- plugins/{network => snmp}/snmp___bri_se_ | 0 plugins/{sensors => snmp}/snmp__areca_ | 0 .../{network => snmp}/snmp__brocade_temp_module_ | 0 plugins/{system => snmp}/snmp__cpu | 0 plugins/{system => snmp}/snmp__cpu_usage | 0 plugins/{system => snmp}/snmp__fn/snmp__fn | 0 plugins/{system => snmp}/snmp__fn/snmp__fn-cpu.png | Bin .../{system => snmp}/snmp__fn/snmp__fn-memory.png | Bin .../{system => snmp}/snmp__fn/snmp__fn-sessions.png | Bin .../snmp__fn/snmp__fn-vpnsessions.png | Bin plugins/{other => snmp}/snmp__gwia_bytes_ | 0 plugins/{groupwise => snmp}/snmp__gwia_msgs_ | 0 plugins/{groupwise => snmp}/snmp__gwmta_msgs_ | 0 plugins/{other => snmp}/snmp__gwpoa_ | 0 plugins/{sensors => snmp}/snmp__hp_temp | 0 plugins/{network => snmp}/snmp__if_ | 0 plugins/{network => snmp}/snmp__ifx_ | 0 plugins/{system => snmp}/snmp__ipoman_ | 0 plugins/{sensors => snmp}/snmp__linksys_poe | 0 plugins/{system => snmp}/snmp__memory_openwrt | 0 plugins/{system => snmp}/snmp__memory_win | 0 plugins/{nfs => snmp}/snmp__netapp_nfs3calls | 0 plugins/{sensors => snmp}/snmp__poseidon-sensors | 0 plugins/{sensors => snmp}/snmp__sfsnmp_fan | 0 plugins/{sensors => snmp}/snmp__sfsnmp_temp | 0 plugins/{sensors => snmp}/snmp__sfsnmp_volt | 0 plugins/{sensors => snmp}/snmp__thecus_fans | 0 plugins/{network => snmp}/snmp__ups2_ | 0 plugins/{system => snmp}/snmp__ups_ | 0 plugins/{sensors => snmp}/snmp__ups_battery | 0 plugins/{sensors => snmp}/snmp__ups_temp | 0 plugins/{sensors => snmp}/snmp__ups_voltage | 0 plugins/{other => snmp}/snmp__webthermometer | 0 plugins/{printers => snmp}/snmp_hplj2015 | 0 plugins/{printers => snmp}/snmp_hplj4xxx | 0 plugins/{system => snmp}/snmp_memory | 0 plugins/{printers => snmp}/snmp_xerox3xxx | 0 plugins/{printers => snmp}/snmp_xerox_wc-7x32 | 0 plugins/{system => snmp}/snmp_zyxel_usg__cpu | 0 plugins/{system => snmp}/snmp_zyxel_usg__ram | 0 plugins/{system => snmp}/snmp_zyxel_usg__sessions | 0 plugins/{system => snmp}/snmp_zyxel_zywall__cpu | 0 plugins/{system => snmp}/snmp_zyxel_zywall__flash | 0 plugins/{system => snmp}/snmp_zyxel_zywall__ram | 0 .../{system => snmp}/snmp_zyxel_zywall__sessions | 0 45 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{network => snmp}/snmp___bri_se_ (100%) rename plugins/{sensors => snmp}/snmp__areca_ (100%) rename plugins/{network => snmp}/snmp__brocade_temp_module_ (100%) rename plugins/{system => snmp}/snmp__cpu (100%) rename plugins/{system => snmp}/snmp__cpu_usage (100%) rename plugins/{system => snmp}/snmp__fn/snmp__fn (100%) rename plugins/{system => snmp}/snmp__fn/snmp__fn-cpu.png (100%) rename plugins/{system => snmp}/snmp__fn/snmp__fn-memory.png (100%) rename plugins/{system => snmp}/snmp__fn/snmp__fn-sessions.png (100%) rename plugins/{system => snmp}/snmp__fn/snmp__fn-vpnsessions.png (100%) rename plugins/{other => snmp}/snmp__gwia_bytes_ (100%) rename plugins/{groupwise => snmp}/snmp__gwia_msgs_ (100%) rename plugins/{groupwise => snmp}/snmp__gwmta_msgs_ (100%) rename plugins/{other => snmp}/snmp__gwpoa_ (100%) rename plugins/{sensors => snmp}/snmp__hp_temp (100%) rename plugins/{network => snmp}/snmp__if_ (100%) rename plugins/{network => snmp}/snmp__ifx_ (100%) rename plugins/{system => snmp}/snmp__ipoman_ (100%) rename plugins/{sensors => snmp}/snmp__linksys_poe (100%) rename plugins/{system => snmp}/snmp__memory_openwrt (100%) rename plugins/{system => snmp}/snmp__memory_win (100%) rename plugins/{nfs => snmp}/snmp__netapp_nfs3calls (100%) rename plugins/{sensors => snmp}/snmp__poseidon-sensors (100%) rename plugins/{sensors => snmp}/snmp__sfsnmp_fan (100%) rename plugins/{sensors => snmp}/snmp__sfsnmp_temp (100%) rename plugins/{sensors => snmp}/snmp__sfsnmp_volt (100%) rename plugins/{sensors => snmp}/snmp__thecus_fans (100%) rename plugins/{network => snmp}/snmp__ups2_ (100%) rename plugins/{system => snmp}/snmp__ups_ (100%) rename plugins/{sensors => snmp}/snmp__ups_battery (100%) rename plugins/{sensors => snmp}/snmp__ups_temp (100%) rename plugins/{sensors => snmp}/snmp__ups_voltage (100%) rename plugins/{other => snmp}/snmp__webthermometer (100%) rename plugins/{printers => snmp}/snmp_hplj2015 (100%) rename plugins/{printers => snmp}/snmp_hplj4xxx (100%) rename plugins/{system => snmp}/snmp_memory (100%) rename plugins/{printers => snmp}/snmp_xerox3xxx (100%) rename plugins/{printers => snmp}/snmp_xerox_wc-7x32 (100%) rename plugins/{system => snmp}/snmp_zyxel_usg__cpu (100%) rename plugins/{system => snmp}/snmp_zyxel_usg__ram (100%) rename plugins/{system => snmp}/snmp_zyxel_usg__sessions (100%) rename plugins/{system => snmp}/snmp_zyxel_zywall__cpu (100%) rename plugins/{system => snmp}/snmp_zyxel_zywall__flash (100%) rename plugins/{system => snmp}/snmp_zyxel_zywall__ram (100%) rename plugins/{system => snmp}/snmp_zyxel_zywall__sessions (100%) diff --git a/plugins/network/snmp___bri_se_ b/plugins/snmp/snmp___bri_se_ similarity index 100% rename from plugins/network/snmp___bri_se_ rename to plugins/snmp/snmp___bri_se_ diff --git a/plugins/sensors/snmp__areca_ b/plugins/snmp/snmp__areca_ similarity index 100% rename from plugins/sensors/snmp__areca_ rename to plugins/snmp/snmp__areca_ diff --git a/plugins/network/snmp__brocade_temp_module_ b/plugins/snmp/snmp__brocade_temp_module_ similarity index 100% rename from plugins/network/snmp__brocade_temp_module_ rename to plugins/snmp/snmp__brocade_temp_module_ diff --git a/plugins/system/snmp__cpu b/plugins/snmp/snmp__cpu similarity index 100% rename from plugins/system/snmp__cpu rename to plugins/snmp/snmp__cpu diff --git a/plugins/system/snmp__cpu_usage b/plugins/snmp/snmp__cpu_usage similarity index 100% rename from plugins/system/snmp__cpu_usage rename to plugins/snmp/snmp__cpu_usage diff --git a/plugins/system/snmp__fn/snmp__fn b/plugins/snmp/snmp__fn/snmp__fn similarity index 100% rename from plugins/system/snmp__fn/snmp__fn rename to plugins/snmp/snmp__fn/snmp__fn diff --git a/plugins/system/snmp__fn/snmp__fn-cpu.png b/plugins/snmp/snmp__fn/snmp__fn-cpu.png similarity index 100% rename from plugins/system/snmp__fn/snmp__fn-cpu.png rename to plugins/snmp/snmp__fn/snmp__fn-cpu.png diff --git a/plugins/system/snmp__fn/snmp__fn-memory.png b/plugins/snmp/snmp__fn/snmp__fn-memory.png similarity index 100% rename from plugins/system/snmp__fn/snmp__fn-memory.png rename to plugins/snmp/snmp__fn/snmp__fn-memory.png diff --git a/plugins/system/snmp__fn/snmp__fn-sessions.png b/plugins/snmp/snmp__fn/snmp__fn-sessions.png similarity index 100% rename from plugins/system/snmp__fn/snmp__fn-sessions.png rename to plugins/snmp/snmp__fn/snmp__fn-sessions.png diff --git a/plugins/system/snmp__fn/snmp__fn-vpnsessions.png b/plugins/snmp/snmp__fn/snmp__fn-vpnsessions.png similarity index 100% rename from plugins/system/snmp__fn/snmp__fn-vpnsessions.png rename to plugins/snmp/snmp__fn/snmp__fn-vpnsessions.png diff --git a/plugins/other/snmp__gwia_bytes_ b/plugins/snmp/snmp__gwia_bytes_ similarity index 100% rename from plugins/other/snmp__gwia_bytes_ rename to plugins/snmp/snmp__gwia_bytes_ diff --git a/plugins/groupwise/snmp__gwia_msgs_ b/plugins/snmp/snmp__gwia_msgs_ similarity index 100% rename from plugins/groupwise/snmp__gwia_msgs_ rename to plugins/snmp/snmp__gwia_msgs_ diff --git a/plugins/groupwise/snmp__gwmta_msgs_ b/plugins/snmp/snmp__gwmta_msgs_ similarity index 100% rename from plugins/groupwise/snmp__gwmta_msgs_ rename to plugins/snmp/snmp__gwmta_msgs_ diff --git a/plugins/other/snmp__gwpoa_ b/plugins/snmp/snmp__gwpoa_ similarity index 100% rename from plugins/other/snmp__gwpoa_ rename to plugins/snmp/snmp__gwpoa_ diff --git a/plugins/sensors/snmp__hp_temp b/plugins/snmp/snmp__hp_temp similarity index 100% rename from plugins/sensors/snmp__hp_temp rename to plugins/snmp/snmp__hp_temp diff --git a/plugins/network/snmp__if_ b/plugins/snmp/snmp__if_ similarity index 100% rename from plugins/network/snmp__if_ rename to plugins/snmp/snmp__if_ diff --git a/plugins/network/snmp__ifx_ b/plugins/snmp/snmp__ifx_ similarity index 100% rename from plugins/network/snmp__ifx_ rename to plugins/snmp/snmp__ifx_ diff --git a/plugins/system/snmp__ipoman_ b/plugins/snmp/snmp__ipoman_ similarity index 100% rename from plugins/system/snmp__ipoman_ rename to plugins/snmp/snmp__ipoman_ diff --git a/plugins/sensors/snmp__linksys_poe b/plugins/snmp/snmp__linksys_poe similarity index 100% rename from plugins/sensors/snmp__linksys_poe rename to plugins/snmp/snmp__linksys_poe diff --git a/plugins/system/snmp__memory_openwrt b/plugins/snmp/snmp__memory_openwrt similarity index 100% rename from plugins/system/snmp__memory_openwrt rename to plugins/snmp/snmp__memory_openwrt diff --git a/plugins/system/snmp__memory_win b/plugins/snmp/snmp__memory_win similarity index 100% rename from plugins/system/snmp__memory_win rename to plugins/snmp/snmp__memory_win diff --git a/plugins/nfs/snmp__netapp_nfs3calls b/plugins/snmp/snmp__netapp_nfs3calls similarity index 100% rename from plugins/nfs/snmp__netapp_nfs3calls rename to plugins/snmp/snmp__netapp_nfs3calls diff --git a/plugins/sensors/snmp__poseidon-sensors b/plugins/snmp/snmp__poseidon-sensors similarity index 100% rename from plugins/sensors/snmp__poseidon-sensors rename to plugins/snmp/snmp__poseidon-sensors diff --git a/plugins/sensors/snmp__sfsnmp_fan b/plugins/snmp/snmp__sfsnmp_fan similarity index 100% rename from plugins/sensors/snmp__sfsnmp_fan rename to plugins/snmp/snmp__sfsnmp_fan diff --git a/plugins/sensors/snmp__sfsnmp_temp b/plugins/snmp/snmp__sfsnmp_temp similarity index 100% rename from plugins/sensors/snmp__sfsnmp_temp rename to plugins/snmp/snmp__sfsnmp_temp diff --git a/plugins/sensors/snmp__sfsnmp_volt b/plugins/snmp/snmp__sfsnmp_volt similarity index 100% rename from plugins/sensors/snmp__sfsnmp_volt rename to plugins/snmp/snmp__sfsnmp_volt diff --git a/plugins/sensors/snmp__thecus_fans b/plugins/snmp/snmp__thecus_fans similarity index 100% rename from plugins/sensors/snmp__thecus_fans rename to plugins/snmp/snmp__thecus_fans diff --git a/plugins/network/snmp__ups2_ b/plugins/snmp/snmp__ups2_ similarity index 100% rename from plugins/network/snmp__ups2_ rename to plugins/snmp/snmp__ups2_ diff --git a/plugins/system/snmp__ups_ b/plugins/snmp/snmp__ups_ similarity index 100% rename from plugins/system/snmp__ups_ rename to plugins/snmp/snmp__ups_ diff --git a/plugins/sensors/snmp__ups_battery b/plugins/snmp/snmp__ups_battery similarity index 100% rename from plugins/sensors/snmp__ups_battery rename to plugins/snmp/snmp__ups_battery diff --git a/plugins/sensors/snmp__ups_temp b/plugins/snmp/snmp__ups_temp similarity index 100% rename from plugins/sensors/snmp__ups_temp rename to plugins/snmp/snmp__ups_temp diff --git a/plugins/sensors/snmp__ups_voltage b/plugins/snmp/snmp__ups_voltage similarity index 100% rename from plugins/sensors/snmp__ups_voltage rename to plugins/snmp/snmp__ups_voltage diff --git a/plugins/other/snmp__webthermometer b/plugins/snmp/snmp__webthermometer similarity index 100% rename from plugins/other/snmp__webthermometer rename to plugins/snmp/snmp__webthermometer diff --git a/plugins/printers/snmp_hplj2015 b/plugins/snmp/snmp_hplj2015 similarity index 100% rename from plugins/printers/snmp_hplj2015 rename to plugins/snmp/snmp_hplj2015 diff --git a/plugins/printers/snmp_hplj4xxx b/plugins/snmp/snmp_hplj4xxx similarity index 100% rename from plugins/printers/snmp_hplj4xxx rename to plugins/snmp/snmp_hplj4xxx diff --git a/plugins/system/snmp_memory b/plugins/snmp/snmp_memory similarity index 100% rename from plugins/system/snmp_memory rename to plugins/snmp/snmp_memory diff --git a/plugins/printers/snmp_xerox3xxx b/plugins/snmp/snmp_xerox3xxx similarity index 100% rename from plugins/printers/snmp_xerox3xxx rename to plugins/snmp/snmp_xerox3xxx diff --git a/plugins/printers/snmp_xerox_wc-7x32 b/plugins/snmp/snmp_xerox_wc-7x32 similarity index 100% rename from plugins/printers/snmp_xerox_wc-7x32 rename to plugins/snmp/snmp_xerox_wc-7x32 diff --git a/plugins/system/snmp_zyxel_usg__cpu b/plugins/snmp/snmp_zyxel_usg__cpu similarity index 100% rename from plugins/system/snmp_zyxel_usg__cpu rename to plugins/snmp/snmp_zyxel_usg__cpu diff --git a/plugins/system/snmp_zyxel_usg__ram b/plugins/snmp/snmp_zyxel_usg__ram similarity index 100% rename from plugins/system/snmp_zyxel_usg__ram rename to plugins/snmp/snmp_zyxel_usg__ram diff --git a/plugins/system/snmp_zyxel_usg__sessions b/plugins/snmp/snmp_zyxel_usg__sessions similarity index 100% rename from plugins/system/snmp_zyxel_usg__sessions rename to plugins/snmp/snmp_zyxel_usg__sessions diff --git a/plugins/system/snmp_zyxel_zywall__cpu b/plugins/snmp/snmp_zyxel_zywall__cpu similarity index 100% rename from plugins/system/snmp_zyxel_zywall__cpu rename to plugins/snmp/snmp_zyxel_zywall__cpu diff --git a/plugins/system/snmp_zyxel_zywall__flash b/plugins/snmp/snmp_zyxel_zywall__flash similarity index 100% rename from plugins/system/snmp_zyxel_zywall__flash rename to plugins/snmp/snmp_zyxel_zywall__flash diff --git a/plugins/system/snmp_zyxel_zywall__ram b/plugins/snmp/snmp_zyxel_zywall__ram similarity index 100% rename from plugins/system/snmp_zyxel_zywall__ram rename to plugins/snmp/snmp_zyxel_zywall__ram diff --git a/plugins/system/snmp_zyxel_zywall__sessions b/plugins/snmp/snmp_zyxel_zywall__sessions similarity index 100% rename from plugins/system/snmp_zyxel_zywall__sessions rename to plugins/snmp/snmp_zyxel_zywall__sessions From 5d5bf6e4e55841c91cb43cd8efc26878b4b70392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:36:33 -0700 Subject: [PATCH 04/11] Remove apcupsd plugin (is actually a readme file), reorder UPSes. --- plugins/other/apcupsd | 6 ------ plugins/{sensors => ups}/nut | 0 plugins/{sensors => ups}/nutups2_ | 0 3 files changed, 6 deletions(-) delete mode 100755 plugins/other/apcupsd rename plugins/{sensors => ups}/nut (100%) rename plugins/{sensors => ups}/nutups2_ (100%) diff --git a/plugins/other/apcupsd b/plugins/other/apcupsd deleted file mode 100755 index 90205f6d..00000000 --- a/plugins/other/apcupsd +++ /dev/null @@ -1,6 +0,0 @@ -This plugin is obsolete. Instead, please use apcupsd_pct plugin: - -apcupsd_pct plugin -http://exchange.munin-monitoring.org/plugins/apcupsd_pct/details - -thanks. diff --git a/plugins/sensors/nut b/plugins/ups/nut similarity index 100% rename from plugins/sensors/nut rename to plugins/ups/nut diff --git a/plugins/sensors/nutups2_ b/plugins/ups/nutups2_ similarity index 100% rename from plugins/sensors/nutups2_ rename to plugins/ups/nutups2_ From e0f0fb865912c3c20aabf805e101541a64af1d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:38:45 -0700 Subject: [PATCH 05/11] Do some more housecleaning. --- plugins/{mysql_schema_size_ => mysql}/mysql-schema-size | 0 plugins/{mysql_table_size_ => mysql}/mysql-table-size | 0 plugins/{print => printer}/printer-ink-levels-by-percent | 0 plugins/{printers => printer}/xerox-wc3220 | 0 plugins/{printers => printer}/xerox-wc7232-consumables | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{mysql_schema_size_ => mysql}/mysql-schema-size (100%) rename plugins/{mysql_table_size_ => mysql}/mysql-table-size (100%) rename plugins/{print => printer}/printer-ink-levels-by-percent (100%) rename plugins/{printers => printer}/xerox-wc3220 (100%) rename plugins/{printers => printer}/xerox-wc7232-consumables (100%) diff --git a/plugins/mysql_schema_size_/mysql-schema-size b/plugins/mysql/mysql-schema-size similarity index 100% rename from plugins/mysql_schema_size_/mysql-schema-size rename to plugins/mysql/mysql-schema-size diff --git a/plugins/mysql_table_size_/mysql-table-size b/plugins/mysql/mysql-table-size similarity index 100% rename from plugins/mysql_table_size_/mysql-table-size rename to plugins/mysql/mysql-table-size diff --git a/plugins/print/printer-ink-levels-by-percent b/plugins/printer/printer-ink-levels-by-percent similarity index 100% rename from plugins/print/printer-ink-levels-by-percent rename to plugins/printer/printer-ink-levels-by-percent diff --git a/plugins/printers/xerox-wc3220 b/plugins/printer/xerox-wc3220 similarity index 100% rename from plugins/printers/xerox-wc3220 rename to plugins/printer/xerox-wc3220 diff --git a/plugins/printers/xerox-wc7232-consumables b/plugins/printer/xerox-wc7232-consumables similarity index 100% rename from plugins/printers/xerox-wc7232-consumables rename to plugins/printer/xerox-wc7232-consumables From 4e3ef5b93e0f55c4edc8583e3bd4d5da6cabd638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:41:09 -0700 Subject: [PATCH 06/11] ipmi: remove the multiple IPMI plugins and simply introduce my FreeIPMI plugin. This is a catch-all that will work with any recent FreeIPMI and actually supports all the features of the others. --- plugins/ipmi/freeipmi_ | 341 ++++++-------- plugins/ipmi/ipmi_ | 95 ---- plugins/ipmi/ipmi_fans | 114 ----- plugins/ipmi/ipmi_sdr_ | 153 ------ plugins/ipmi/ipmi_therm | 103 ---- plugins/ipmi/ipmisens-v3 | 865 ---------------------------------- plugins/ipmi/ipmisensors | Bin 3155 -> 0 bytes plugins/ipmi/ipmitool_sensor_ | 461 ------------------ 8 files changed, 146 insertions(+), 1986 deletions(-) mode change 100755 => 100644 plugins/ipmi/freeipmi_ delete mode 100755 plugins/ipmi/ipmi_ delete mode 100755 plugins/ipmi/ipmi_fans delete mode 100755 plugins/ipmi/ipmi_sdr_ delete mode 100755 plugins/ipmi/ipmi_therm delete mode 100755 plugins/ipmi/ipmisens-v3 delete mode 100755 plugins/ipmi/ipmisensors delete mode 100755 plugins/ipmi/ipmitool_sensor_ diff --git a/plugins/ipmi/freeipmi_ b/plugins/ipmi/freeipmi_ old mode 100755 new mode 100644 index 101fea4f..9dfe7875 --- a/plugins/ipmi/freeipmi_ +++ b/plugins/ipmi/freeipmi_ @@ -1,228 +1,179 @@ -#!/usr/bin/python -# -# Copyright (C) 2011,2012 Andreas Thienemann -# -# 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, either version 3 of the License, or -# (at your option) any later version. -# -# 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, see . -# +#!/bin/sh +# -*- sh -*- + +: << =cut -""" =head1 NAME -freeipmi_ - Munin plugin to retreive temperature and fan speed measurements -from a local machine via IPMI. - -=head1 APPLICABLE SYSTEMS - -All machines with an IPMI capable baseboard management controller. +freeipmi_ - Plugin to monitor temperature or fan speed using FreeIPMI =head1 CONFIGURATION -On most supported systems this plugin works nearly out of the box as long as -both Python and the freeipmi binaries in a semi-recent version are installed. +=head2 ENVIRONMENT VARIABLES -If the machine works out of the box can be tested by calling bmc-info. -If there's text output, a bmc card was detected. If there's an entry for -"Sensor Device" visible in the "Additional Device Support" entry you're good. +When used to monitor a foreign host, this plugins use the variables +IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system. -If you get a "ipmi_cmd_get_device_id: driver timeout" message you have most -likely no bmc to query. +=head2 WILDCARD PLUGIN -In certain cases however bmc-info will just seem to hang for quite some time. -In this case, autodetection does not work because the smbios table has -incorrect information. One system known to experience this problem is the -HP Proliant Microserver. +You can monitor either the current system (via /dev/ipmi0 and the +like) or a remote system (via the LAN protocols), and for each of the +two options you can select your sensors: -Adding env.freeipmi_args "--no-probing --driver-type=KCS --driver-address=0xca2 --register-spacing=1" -to the munin plugin configuration will make the plugin work. This is the -specific line for the HP Proliant Microserver mentioned above. Your mileage -may vary. + - fans; + - temp; + - power; + - current; + - voltage. -Basic configuration for every system is that the plugin needs to be called as root. +When used for the local host, the plugin should be linked as, e.g., +'ipmi_temp', whereas when used to monitor a foreign host it should be, +e.g., 'ipmi_192.168.0.253_temp'. -Add the following to your /etc/munin/plugin-conf.d/freeipmi: - - [freeipmi_*] - user root - -=head1 INTERPRETATION - -The plugin shows the temperature in Celsius or the fanspeed in rotations per minute. - -=head1 MAGIC MARKERS - - #%# family=contrib - #%# capabilities=autoconf suggest - -=head1 VERSION - -0.0.1 - -=head1 BUGS - -Only local support for now. Remote could be hacked in via freeipmi_args for now. +=head1 NOTE =head1 AUTHOR -Andreas Thienemann +Rewritten by Diego Elio Pettenò . +Based on the work of Nicolai Langfeldt , Logilab and +Peter Palfrader. =head1 LICENSE -GPLv3+ +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf suggest =cut -""" -import subprocess -import sys -import os -import re -import pprint +#### Parse commandline to determine what the job is -# Parse some environment variables -if os.getenv("freeipmi_args") is not None: - freeipmi_args = " %s" % (os.getenv("freeipmi_args")) -else: - freeipmi_args = "" +_ipmisensors() { + params="--quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors" + if [ "x${hostname}" != "x" ]; then + params="${params} --hostname=${hostname}" + [ "x${IPMI_USERNAME}" != "x" ] && params="${params} --username=${IPMI_USERNAME}" + [ "x${IPMI_PASSWORD}" != "x" ] && params="${params} --password=${IPMI_PASSWORD}" + fi -# We are a wildcard plugin, figure out whether we are called for temp or fan -if sys.argv[0].split("_")[1] == "temp": - mode = "Temperature" -elif sys.argv[0].split("_")[1] == "fan": - mode = "Fan" -else: - mode = None + if ! ipmi-sensors ${params} --output-sensor-thresholds "$@"; then + ipmi-sensors ${params} "$@" + fi +} -def whereis(prog): - """Check if prog can be found in the path and if yes, return the full pathname""" - prog = os.path.basename(prog) - for dir in os.getenv("PATH").split(":"): - for root, dirs, files in os.walk(dir): - if prog in files: - return os.path.join(dir, prog) - return None +# extract and eventual hostname out of the called name; we +# have to check whether it's set to "u" as that's what happens +# when the compatibility with ipmi_sensor_ is used. +hostname1=${0#*_} +hostname=${hostname1%%_*} +if [ "x${hostname}" = "xu" -o "x${hostname}" = "x${hostname1}" ]; then + hostname="" +fi -def normalize_sensor(name): - name = name.lower().replace("-","M").replace("+","P") - name = re.sub("[^a-z0-9A-Z]","_", name) - return name +case $0 in + *_temp|*_u_degrees_c) + title="Temperatures" + vlabel="degrees Celsius" + type=Temperature + unit=C + ;; + *_fans|*_u_rpm) + title="Fan speeds" + vlabel="Rotations per Minute (RPM)" + type=Fan + unit=RPM + ;; + *_power|*_u_watts) + title="Power consumption" + vlabel="Watts" + type=Current + unit=W + ;; + *_current|*_u_amps) + title="Current drain" + vlabel="Amperes" + type=Current + unit=A + ;; + *_voltage|*_u_volts) + title="Voltages" + vlabel="Volts" + type=Voltage + unit=V + ;; + *) + if [ x"$1" != x"autoconf" -a x"$1" != x"suggest" ]; then + echo "Please invoke as one of the supported sensors types:" >&2 + echo freeipmi_{temp,fans,power,current} >&2 + exit 1 + fi +esac -# Code sniplet from Philipp Keller -# http://code.pui.ch/2007/02/19/set-timeout-for-a-shell-command-in-python/ -def timeout_command(command, timeout): - """call shell-command and either return its output or kill it - if it doesn't normally exit within timeout seconds and return None""" - import subprocess, datetime, os, time, signal - start = datetime.datetime.now() - process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) - while process.poll() is None: - time.sleep(0.1) - now = datetime.datetime.now() - if (now - start).seconds> timeout: - os.kill(process.pid, signal.SIGKILL) - os.waitpid(-1, os.WNOHANG) - return None - return process.stdout.read() +case $1 in + autoconf) + if ! command -v ipmi-sensors >/dev/null 2>&1 ; then + echo 'no (missing ipmi-sensors command)' + exit 0 + fi -def bmc_detect(): - """Check whether there's a baseboard management controller we can query.""" - if whereis("bmc-info") is None: - print "no (bmc-info not found in path. Please install FreeIPMI.)" - sys.exit(0) - else: - out = timeout_command("bmc-info%s" % (freeipmi_args), 2) - if out is not None and "[Sensor Device]" in out: - print "yes" - sys.exit(0) - else: - print "no (no supported bmc found)" - sys.exit(0) + if ! _ipmisensors -t OS_Boot >/dev/null 2>&1 ; then + echo 'no (unable to access IPMI device)' + exit 0 + fi -def read_sensors(): - """Return all sensor data as a dict""" - out = timeout_command("ipmi-sensors --verbose%s" % (freeipmi_args), 2) - sensors = dict() - sensor = dict() - sensor_id = None - for line in out.split("\n"): - if ":" in line: - k,v = line.split(": ") - if k == "Record ID": - sensor = dict() - sensor_id = int(v) - sensor[k] = v - else: - sensor[k] = v - else: - sensors[sensor_id] = sensor - return sensors + echo yes + exit 0 + ;; + suggest) + _ipmisensors | awk -F, ' +$3 == "Temperature" { print "temp"; } +$3 == "Fan" { print "fans"; } +$3 == "Current" && $5 == "W" { print "power"; } +$3 == "Current" && $5 == "A" { print "current"; } +$3 == "Voltage" { print "voltage"; } +' + exit 0;; + config) + cat - < 0: - print "fan" - if temperature > 0: - print "temp" - sys.exit(0) - -else: - fetch() +# vim: syntax=sh ts=4 et diff --git a/plugins/ipmi/ipmi_ b/plugins/ipmi/ipmi_ deleted file mode 100755 index acaa9fcd..00000000 --- a/plugins/ipmi/ipmi_ +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python -from commands import getstatusoutput as gso - -def safe(s): - s=s.replace("-", "_") - s=s.replace(" ", "_") - s=s.replace(".", "_") - return s - -def config(data,title): - for i in data: - print "%s.label %s"%(safe(i[0]), i[0]) - - # check for non-critical thresholds - if i[6] != 'na': - if i[7] != 'na': - warning = "%s:%s"%(i[6],i[7]) - else: - warning = "%s:"%i[6] - else: - if i[7] != 'na': - warning = "%s"%i[7] - else: - warning = "" - if warning: - print "%s.warning %s"%(safe(i[0]),warning) - - # check for critical thresholds - if i[5] == 'na': - i[5] == i[4] # N/A, so see if there is a non-recoverable threshold - if i[8] == 'na': - i[8] == i[9] # N/A, so see if there is a non-recoverable threshold - if i[5] != 'na': - if i[8] != 'na': - critical = "%s:%s"%(i[5],i[8]) - else: - critical = "%s:"%i[5] - else: - if i[8] != 'na': - critical = "%s"%i[8] - else: - critical = "" - if critical: - print "%s.critical %s"%(safe(i[0]),critical) - - print "graph_title %s"%title - if title == "Voltages": - print "graph_args -X 0 --logarithmic -l 1 -u 15" - #print "graph_args --base 1000 --logarithmic" - else: - print "graph_args -l 0" - print "graph_vlabel %s"%i[2] - print "graph_period minute" - print "graph_category IPMI" - -def get_data(): - import sys - category = sys.argv[0].split("_",1)[1] - data = [] - if category =="Fans": - ids = ("Fan 1 Tach", "Fan 2 Tach", "Fan 3 Tach", - "Fan 4 Tach", "Fan 5 Tach", "Fan 6 Tach",) - title = "Fan Speed" - elif category == "Temperature": - ids = ("Ambient Temp", "Memory Temp",) - title = "Temperatures" - elif category == "Voltage": - ids = ("Planar 1.5V", "Planar 1.8V", - "Planar 3.3V", "Planar 5V", "Planar 12V", - "Planar VBAT", "CPU 1 VCore", "CPU 2 VCore",) - title = "Voltages" - - status, output = gso("ipmitool sensor") - for row in output.split("\n"): - items = map(str.strip,row.split("|")) - field,value,units,status,lower_nonrecoverable,lower_critical,lower_non_critical,upper_non_critical,upper_critical,upper_nonrecoverable=items - if field in ids: - if value == 'na': continue - data.append(items) - return data,title - -def sample(data): - for i in data: - print "%s.value %s"%(safe(i[0]),i[1]) - -def main(): - import sys - data,title = get_data() - if 'config' in sys.argv: - return config(data,title) - sample(data) - -if __name__ == '__main__': - main() - diff --git a/plugins/ipmi/ipmi_fans b/plugins/ipmi/ipmi_fans deleted file mode 100755 index 0d23f126..00000000 --- a/plugins/ipmi/ipmi_fans +++ /dev/null @@ -1,114 +0,0 @@ -#! /usr/bin/perl -w -# -# This plugin will graph the chassis fan speed on a Dell PowerEdge Server -# via the ipmi-sensors tool. It has been tested on the following chassis: -# -# PE1850 -# -# To enable: -# -# ln -s /usr/share/munin/plugins/ipmi-fans /etc/munin/plugins/ipmi-fans -# -# Configuration parameters for /etc/munin/plugin-conf.d/munin-node -# -# [ipmi_fans] -# user - User that has permissions to run the omreport binary -# env.omreport - Path to the omreport binary -# -# Parameters: -# -# config -# autoconf -# -# Author: Alexx Roche -# Built on the work of Justin Shepherd -# Revision: 2.1 2011/01/10 -# -#%# family=auto -#%# capabilities=autoconf - -use strict; - -my $IPMI; -if(-f "/usr/sbin/ipmi-sensors"){ $IPMI='/usr/sbin/ipmi-sensors'; } -unless($IPMI){ - $IPMI = `which ipmi-sensors 2>/dev/null|sed 's/.*no ipmi-sensors//'`; - #$IPMI = `echo -n \$(which ipmi-sensors)`; -} -chomp($IPMI); -unless($IPMI){ exit 1; } - -if ($ARGV[0] && $ARGV[0] eq "autoconf"){ - if (-f $IPMI){ - print "yes\n"; - }else{ - print "no ($IPMI does not exist)\n"; - exit(1); - } -}else{ - my $cmd = "$IPMI --verbose --sensors=\"\$(echo \$($IPMI |grep FAN|sed 's/:.*//'))\""; - #if ($ARGV[0] eq 'cmd'){ print $cmd; exit;}; - my @result = `$cmd`; - my (%val, $index); - $index=0; - my $count=0; - #Four of these seem to be unlabled, I'm going to guess that they are the CPU(s) and HDD(s) - my @unknown = ('HDD0','HDD1','CPU0','CPU1'); - foreach my $line (@result) { - $line =~ s/\s+/ /g; - $line =~ s/\s$//g; - if(!$line || $line eq ""){ - $index++; - next; - } - my ($key, $val) = split(/\: /, $line); - unless($key){ - # $index++; - # next; - } - if($key eq 'Sensor Name'){ - if($val eq 'Temp'){ - $val = $unknown[$count]; - $count++; - } - #my @data = split / /, $val; - #$data[2]=~s/^\(//; - #$data[2]=~s/\)$//; - #my($warn,$crit) = split/\//, $data[2]; - $val{$index}{'Probe Name'} = "$val"; - }elsif($key eq 'Upper Critical Threshold'){ - $val=~s/ .*$//; - next unless $val=~m/^\d+\.\d+$/; - $val{$index}{'Critical Threshold'} = "$val"; - }elsif($key eq 'Normal Max.'){ - $val=~s/ .*//; - $val{$index}{'Warning Threshold'} = $val; - }elsif($key eq 'Sensor Reading'){ - $val=~s/ .*//; - $val{$index}{'Reading'} = $val; - }elsif($key eq 'Sensor Max. Reading' && !$val{$index}{'Critical Threshold'}){ - $val=~s/ .*$//; - $val{$index}{'Critical Threshold'} = "$val"; - } - } - - if ($ARGV[0] && $ARGV[0] eq "config") { - print "graph_title IPMI - Fan Speeds\n"; - print "graph_args --base 1000 -l 0\n"; - print "graph_vlabel Speed in RPM\n"; - print "graph_category Sensors\n"; - foreach my $j (sort keys %val) { - print "probe_$j\.label $val{$j}{'Probe Name'}\n"; - print "probe_$j\.warning $val{$j}{'Warning Threshold'}\n"; - print "probe_$j\.critical $val{$j}{'Critical Threshold'}\n"; - } - }else{ - foreach my $j (sort keys %val) { - if($val{$j}{'Reading'}){ - print "probe_$j.value $val{$j}{'Reading'}\n"; - } - } - } -} -exit(0); - diff --git a/plugins/ipmi/ipmi_sdr_ b/plugins/ipmi/ipmi_sdr_ deleted file mode 100755 index a7d6c734..00000000 --- a/plugins/ipmi/ipmi_sdr_ +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/perl -w -# -# IPMI data gathering for munin. -# -# Author: 2008 Benjamin Pineau -# This work is hereby released into the Public Domain. -# To view a copy of the public domain dedication, visit -# http://creativecommons.org/licenses/publicdomain/ -# -# Requirements : -# -# - ipmitool command line utility (and kernel drivers) -# - access rights to /dev/ipmi0 device (ie, root privileges -# can be configured in /etc/munin/plugin-conf.d/munin-node) -# -# Parameters supported: -# -# config -# autoconf -# -# Setup : -# -# ipmitool sdr || echo "please load IPMI kernel modules" -# cp ipmi_sdr_ /usr/share/munin/plugins/ -# chmod +x /usr/share/munin/plugins/ipmi_sdr_ -# ln -s /usr/share/munin/plugins/ipmi_sdr_ /etc/munin/plugins/ipmi_sdr_fan -# ln -s /usr/share/munin/plugins/ipmi_sdr_ /etc/munin/plugins/ipmi_sdr_current -# ln -s /usr/share/munin/plugins/ipmi_sdr_ /etc/munin/plugins/ipmi_sdr_voltage -# ln -s /usr/share/munin/plugins/ipmi_sdr_ /etc/munin/plugins/ipmi_sdr_temperature -# echo -e "\n[ipmi_sdr*]\nuser root\ntimeout 15\n" >> /etc/munin/plugin-conf.d/munin-node -# /etc/init.d/munin-node restart -# -# Magic markers -#%# family=auto -#%# capabilities=autoconf - -use strict; -use warnings; - -$ENV{'LANG'} = 'C'; -$ENV{'LC_ALL'} = 'C'; - -my $ipmidump = $ENV{'ipmidump'} || '/var/lib/munin/plugin-state/ipmi_sdr'; -my $ipmitool = $ENV{'ipmitool'} || 'ipmitool'; -my $drefresh = $ENV{'drefresh'} || 86400; - -my %sensors; - -my $desc = { - 'fan' => { - 'graph_title' => 'Fans rotations per minute', - 'graph_vlabel' => 'RPM', - 'graph_info' => 'Fans rotations per minute', - }, - 'voltage' => { - 'graph_title' => 'Electrical tensions', - 'graph_vlabel' => 'Volts', - 'graph_info' => 'Electrical tensions', - }, - 'temperature' => { - 'graph_title' => 'Hardware temperatures', - 'graph_vlabel' => 'Degrees Celsius', - 'graph_info' => 'Hardware temperature sensors output', - }, - 'current' => { - 'graph_title' => 'Hardware power consumption', - 'graph_vlabel' => 'Watts or Amperes', - 'graph_info' => 'Hardware power consumption', - }, -}; - -my $stype = $0 =~ /.*ipmi_sdr_(\w+)$/ ? lc($1) : 'temperature'; - -if (!defined($desc->{"$stype"})) { - printf STDERR "Unknown sensor type : '$stype'. Aborting.\n"; - exit 1; -} - -sub strip_spaces($) { - (my $s = shift) =~ s/^\s*(.*?)\s*\n?$/$1/; - return $s; -} - -sub normalize_name($) { - (my $l = lc(strip_spaces(shift))) =~ tr/\t ./_/; - return $l; -} - -sub sdrlist_parse(@) { - foreach(@_) { - next unless /^([^\|]+)\s*\|\s*(\w+)\s*\|[^\|]+\|[^\|]+\|\s*([\d\.]+)\s+/; - $sensors{$_}{"name"} = strip_spaces($1); - $sensors{$_}{"value"} = strip_spaces($3); - $sensors{$_}{"label"} = normalize_name($1) . normalize_name($2); - } -} - -if (defined $ARGV[0] and $ARGV[0] eq 'autoconf') { - `$ipmitool help 2> /dev/null`; - if ($?) { - print "no ($ipmitool not found)"; - exit 1; - } - - `$ipmitool sdr dump $ipmidump`; - if ($?) { - printf "no (ipmitool sdr dump returned code %d)\n", $? >> 8; - exit 1; - } - - `$ipmitool sdr type $stype -S $ipmidump`; - if ($?) { - print "no (ipmitool didn't found any sensor of type "; - printf "'$stype', returned code %d)\n", $? >> 8; - exit 1; - } - - print "yes\n"; - exit 0; -} - -# "ipmitool dump" dumps speeds up data retreival big time, by avoiding -# IPMI sensors autodiscovery. This only caches sensors names/types/ids -# (not values/datas), so we can have a very long cache lifetime policy. -if (-f $ipmidump) { - unlink($ipmidump) if (time - (stat($ipmidump))[9] >= $drefresh); -} - -unless (-f $ipmidump) { - `$ipmitool sdr dump $ipmidump` || die $!; -} - -(my @dt = `$ipmitool sdr type $stype -S $ipmidump`) || die $!; -sdrlist_parse(@dt); - -if (defined($ARGV[0]) && $ARGV[0] eq "config") { - print "graph_category system\n"; - print "graph_title " . $desc->{$stype}->{"graph_title"} . "\n"; - print "graph_vlabel " . $desc->{$stype}->{"graph_vlabel"} . "\n"; - print "graph_info " . $desc->{$stype}->{"graph_info"} . "\n"; - - foreach my $v (values(%sensors)) { - print $v->{"label"} . ".label " . $v->{"name"} . "\n"; - print $v->{"label"} . ".type GAUGE\n"; - } - - exit 0; -} - -foreach my $v (values(%sensors)) { - print $v->{"label"} . ".value " . $v->{"value"} . "\n"; -} - diff --git a/plugins/ipmi/ipmi_therm b/plugins/ipmi/ipmi_therm deleted file mode 100755 index b9307018..00000000 --- a/plugins/ipmi/ipmi_therm +++ /dev/null @@ -1,103 +0,0 @@ -#! /usr/bin/perl -w -# -# This plugin will graph the chassis temp sensors on a Dell PowerEdge Server -# via the ipmi-sensors tool. It has been tested on the following chassis: -# -# PE1850 -# -# To enable: -# -# ln -s /usr/share/munin/plugins/ipmi-therm /etc/munin/plugins/ipmi-therm -# -# Configuration parameters for /etc/munin/plugin-conf.d/munin-node -# -# [ipmi_therm] -# user - User that has permissions to run ipmi-sensors -# env.category sensors -# -# Parameters: -# -# config -# autoconf -# -# Author: Alexx Roche -# Built on the work of Justin Shepherd -# Revision: 1.3 2011/01/10 -# -#%# family=auto -#%# capabilities=autoconf - -use strict; - -my $IPMI; -if(-f "/usr/sbin/ipmi-sensors"){ $IPMI='/usr/sbin/ipmi-sensors'; } -unless($IPMI){ - $IPMI = `which ipmi-sensors 2>/dev/null|sed 's/.*no ipmi-sensors//'`; - #$IPMI = `echo -n \$(which ipmi-sensors)`; -} -chomp($IPMI); -unless($IPMI){ exit 1; } - -if ($ARGV[0] && $ARGV[0] eq "autoconf"){ - if (-f $IPMI){ - print "yes\n"; - }else{ - print "no ($IPMI does not exist)\n"; - exit(1); - } -}else{ - my $cmd = "$IPMI|grep Temp"; - my @result = `$cmd`; - my (%val, $index); - $index=0; - my $count=0; - #Four of these seem to be unlabled, I'm going to guess that they are the CPU(s) and HDD(s) - my @unknown = ('CPU0','CPU1','HDD0','HDD1'); - foreach my $line (@result) { - $line =~ s/\s+/ /g; - $line =~ s/\s$//g; - next if ($line eq ""); - my ($list, $field, $value, $state) = split(/\: /, $line); - #print "L: $list F: $field V: $value S: $state\n"; - if($field=~m/^(Temp|Ambient|Planar|Riser)/) { - my $f=$1; - if($f eq 'Temp'){ - $f = $unknown[$count]; - $count++; - } - my @data = split / /, $value; - $data[2]=~s/^\(//; - $data[2]=~s/\)$//; - if($f){ - my($warn,$crit) = split/\//, $data[2]; - unless($warn=~m/\d+/){ $warn = 0; } - unless($crit=~m/\d+/){ $crit = 200; } - $val{$index}{'Probe Name'} = "$f"; - $val{$index}{'Reading'} = "$data[0]"; - $val{$index}{'Warning Threshold'} = ($crit - $warn); - $val{$index}{'Critical Threshold'} = "$crit"; - $index++; - } - } - } - - if ($ARGV[0] && $ARGV[0] eq "config") { - print "graph_title IPMI sensors - Temperature Probes\n"; - print "graph_args --base 1000 -l 0\n"; - print "graph_vlabel Temperature in Celsius\n"; - print "graph_category Sensors\n"; - foreach my $j (sort keys %val) { - print "probe_$j\.label $val{$j}{'Probe Name'}\n"; - print "probe_$j\.warning $val{$j}{'Warning Threshold'}\n"; - print "probe_$j\.critical $val{$j}{'Critical Threshold'}\n"; - } - }else{ - foreach my $j (sort keys %val) { - if($val{$j}{'Reading'}){ - print "probe_$j.value $val{$j}{'Reading'}\n"; - } - } - } -} -exit(0); - diff --git a/plugins/ipmi/ipmisens-v3 b/plugins/ipmi/ipmisens-v3 deleted file mode 100755 index 73d18afa..00000000 --- a/plugins/ipmi/ipmisens-v3 +++ /dev/null @@ -1,865 +0,0 @@ -#!/usr/bin/perl -w -# -# ipmisens3 -# Munin plugin to read IPMI sensor data -# Zoltan HERPAI (c) 2009 -# -# Symlink this script into your /etc/munin/plugins directory in the -# following way: -# -# ipmisens2_[machine]_[sensors] -# -# Supported machines: -# - Asus K8N-LR: asmb2 (temp, volt, fan) -# - Dell DCS-XS23: xs23 (temp, volt, fan) -# - Dell M610 blade: m610 (temp) -# - Dell PowerEdge 2650: pe2650 (temp, volt, fan) -# - Fujitsu TX120: tx120 (temp, volt, fan) -# - HP Proliant ML350G5: proliantg5 (temp) -# - HP Proliant DL380G5: proliantg5 (temp) -# - HP Proliant DL385G1: hpasmcli (temp, fan) -# - IBM HS21/HS22/Dataplex DX360: ibmhsxx (volt) -# - IBM LS20/LS21: ibmlsxx (temp, volt) -# - IBM LS41: ibmls4x (temp, volt) -# - IBM x3200/x3550: ibmx3xx0 (temp, volt, fan) -# - IBM x346: x346 (temp, volt, fan) -# - Intel SHG2 mainboard: shg2 (temp, volt, fan) -# - Sun x2100/2100m2/2200/2200m2: x2100 (temp, volt, fan) -# - Sun x2250: x2250 (temp, volt, fan) -# - Sun x2270: x2270 (temp, volt, fan) -# - Sun x4100/4100m2/4200/4200m2/4600: x4x00 (temp, volt, fan) -# - Sun x4150: x4150 (temp, volt, fan) -# - Sun V20z (V40z?): v20z (temp, volt, fan) -# - Supermicro X7DB8/X7DCL: aocipmi20e (temp, volt, fan) -# - Supermicro X8DT6/X8DTT-F: hermon (temp, volt, fan) -# - Verari VB1205XM: vb1205 (temp, volt) -# -# Supported but not tested: -# - HP DL145G2: asmb2 (temp, volt, fan) -# -# Notes: -# - hpasmcli machtype requires HP's hpasmcli package, and the additional -# hpasmcliget script. -# -# Outputs submitted by: -# - Zoltan LAJBER -# - Gergely MADARASZ -# - Louis van Belle -# - Andras GOT -# - Andras KORN -# - Tamas TEVESZ -# - Gergely TOMKA -# - Gabor SZOLLOSI -# - Reka KAROLYI -# - Andras HORVATH -# -# CHANGELOG -# -# Revision 3.01 2010/09/23 Zoltan HERPAI -# * Add support for handling non-ipmitool-based machtypes -# * Add support for HP Proliant DL385G1 -# -# Revision 3.00 2010/05/25 Zoltan HERPAI -# * Add support for Supermicro X7DB8 via AOC IPMI20-E (aocipmi20e) -# * Add support for Supermicro X7DCL via AOC IPMI20-E (aocipmi20e) -# * Add support for Supermicro X8DT6 via Winbond Hermon BMC (hermon) -# * Add support for Supermicro X8DTT-F via Winbond Hermon BMC (hermon) -# * Add support for Dell M610 (m610) -# * Add support for HP DL380G5 (proliantg5) -# * Add support for HP ML350G5 (proliantg5) -# * Re-add support for Asus K8N-LR via ASMB2 (asmb2) -# * Add to-be-tested support for HP DL145G2 as per Paulo@muninexchange (asmb2) -# -# Revision 3.00early4 2010/01/09 Zoltan HERPAI -# * Add support for IBM HS22 (ibmhsxx) -# * Add support for IBM iDataplex DX360 (ibmhsxx) -# * Add support for Dell DCS XS23-sc (xs23) -# -# Revision 3.00early3 2009/12/30 Zoltan HERPAI -# * Support for easier debugging ($debug) -# * Add support for IBM LS41 (ibmls4x) -# * Add complete support for Sun x2270 (x2270) -# * Add support for Sun x4500 (x4x00) -# * Add support for Fujitsu-Siemens TX120 (tx120) -# -# Revision 3.00early2 2009/09/09 Zoltan HERPAI -# * Minor bugfix due to munin brain damage -# -# Revision 3.00early 2009/09/01 Zoltan HERPAI -# * Complete rewrite in perl. -# * Sun x2100, x2100M2 and x2200 are now supported in 'x2100' machtype -# * Bunch of new machtypes are supported -# - -use strict; -use warnings; -use POSIX; -use FindBin qw($Script); - -my $IPMITOOL = '/usr/bin/ipmitool'; -my $curtime = time(); -my $TEMPFILE = "/var/lib/munin/plugin-state/ipmisens3"; -# set the ipmidump expiration to 1 day -my $TEMPREFRESH = 86400; -my $debug = 0; -my $devel = 0; - -############## -# You should not need to edit anything below here -# -$ENV{PATH} = '/bin:/usr/bin:/usr/sbin'; -$ENV{IFS} = "\n"; - -$0 =~ /.*_(.*)_(.*)/; -my $machine = $1; -my $sensor = $2; - -# Test if ipmitool is available -if ( !$devel ) -{ - if ( $machine ne 'hpasmcli' ) { - `$IPMITOOL help 2> /dev/null`; - if ($?) - { - print "no ($IPMITOOL not found)"; - exit 1; - } - } -} - - -print "Machine: $machine , sensor: $sensor\n" if ($debug); - -# check expiration time of the dumpfile -if ( !$devel ) -{ - if ( $machine ne 'hpasmcli' ) { - if ( -f $TEMPFILE && $curtime - (stat($TEMPFILE))[9] >= $TEMPREFRESH ) - { - print "Unlinking $TEMPFILE...\n" if ($debug); - unlink ($TEMPFILE); - } - } -} - -if ( !$devel ) -{ - if ( $machine ne 'hpasmcli' ) { - if ( ! -f $TEMPFILE ) - { - print "Writing dumpfile $TEMPFILE...\n" if ($debug); - `$IPMITOOL sdr dump $TEMPFILE` || die $!; - if ($?) - { - print "no (retcode $?)\n"; - exit 2; - } - } - } -} - -my @ipmioutput; - -# Read the sensors -if ( $machine ne 'hpasmcli' ) { - @ipmioutput = `$IPMITOOL sdr -S $TEMPFILE`; -} -else { - @ipmioutput = `cat /tmp/ipmi-sensors`; -} -#my @ipmioutput = `cat ~wigyori/ipmisens2/outputs/hp_ml350g5`; - -if ($?) -{ - print "no (retcode $?)\n"; - exit 3; -} - -my $arg; -if ( defined($ARGV[0]) && $ARGV[0] ne "" ) -{ - print "argv: ".$ARGV[0]."\n" if ($debug); - if ( $ARGV[0] eq 'config' ) { $arg = 'config'; } - if ( $ARGV[0] eq 'autoconf' ) { $arg = 'autoconf'; } - - if ( $arg eq 'autoconf' ) { print "no\n"; exit 0; } - - my %cnf; - if ( $arg eq 'config' ) - { - # Base sensor config - if ( $sensor eq 'temp' ) - { - %cnf = ( - 'graph_title' => 'Temperature', - 'graph_vlabel' => 'C', - 'graph_category' => 'sensors', - ); - } - - if ( $sensor eq 'volt' ) - { - %cnf = ( - 'graph_title' => 'Voltages', - 'graph_vlabel' => 'Volts', - 'graph_category' => 'sensors', - ); - } - - if ( $sensor eq 'fan' ) - { - if ( $machine ne 'hpasmcli' ) { - %cnf = ( - 'graph_title' => 'Fan speeds', - 'graph_vlabel' => 'RPM', - 'graph_category' => 'sensors', - ); - } - else { - %cnf = ( - 'graph_title' => 'Fan speeds', - 'graph_vlabel' => '%', - 'graph_category' => 'sensors', - ); - } - } - - # Static descriptors - my %base; - - # Sun x4100 - $base{'x4x00'}->{'mbt_amb'} = 'Mainboard'; - $base{'x4x00'}->{'fpt_amb'} = 'FP'; - $base{'x4x00'}->{'pdbt_amb'} = 'PSU'; - $base{'x4x00'}->{'iot_amb'} = 'Disks'; - $base{'x4x00'}->{'p0t_core'} = 'CPU0'; - $base{'x4x00'}->{'p1t_core'} = 'CPU1'; - $base{'x4x00'}->{'ft0fm0f0'} = 'ft0.fm0.f0'; - $base{'x4x00'}->{'ft0fm1f0'} = 'ft0.fm1.f0'; - $base{'x4x00'}->{'ft0fm2f0'} = 'ft0.fm2.f0'; - $base{'x4x00'}->{'ft0fm0f1'} = 'ft0.fm0.f1'; - $base{'x4x00'}->{'ft0fm1f1'} = 'ft0.fm1.f1'; - $base{'x4x00'}->{'ft0fm2f1'} = 'ft0.fm2.f1'; - $base{'x4x00'}->{'ft1fm0f0'} = 'ft1.fm0.f0'; - $base{'x4x00'}->{'ft1fm1f0'} = 'ft1.fm1.f0'; - $base{'x4x00'}->{'ft1fm2f0'} = 'ft1.fm2.f0'; - $base{'x4x00'}->{'ft1fm0f1'} = 'ft1.fm0.f1'; - $base{'x4x00'}->{'ft1fm1f1'} = 'ft1.fm1.f1'; - $base{'x4x00'}->{'ft1fm2f1'} = 'ft1.fm2.f1'; - $base{'x4x00'}->{'mbv_bat'} = 'BAT'; - $base{'x4x00'}->{'mbv_3v3stby'} = '3.3VSTBY'; - $base{'x4x00'}->{'mbv_3v3'} = '3.3V'; - $base{'x4x00'}->{'mbv_5v'} = '5V'; - $base{'x4x00'}->{'mbv_12v'} = '+12V'; - $base{'x4x00'}->{'mbv_dash12v'} = '-12V'; - $base{'x4x00'}->{'mbv_2v5core'} = 'MB 2.5V'; - $base{'x4x00'}->{'mbv_1v8core'} = 'MB 1.8V'; - $base{'x4x00'}->{'mbv_1v2core'} = 'MB 1.2V'; - $base{'x4x00'}->{'p0v_1v5'} = 'CPU0 1.5V'; - $base{'x4x00'}->{'p0v_2v5core'} = 'CPU0 2.5V'; - $base{'x4x00'}->{'p0v_1v25core'} = 'CPU0 1.25V'; - $base{'x4x00'}->{'p1v_1v5'} = 'CPU1 1.5V'; - $base{'x4x00'}->{'p1v_2v5core'} = 'CPU1 2.5V'; - $base{'x4x00'}->{'p1v_1v25core'} = 'CPU1 1.25V'; - # Sun x4100m2 extents - $base{'x4x00'}->{'mbv_1v5core'} = 'MB 1.5V'; - $base{'x4x00'}->{'p0v_vddio'} = 'CPU0 VDDIO'; - $base{'x4x00'}->{'p0v_vdd'} = 'CPU0 VDD'; - $base{'x4x00'}->{'p0v_vtt'} = 'CPU0 VTT'; - $base{'x4x00'}->{'p1v_vddio'} = 'CPU1 VDDIO'; - $base{'x4x00'}->{'p1v_vdd'} = 'CPU1 VDD'; - $base{'x4x00'}->{'p1v_vtt'} = 'CPU1 VTT'; - # Sun x4600 voltage extents - $base{'x4x00'}->{'mbv_1v2'} = 'MB +1.2V'; - $base{'x4x00'}->{'mbv_1v5'} = 'MB +1.5V'; - $base{'x4x00'}->{'mbv_2v5'} = 'MB +2.5V'; - $base{'x4x00'}->{'mbv_3v3aux_r'} = 'MB +3.3VAUX'; - $base{'x4x00'}->{'p0v_12v'} = 'CPU0 module +12V'; - $base{'x4x00'}->{'p1v_12v'} = 'CPU1 module +12V'; - $base{'x4x00'}->{'p2v_12v'} = 'CPU2 module +12V'; - $base{'x4x00'}->{'p3v_12v'} = 'CPU3 module +12V'; - $base{'x4x00'}->{'p4v_12v'} = 'CPU4 module +12V'; - $base{'x4x00'}->{'p5v_12v'} = 'CPU5 module +12V'; - $base{'x4x00'}->{'p6v_12v'} = 'CPU6 module +12V'; - $base{'x4x00'}->{'p7v_12v'} = 'CPU7 module +12V'; - $base{'x4x00'}->{'p0v_2v5'} = 'CPU0 module +2.5V'; - $base{'x4x00'}->{'p1v_2v5'} = 'CPU1 module +2.5V'; - $base{'x4x00'}->{'p2v_2v5'} = 'CPU2 module +2.5V'; - $base{'x4x00'}->{'p3v_2v5'} = 'CPU3 module +2.5V'; - $base{'x4x00'}->{'p4v_2v5'} = 'CPU4 module +2.5V'; - $base{'x4x00'}->{'p5v_2v5'} = 'CPU5 module +2.5V'; - $base{'x4x00'}->{'p6v_2v5'} = 'CPU6 module +2.5V'; - $base{'x4x00'}->{'p7v_2v5'} = 'CPU7 module +2.5V'; - $base{'x4x00'}->{'p0v_1v2'} = 'CPU0 module +1.2V'; - $base{'x4x00'}->{'p1v_1v2'} = 'CPU1 module +1.2V'; - $base{'x4x00'}->{'p2v_1v2'} = 'CPU2 module +1.2V'; - $base{'x4x00'}->{'p3v_1v2'} = 'CPU3 module +1.2V'; - $base{'x4x00'}->{'p4v_1v2'} = 'CPU4 module +1.2V'; - $base{'x4x00'}->{'p5v_1v2'} = 'CPU5 module +1.2V'; - $base{'x4x00'}->{'p6v_1v2'} = 'CPU6 module +1.2V'; - $base{'x4x00'}->{'p7v_1v2'} = 'CPU7 module +1.2V'; - $base{'x4x00'}->{'p0v_3v3aux_r'} = 'CPU0 module +3.3VAUX'; - $base{'x4x00'}->{'p1v_3v3aux_r'} = 'CPU1 module +3.3VAUX'; - $base{'x4x00'}->{'p2v_3v3aux_r'} = 'CPU2 module +3.3VAUX'; - $base{'x4x00'}->{'p3v_3v3aux_r'} = 'CPU3 module +3.3VAUX'; - $base{'x4x00'}->{'p4v_3v3aux_r'} = 'CPU4 module +3.3VAUX'; - $base{'x4x00'}->{'p5v_3v3aux_r'} = 'CPU5 module +3.3VAUX'; - $base{'x4x00'}->{'p6v_3v3aux_r'} = 'CPU6 module +3.3VAUX'; - $base{'x4x00'}->{'p7v_3v3aux_r'} = 'CPU7 module +3.3VAUX'; - $base{'x4x00'}->{'p0v_3v3led'} = 'CPU0 module +3.3V LED'; - $base{'x4x00'}->{'p1v_3v3led'} = 'CPU1 module +3.3V LED'; - $base{'x4x00'}->{'p2v_3v3led'} = 'CPU2 module +3.3V LED'; - $base{'x4x00'}->{'p3v_3v3led'} = 'CPU3 module +3.3V LED'; - $base{'x4x00'}->{'p4v_3v3led'} = 'CPU4 module +3.3V LED'; - $base{'x4x00'}->{'p5v_3v3led'} = 'CPU5 module +3.3V LED'; - $base{'x4x00'}->{'p6v_3v3led'} = 'CPU6 module +3.3V LED'; - $base{'x4x00'}->{'p7v_3v3led'} = 'CPU7 module +3.3V LED'; - $base{'x4x00'}->{'p2v_1v25core'} = 'CPU2 1.25V'; - $base{'x4x00'}->{'p3v_1v25core'} = 'CPU3 1.25V'; - $base{'x4x00'}->{'p4v_1v25core'} = 'CPU4 1.25V'; - $base{'x4x00'}->{'p5v_1v25core'} = 'CPU5 1.25V'; - $base{'x4x00'}->{'p6v_1v25core'} = 'CPU6 1.25V'; - $base{'x4x00'}->{'p7v_1v25core'} = 'CPU7 1.25V'; - $base{'x4x00'}->{'p0v_core'} = 'CPU0 Vcore'; - $base{'x4x00'}->{'p1v_core'} = 'CPU1 Vcore'; - $base{'x4x00'}->{'p2v_core'} = 'CPU2 Vcore'; - $base{'x4x00'}->{'p3v_core'} = 'CPU3 Vcore'; - $base{'x4x00'}->{'p4v_core'} = 'CPU4 Vcore'; - $base{'x4x00'}->{'p5v_core'} = 'CPU5 Vcore'; - $base{'x4x00'}->{'p6v_core'} = 'CPU6 Vcore'; - $base{'x4x00'}->{'p7v_core'} = 'CPU7 Vcore'; - # Sun x4600 temp extents - $base{'x4x00'}->{'p2t_core'} = 'CPU2'; - $base{'x4x00'}->{'p3t_core'} = 'CPU3'; - $base{'x4x00'}->{'p4t_core'} = 'CPU4'; - $base{'x4x00'}->{'p5t_core'} = 'CPU5'; - $base{'x4x00'}->{'p6t_core'} = 'CPU6'; - $base{'x4x00'}->{'p7t_core'} = 'CPU7'; - $base{'x4x00'}->{'p0t_amb'} = 'CPU0 module'; - $base{'x4x00'}->{'p1t_amb'} = 'CPU1 module'; - $base{'x4x00'}->{'p2t_amb'} = 'CPU2 module'; - $base{'x4x00'}->{'p3t_amb'} = 'CPU3 module'; - $base{'x4x00'}->{'p4t_amb'} = 'CPU4 module'; - $base{'x4x00'}->{'p5t_amb'} = 'CPU5 module'; - $base{'x4x00'}->{'p6t_amb'} = 'CPU6 module'; - $base{'x4x00'}->{'p7t_amb'} = 'CPU7 module'; - $base{'x4x00'}->{'mbt_amb0'} = 'System board 0'; - $base{'x4x00'}->{'mbt_amb1'} = 'System board 1'; - $base{'x4x00'}->{'mbt_amb2'} = 'System board 2'; - # Sun x4500 voltage extents - $base{'x4x00'}->{'procp0v_1v25'} = 'CPU0 1.25V'; - $base{'x4x00'}->{'procp1v_1v25'} = 'CPU1 1.25V'; - $base{'x4x00'}->{'procp0v_1v5'} = 'CPU0 1.5V'; - $base{'x4x00'}->{'procp1v_1v5'} = 'CPU1 1.5V'; - $base{'x4x00'}->{'procp0v_2v5'} = 'CPU0 2.5V'; - $base{'x4x00'}->{'procp1v_2v5'} = 'CPU1 2.5V'; - $base{'x4x00'}->{'procv_1v8'} = 'CPU 1.8V'; - $base{'x4x00'}->{'iov_1v5'} = 'IO 1.5V'; - $base{'x4x00'}->{'iov_2v5'} = 'IO 2.5V'; - $base{'x4x00'}->{'iov_5v_disk'} = 'IO 5V disk'; - $base{'x4x00'}->{'iov_dash12v'} = 'IO -12V'; - # Sun x4500 temp extents - $base{'x4x00'}->{'iofrontt_amb'} = 'IO front'; - $base{'x4x00'}->{'ioreart_amb'} = 'IO rear'; - $base{'x4x00'}->{'procfrontt_amb'} = 'CPU front'; - $base{'x4x00'}->{'procreart_amb'} = 'CPU rear'; - $base{'x4x00'}->{'procp0t_core'} = 'CPU0 temp'; - $base{'x4x00'}->{'procp1t_core'} = 'CPU1 temp'; - $base{'x4x00'}->{'dbpt_amb'} = 'DBP'; - - # Sun V20z (V40z?) - $base{'v20z'}->{'ambient'} = 'System'; - $base{'v20z'}->{'cpu0die'} = 'CPU0 die'; - $base{'v20z'}->{'cpu0mem'} = 'CPU0 mem'; - $base{'v20z'}->{'cpu1die'} = 'CPU1 die'; - $base{'v20z'}->{'cpu1mem'} = 'CPU1 mem'; - $base{'v20z'}->{'gbeth'} = 'GBNIC'; - $base{'v20z'}->{'hddbp'} = 'HDD backplane'; - $base{'v20z'}->{'sp'} = 'Service CPU'; - - # Sun x2100 - $base{'x2100'}->{'cpucorevoltage'} = 'CPU core'; - $base{'x2100'}->{'batteryvolt'} = 'VBAT'; - $base{'x2100'}->{'ddr26v'} = 'DDR 2.6V'; - $base{'x2100'}->{'vcc33v'} = '+3.3V'; - $base{'x2100'}->{'vcc5v'} = '+5V'; - $base{'x2100'}->{'vcc12v'} = '+12V'; - $base{'x2100'}->{'cputemp'} = 'CPU'; - $base{'x2100'}->{'system'} = 'System'; - # Sun x2100M2 extents - $base{'x2100'}->{'ddrp118v'} = 'DDR P1 1.8V'; - $base{'x2100'}->{'vcc33vstb'} = '+3.3VSTBY'; - $base{'x2100'}->{'ambienttemp'} = 'System'; - # Sun x2200 extents - $base{'x2100'}->{'ddrp018v'} = 'DDR P0 1.8V'; - $base{'x2100'}->{'ambienttemp0'} = 'System temp 0'; - $base{'x2100'}->{'ambienttemp1'} = 'System temp 1'; - $base{'x2100'}->{'cpu0temp'} = 'CPU0 temp'; - $base{'x2100'}->{'cpu1temp'} = 'CPU1 temp'; - - # Intel SHG2 - $base{'shg2'}->{'baseboard12v'} = 'MB 12V'; - $base{'shg2'}->{'baseboard15v'} = 'MB 1.5V'; - $base{'shg2'}->{'baseboard25v'} = 'MB 2.5V'; - $base{'shg2'}->{'baseboard33v'} = 'MB 3.3V'; - $base{'shg2'}->{'baseboard33vsb'} = '3.3VSTBY'; - $base{'shg2'}->{'baseboard5v'} = 'MB 5V'; - $base{'shg2'}->{'baseboarddash12v'} = 'MB -12V'; - $base{'shg2'}->{'batteryvoltage'} = 'VBAT'; - $base{'shg2'}->{'processorvrm'} = 'VRM'; - - # IBM x346 - $base{'x346'}->{'125vsense'} = '+1.25V'; - $base{'x346'}->{'12vasense'} = '+12V A'; - $base{'x346'}->{'12vbsense'} = '+12V B'; - $base{'x346'}->{'12vcsense'} = '+12V C'; - $base{'x346'}->{'13vsense'} = '+1.3V'; - $base{'x346'}->{'15vsense'} = '+1.5V'; - $base{'x346'}->{'18vsense'} = '+1.8V'; - $base{'x346'}->{'25vsense'} = '+2.5V'; - $base{'x346'}->{'5vsense'} = '+5V'; - $base{'x346'}->{'cpu1vcore'} = 'CPU1 Vcore'; - $base{'x346'}->{'cpu2vcore'} = 'CPU2 Vcore'; - $base{'x346'}->{'cpuvtt'} = 'CPU VTT'; - $base{'x346'}->{'dash12vsense'} = '-12V'; - $base{'x346'}->{'vbat'} = 'VBAT'; - $base{'x346'}->{'cpu1'} = 'CPU1'; - $base{'x346'}->{'cpu2'} = 'CPU2'; - $base{'x346'}->{'dasd'} = 'DASD'; - $base{'x346'}->{'ambient'} = 'System'; - - # Sun x2250 - $base{'x2250'}->{'3v3_stby'} = '3.3VSTBY'; - $base{'x2250'}->{'3v3'} = '+3.3V'; - $base{'x2250'}->{'5v'} = '+5V'; - $base{'x2250'}->{'12v'} = '+12V'; - $base{'x2250'}->{'1v5'} = '+1.5V'; - $base{'x2250'}->{'1v8'} = '+1.8V'; - $base{'x2250'}->{'0v9'} = '+0.9V'; - $base{'x2250'}->{'vtt'} = 'VTT'; - $base{'x2250'}->{'1v5_esb'} = 'ESB +1.5V'; - $base{'x2250'}->{'1v2_nic'} = 'NIC +1.2V'; - $base{'x2250'}->{'1v8_nic'} = 'NIC +1.8V'; - $base{'x2250'}->{'1v5_fbd'} = 'FBDIMM +1.5V'; - - # Sun x2270 - $base{'x2270'}->{'3v3_stby'} = '3.3VSTBY'; - $base{'x2270'}->{'3v3'} = '+3.3V'; - $base{'x2270'}->{'5v'} = '+5V'; - $base{'x2270'}->{'12v'} = '+12V'; - $base{'x2270'}->{'3v3_vbat'} = '3.3VBAT'; - $base{'x2270'}->{'1v5'} = '+1.5V'; - $base{'x2270'}->{'p0_1v5_ddr'} = 'DDR P0 +1.5V'; - $base{'x2270'}->{'p1_1v5_ddr'} = 'DDR P1 +1.5V'; - $base{'x2270'}->{'p0_1v8'} = 'P0 +1.8V'; - $base{'x2270'}->{'p1_1v8'} = 'P1 +1.8V'; - $base{'x2270'}->{'p0_vtt'} = 'P0 VTT'; - $base{'x2270'}->{'p1_vtt'} = 'P1 VTT'; - $base{'x2270'}->{'p0_vccp'} = 'P0 VCCp'; - $base{'x2270'}->{'p1_vccp'} = 'P1 VCCp'; - - # Sun x4150 - $base{'x4150'}->{'mb_t_amb0'} = 'MB Sensor 0'; - $base{'x4150'}->{'mb_t_amb1'} = 'MB Sensor 1'; - $base{'x4150'}->{'mb_t_amb2'} = 'MB Sensor 2'; - $base{'x4150'}->{'mb_t_amb3'} = 'MB Sensor 3'; - $base{'x4150'}->{'ps0_t_amb'} = 'PS 1 temp'; - $base{'x4150'}->{'ps1_t_amb'} = 'PS 2 temp'; - $base{'x4150'}->{'t_amb'} = 'System'; - $base{'x4150'}->{'ps0_f0'} = 'PS 1 fan'; - $base{'x4150'}->{'ps1_f0'} = 'PS 2 fan'; - $base{'x4150'}->{'mb_p0_v_vcc'} = 'CPU0 VCC'; - $base{'x4150'}->{'mb_p1_v_vcc'} = 'CPU1 VCC'; - $base{'x4150'}->{'mb_v_12v'} = '+12V'; - $base{'x4150'}->{'mb_v_1v5'} = '+1.5V'; - $base{'x4150'}->{'mb_v_1v8'} = '+1.8V'; - $base{'x4150'}->{'mb_v_2v5stby'} = '+2.5VSTBY'; - $base{'x4150'}->{'mb_v_3v3'} = '+3.3V'; - $base{'x4150'}->{'mb_v_3v3stby'} = '+3.3VSTBY'; - $base{'x4150'}->{'mb_v_5v'} = '+5V'; - $base{'x4150'}->{'mb_v_nic'} = 'NIC'; - $base{'x4150'}->{'mb_v_vtt'} = 'VTT'; - $base{'x4150'}->{'ps0_v_in'} = 'PS 1 voltage in'; - $base{'x4150'}->{'ps0_v_out'} = 'PS 1 voltage out'; - $base{'x4150'}->{'ps1_v_in'} = 'PS 2 voltage in'; - $base{'x4150'}->{'ps1_v_out'} = 'PS 2 voltage out'; - - # Verari VB1205XM - $base{'vb1205'}->{'12v'} = '+12V'; - $base{'vb1205'}->{'1_2v'} = '+1.2V'; - $base{'vb1205'}->{'1_5v'} = '+1.5V'; - $base{'vb1205'}->{'3_3v'} = '+3.3V'; - $base{'vb1205'}->{'5v'} = '+5V'; - $base{'vb1205'}->{'5vsb'} = '+5VSTBY'; - $base{'vb1205'}->{'cpu1vcore'} = 'CPU1 Vcore'; - $base{'vb1205'}->{'cpu2vcore'} = 'CPU2 Vcore'; - $base{'vb1205'}->{'dash12v'} = '-12V'; - $base{'vb1205'}->{'vbat'} = 'VBAT'; - $base{'vb1205'}->{'cputemp1'} = 'CPU 1 temp'; - $base{'vb1205'}->{'cputemp2'} = 'CPU 2 temp'; - $base{'vb1205'}->{'systemp'} = 'System'; - - # Dell PowerEdge 2650 - $base{'pe2650'}->{'esmmbfan1'} = 'Fan 1'; - $base{'pe2650'}->{'esmmbfan2'} = 'Fan 2'; - $base{'pe2650'}->{'esmmbfan3'} = 'Fan 3'; - $base{'pe2650'}->{'esmmbfan4'} = 'Fan 4'; - $base{'pe2650'}->{'esmmbfan5'} = 'Fan 5'; - $base{'pe2650'}->{'esmmbfan6'} = 'Fan 6'; - $base{'pe2650'}->{'esmmbfan7'} = 'Fan 7'; - $base{'pe2650'}->{'esmmb12'} = 'MB +12V'; - $base{'pe2650'}->{'esmmb25'} = 'MB +2.5V'; - $base{'pe2650'}->{'esmmb33'} = 'MB +3.3V'; - $base{'pe2650'}->{'esmmb5'} = 'MB +5V'; - $base{'pe2650'}->{'esmmbbat'} = 'VBAT'; - $base{'pe2650'}->{'esmmbdash12'} = 'MB -12V'; - $base{'pe2650'}->{'esmrombpk'} = 'ROMB PK'; - $base{'pe2650'}->{'esmvtt'} = 'VTT'; - $base{'pe2650'}->{'esmcpu'} = 'CPU'; - $base{'pe2650'}->{'esm5aux'} = '5V AUX'; - $base{'pe2650'}->{'esmcpu1'} = 'CPU1'; - $base{'pe2650'}->{'esmcpu2'} = 'CPU2'; - $base{'pe2650'}->{'esmfrti_o'} = 'Front I/O'; - $base{'pe2650'}->{'esmriser'} = 'Riser'; - - # IBM x3200 - $base{'ibmx3xx0'}->{'planar12v'} = '+12V'; - $base{'ibmx3xx0'}->{'planar15v'} = '+1.5V'; - $base{'ibmx3xx0'}->{'planar18v'} = '+1.8V'; - $base{'ibmx3xx0'}->{'planar33v'} = '+3.3V'; - $base{'ibmx3xx0'}->{'planar5v'} = '+5V'; - $base{'ibmx3xx0'}->{'cpuvcore'} = 'CPU Vcore'; - $base{'ibmx3xx0'}->{'cpuvtt'} = 'VTT'; - $base{'ibmx3xx0'}->{'ambient'} = 'System'; - $base{'ibmx3xx0'}->{'cpu'} = 'CPU'; - # IBM x3550 extents - $base{'ibmx3xx0'}->{'planarvbat'} = 'VBAT'; - - # IBM LS41 - $base{'ibmlsxx'}->{'12vsense'} = '+12V'; - $base{'ibmlsxx'}->{'3_3vsense'} = '+3.3V'; - $base{'ibmlsxx'}->{'5vsense'} = '+5V'; - $base{'ibmlsxx'}->{'planarvbat'} = 'VBAT'; - # IBM LS20 extents - $base{'ibmlsxx'}->{'1_8vsense'} = '+1.8V'; - $base{'ibmlsxx'}->{'1_8vsbsense'} = '+1.8VSB'; - $base{'ibmlsxx'}->{'12vsbsense'} = '+12VSB'; - $base{'ibmlsxx'}->{'12v_isense'} = '+12V_I'; - - # IBM HS21 - $base{'ibmhsxx'}->{'planar0_9v'} = '+0.9V'; - $base{'ibmhsxx'}->{'planar12v'} = '+12V'; - $base{'ibmhsxx'}->{'planar3_3v'} = '+3.3V'; - $base{'ibmhsxx'}->{'planar5v'} = '+5V'; - $base{'ibmhsxx'}->{'planarvbat'} = 'VBAT'; - # IBM iDataplex DX320 extents - $base{'ibmhsxx'}->{'cpu1vcore'} = 'CPU1 Vcore'; - $base{'ibmhsxx'}->{'cpu2vcore'} = 'CPU2 Vcore'; - - # Fujitsu-Siemens TX120 - $base{'tx120'}->{'12v'} = '12V'; - $base{'tx120'}->{'15v'} = '1.5V'; - $base{'tx120'}->{'18v'} = '1.8V'; - $base{'tx120'}->{'33v'} = '3.3V'; - $base{'tx120'}->{'5v'} = '5V'; - $base{'tx120'}->{'dash12v'} = '-12V'; - $base{'tx120'}->{'stdby33v'} = '3.3VSTBY'; - $base{'tx120'}->{'vtt'} = 'VTT'; - $base{'tx120'}->{'battery3v'} = '3VBAT'; - $base{'tx120'}->{'fanpsu'} = 'Fan PSU'; - $base{'tx120'}->{'fan1sys'} = 'Fan Sys 1'; - $base{'tx120'}->{'fan2sys'} = 'Fan Sys 2'; - $base{'tx120'}->{'fancpu'} = 'Fan CPU'; - $base{'tx120'}->{'ambient'} = 'Ambient'; - $base{'tx120'}->{'systemboard'} = 'System board'; - $base{'tx120'}->{'cpu'} = 'CPU'; - - # Dell DCS XS23-sc - $base{'xs23'}->{'systemfan'} = 'System fan'; - $base{'xs23'}->{'cpu0'} = 'CPU 0'; - $base{'xs23'}->{'cpu1'} = 'CPU 1'; - $base{'xs23'}->{'midplane'} = 'Midplane'; - $base{'xs23'}->{'p12v'} = 'Planar 12V'; - $base{'xs23'}->{'p15v'} = 'Planar 1.5V'; - $base{'xs23'}->{'p18v'} = 'Planar 1.8V'; - $base{'xs23'}->{'p33v'} = 'Planar 3.3V'; - $base{'xs23'}->{'p5v'} = 'Planar 5V'; - $base{'xs23'}->{'vtt'} = 'Vtt'; - $base{'xs23'}->{'vcc33vaux'} = 'Vcc 3.3V AUX'; - - # Supermicro X8DT6 / X8DTT-F via Winbond Hermon BMC - $base{'hermon'}->{'fan1'} = 'Fan 1'; - $base{'hermon'}->{'fan2'} = 'Fan 2'; - $base{'hermon'}->{'fan3'} = 'Fan 3'; - $base{'hermon'}->{'fan4'} = 'Fan 4'; - $base{'hermon'}->{'fan5'} = 'Fan 5'; - $base{'hermon'}->{'fan6'} = 'Fan 6'; - $base{'hermon'}->{'fan7'} = 'Fan 7'; - $base{'hermon'}->{'fan8'} = 'Fan 8'; - $base{'hermon'}->{'system'} = 'System'; - $base{'hermon'}->{'cpu1temp'} = 'CPU1 temp'; - $base{'hermon'}->{'cpu2temp'} = 'CPU2 temp'; - $base{'hermon'}->{'12v'} = '+12V'; - $base{'hermon'}->{'15v'} = '+1.5V'; - $base{'hermon'}->{'33v'} = '+3.3V'; - $base{'hermon'}->{'33vsb'} = '+3.3VSB'; - $base{'hermon'}->{'5v'} = '+5V'; - $base{'hermon'}->{'vbat'} = 'VBAT'; - $base{'hermon'}->{'cpu1dimm'} = 'CPU1 DIMM'; - $base{'hermon'}->{'cpu2dimm'} = 'CPU2 DIMM'; - $base{'hermon'}->{'cpu1vcore'} = 'CPU1 Vcore'; - $base{'hermon'}->{'cpu2vcore'} = 'CPU2 Vcore'; - - # Most of these are similar on the Supermicro X* boards - $base{'aocipmi20e'} = $base{'hermon'}; - $base{'aocipmi20e'}->{'dash12v'} = '-12V'; - $base{'aocipmi20e'}->{'5vsb'} = '+5VSB'; - $base{'aocipmi20e'}->{'fan7_cpu1'} = 'Fan7 / CPU1'; - $base{'aocipmi20e'}->{'fan8_cpu2'} = 'Fan8 / CPU2'; - $base{'aocipmi20e'}->{'sys'} = 'System'; - - # Asus K8N-LR / HP DL145G2 - $base{'asmb2'}->{'cpufan1'} = 'CPU Fan 1'; - $base{'asmb2'}->{'cpufan2'} = 'CPU Fan 2'; - $base{'asmb2'}->{'frontfan1'} = 'Front Fan 1'; - $base{'asmb2'}->{'frontfan2'} = 'Front Fan 2'; - $base{'asmb2'}->{'rearfan1'} = 'Rear Fan 1'; - $base{'asmb2'}->{'rearfan2'} = 'Rear Fan 2'; - $base{'asmb2'}->{'cpu1thermal'} = 'CPU1'; - $base{'asmb2'}->{'systemthermal'} = 'System'; - $base{'asmb2'}->{'25vor18v'} = '+2.5V / +1.8V'; - $base{'asmb2'}->{'bat_cmos'} = 'VBAT'; - $base{'asmb2'}->{'cpuvcore1'} = 'CPU1 Vcore'; - $base{'asmb2'}->{'system12v'} = '+12V'; - $base{'asmb2'}->{'system15v'} = '+1.5V'; - $base{'asmb2'}->{'system5v'} = '+5V'; - $base{'asmb2'}->{'system3v'} = '+3V'; - $base{'asmb2'}->{'system5vsb'} = '+5VSTBY'; - - # Dell M610 blade - $base{'m610'}->{'ambienttemp'} = 'Ambient temp'; - $base{'m610'}->{'temp'} = 'Blade temp'; - - # hpasmcli / Proliant DL385G1 - $base{'hpasmcli'}->{'cpu-1'} = 'CPU 1'; - $base{'hpasmcli'}->{'cpu-2'} = 'CPU 2'; - $base{'hpasmcli'}->{'i_o_zone'} = 'I/O zone'; - $base{'hpasmcli'}->{'power_supply_bay'} = 'PSU bay'; - $base{'hpasmcli'}->{'processor_zone'} = 'CPU zone'; - - # Machine config, run through the file/output - my $label; my $tmp; - foreach my $line ( @ipmioutput ) - { - $line =~ s/\s+/ /g; - if ( $sensor eq 'fan' && $line =~ /.*RPM.*ok/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\.speed.*/; $label = $1; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)\.tach.*/; $label = $1; } - if ( $machine eq 'x2100') { $line =~ s/(.*)\s+\|.*RPM.*/\L$1/; $label = $line; } - if ( $machine eq 'x346' ) { $line =~ /(.*) Tach.*/; $label = $1; } - if ( $machine eq 'shg2' ) { $line =~ s/(.*)\s+\|.*RPM.*\|\s+ok/$1/; $label = $1; } - if ( $machine eq 'x2250' ) { $line =~ /(.*)\/TACH.*RPM.*/; $label = $1; } - if ( $machine eq 'x2270' ) { $line =~ /(.*)\/TACH.*RPM.*/; $label = $1; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\/TACH.*RPM.*/; $label = $1; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) RPM\s+\|.*RPM.*/; $label = $1; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*) Tach.*/; $label = $1; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\s+\|.*RPM.*\|\s+ok/; $label = $1; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\s+\|.*RPM.*\|\s+ok/; $label = $1; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\s+\|.*RPM.*\|\s+ok/; $label = $1; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\s+\|.*RPM.*\|\s+ok/; $label = $1; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|.*RPM.*\|\s+ok/; $label = $1; } - - } - elsif ( $sensor eq 'fan' && $line =~ /\#\d+\s+\S+\s+Yes.*\%/ ) { - if ( $machine eq 'hpasmcli' ) { $line =~ /\#(\d+)\s+(.*)\s+Yes.*\%.*/; $label = "$2_$1"; } - } - - if ( $sensor eq 'temp' && $line =~ /.*degree.*ok/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\ \|.*deg.*/; $label = $1; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)temp.*/; $label = $1; } - if ( $machine eq 'x2100') { $line =~ s/(.*)\s+\|.*deg.*/\L$1/; $label = $line; } - if ( $machine eq 'x346' ) { $line =~ /(.*) Temp.*/; $label = $1; } - if ( $machine eq 'ibmls4x' ) { $line =~ /(.*) TEMP.*/; $label = $1; } - if ( $machine eq 'shg2' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'x2250' ) { $line =~ /MB\/T\_(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'x2270' ) { $line =~ /MB\/T\_(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'vb1205' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) Temp.*/; $label = $1; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*) Temp.*/; $label = $1; } - if ( $machine eq 'ibmlsxx' ) { $line =~ /(.*) TEMP.*/; $label = $1; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\ \|.*deg.*/; $label = $1; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\ Temp\s+|.*deg.*/; $label = $1; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\ Temp\s+|.*deg.*/; $label = $1; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\ Temp\s+|.*deg.*/; $label = $1; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'm610' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - if ( $machine eq 'proliantg5' ) { $line =~ /(.*)\s+\|.*deg.*/; $label = $1; } - } - elsif ( $sensor eq 'temp' && $line =~ /\d+C\/\d+F/ ) { - if ( $machine eq 'hpasmcli' ) { $line =~ /.*\s+(.*)\s+\d+C\/\d+F\s+\d+C\/\d+F/; $label = $1; } - } - - if ( $sensor eq 'volt' && $line =~ /.*Volts.*/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\ \|.*Volts.*/; $label = $1; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)\ \|.*Volts.*/; $label = $1; } - if ( $machine eq 'x2100') { $line =~ s/(.*)\s+\|.*Volts.*/\L$1/; $label = $line; } - if ( $machine eq 'x346' ) { $line =~ /(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'ibmls4x' ) { $line =~ /(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'shg2' ) { $line =~ /(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'x2250' ) { $line =~ /MB\/V\_(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'x2270' ) { $line =~ /MB\/(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; } - if ( $machine eq 'vb1205' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; $label =~ s/\./_/g; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) Volt\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; } - if ( $machine eq 'ibmlsxx' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; $label =~ s/\./_/g; } - if ( $machine eq 'ibmhsxx' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; $label =~ s/\./_/g; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\ \|.*Volts.*/; $label = $1; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\s+\|.*Volts.*/; $label = $1; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|\s+.*Volts.*/; $label = $1; } - } - - if ( $label ) - { - $label =~ s/\.//g; - $label =~ s/\-/dash/g; - $label =~ s/\+//; - $label =~ s/\s+//g; - $label =~ s/(.*)/\L$1/; - $label =~ s/\//_/g; - $label =~ s/\#/_/g; - - # Random fixups - if ( $machine eq 'x2270' ) { $label =~ s/v_//; } - if ( $machine eq 'x4x00' ) { $label =~ s/^sysv\_/mbv\_/; } - if ( $machine eq 'tx120' ) { $label =~ s/main//; } - - if ( $base{$machine}->{$label} ) - { - $cnf{ $label. '.label' } = $base{$machine}->{$label}; - } - else - { - $cnf{ $label. '.label' } = $label; - } - } - - undef ($label); - } - foreach my $key ( sort(keys(%cnf)) ) - { - print "$key $cnf{$key}\n"; - } - } - exit 0; -} - -my %res; my $label; my $value; -foreach my $line ( @ipmioutput ) -{ - $line =~ s/\s+/ /g; - if ( $sensor eq 'fan' && $line =~ /.*RPM.*ok/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\.speed\s+\|\s+(\d+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)\.tach\s+\|\s+(\d+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2100' ) { $line =~ s/(.*)\s+\|\s+(\S+) RPM.*/\L$1/; $label = $line; $value = $2; } - if ( $machine eq 'x346' ) { $line =~ /(.*) Tach\s+\| (\d+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'shg2' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|.*ok/; $label = $1; $value = $2; } - if ( $machine eq 'x2250' ) { $line =~ /(.*)\/TACH\s+\|\s+(.*) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2270' ) { $line =~ /(.*)\/TACH\s+\|\s+(.*) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\/TACH\s+\|\s+(\S+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) RPM\s+\|\s+(\S+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*) Tach\s+\|\s+(\S+) RPM.*/; $label = $1; $value = $2; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|\s+ok/; $label = $1; $value = $2; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|\s+ok/; $label = $1; $value = $2; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|\s+ok/; $label = $1; $value = $2; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|\s+ok/; $label = $1; $value = $2; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|\s+(.*) RPM.*\|\s+ok/; $label = $1; $value = $2; } - } - elsif ( $sensor eq 'fan' && $line =~ /\#\d+\s+\S+\s+Yes.*\%/ ) { - if ( $machine eq 'hpasmcli' ) { $line =~ /\#(\d+)\s+(.*)\s+Yes\s+\w+\s+(\d+)\%.*/; $label = "$2_$1"; $value = $3; } - } - - if ( $sensor eq 'temp' && $line =~ /.*degree.*ok/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)temp\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2100' ) { $line =~ s/(.*)\s+\|\s+(\d+) deg.*/\L$1/; $label = $line; $value = $2; } - if ( $machine eq 'x346' ) { $line =~ /(.*) Temp\s+\|\s+(\d+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmls4x' ) { $line =~ /(.*) TEMP\s+\|\s+(\d+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'shg2' ) { $line =~ /(.*)\s+\|\s+(\d+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2250' ) { $line =~ /MB\/T\_(.*)\s+\|\s+(\d+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2270' ) { $line =~ /MB\/T\_(.*)\s+\|\s+(\d+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\s+\|\s+(\S+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'vb1205' ) { $line =~ /(.*)\s+\|\s+(\S+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) Temp\s+\|\s+(\S+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*) Temp\s+\|\s+(\S+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmlsxx' ) { $line =~ /(.*) TEMP\s+\|\s+(\S+) deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\ Temp\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\ Temp\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\ Temp\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'm610' ) { $line =~ /(.*)\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - if ( $machine eq 'proliantg5' ) { $line =~ /(.*)\s+\|\s+(\S+)\ deg.*/; $label = $1; $value = $2; } - } - elsif ( $sensor eq 'temp' && $line =~ /\d+C\/\d+F/ ) { - if ( $machine eq 'hpasmcli' ) { $line =~ /.*\s+(.*)\s+(\d+)C\/\d+F\s+\d+C\/\d+F/; $label = $1; $value = $2; } - } - - if ( $sensor eq 'volt' && $line =~ /.*Volt.*ok/ ) - { - if ( $machine eq 'x4x00' ) { $line =~ /(.*)\ \|\s+(\S+)\ Volt.*/; $label = $1; $value = $2; } - if ( $machine eq 'v20z' ) { $line =~ /(.*)\s+\|\s+(\S+)\ Volt.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2100' ) { $line =~ s/(.*)\s+\|\s+(\S+)\ Volt.*/\L$1/; $label = $line; $value = $2; } - if ( $machine eq 'x346' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmls4x' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'shg2' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2250' ) { $line =~ /MB\/V\_(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'x2270' ) { $line =~ /MB\/(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'x4150' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'vb1205' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; $label =~ s/\./_/g; } - if ( $machine eq 'pe2650' ) { $line =~ /(.*) Volt\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmx3xx0' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'ibmlsxx' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; $label =~ s/\./_/g; } - if ( $machine eq 'ibmhsxx' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; $label =~ s/\./_/g; } - if ( $machine eq 'tx120' ) { $line =~ /(.*)\ \|\s+(\S+)\ Volt.*/; $label = $1; $value = $2; } - if ( $machine eq 'xs23' ) { $line =~ /(.*)\ \|\s+(\S+)\ Volt.*/; $label = $1; $value = $2; } - if ( $machine eq 'hermon' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'aocipmi20e' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - if ( $machine eq 'asmb2' ) { $line =~ /(.*)\s+\|\s+(\S+) Volts.*/; $label = $1; $value = $2; } - } - - if ( $label ) - { - $label =~ s/\.//g; - $label =~ s/\-/dash/g; - $label =~ s/\+//; - $label =~ s/\s+//g; - $label =~ s/(.*)/\L$1/; - $label =~ s/\//_/g; - $label =~ s/\#/_/g; - - # Random fixups - if ( $machine eq 'x2270' ) { $label =~ s/v_//; } - if ( $machine eq 'x4x00' ) { $label =~ s/^sysv\_/mbv\_/; } - if ( $machine eq 'tx120' ) { $label =~ s/main//; } - - - $res{$label} = $value; - } - undef ($label); -} - -my $key; -foreach $key ( sort(keys(%res)) ) -{ - print "$key.value ".$res{$key}."\n"; -} - diff --git a/plugins/ipmi/ipmisensors b/plugins/ipmi/ipmisensors deleted file mode 100755 index 1d84a20adc49957cfb88a37bb0ae800a53aa0d43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3155 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 { - regex => exists $ENV{'fan_type_regex'} ? qr/$ENV{'fan_type_regex'}/im : qr/RPM/im, - title => 'IPMITool Sensor: Fans', - vtitle => 'RPM', - print_threshold => \&fan_threshold, - graph_args => '--base 1000 -l 0' - }, - temp => { - regex => exists $ENV{'temp_type_regex'} ? qr/$ENV{'temp_type_regex'}/im : qr/degrees C/im, - title => 'IPMITool Sensor: Temperatures', - vtitle => 'Celsius', - print_threshold => \&temp_threshold, - graph_args => '--base 1000 -l 0' - }, - volt => { - regex => exists $ENV{'volt_type_regex'} ? qr/$ENV{'volt_type_regex'}/im : qr/(Volts|Watts|Amps)/im, - title => 'IPMITool Sensor: Voltages', - vtitle => '_AUTO_DETECT_FAILED_', - print_threshold => \&volt_threshold, - graph_args => '--base 1000' - }, -); - -if (defined $ARGV[0] and $ARGV[0] eq 'autoconf') { - close(STDERR); - my $ret = system($IPMITOOL); - open (STDERR, ">&STDOUT"); - if ($ret == 0 || $ret == 256) { - print "yes\n"; - exit 0; - } else { - print "no (program $IPMITOOL not found)\n"; - } - exit 1; -} - -if (defined $ARGV[0] and $ARGV[0] eq 'suggest') { - my $text = get_sensor_data(); - my $alltext = join('\n', @{$text}); - foreach my $func (keys %config) { - print $func, "\n" if $alltext =~ $config{$func}->{regex}; - } - exit; -} - -$0 =~ /ipmitool_sensor_(.+)*$/; -my $func = $1; -exit 2 unless defined $func; - -my $text = get_sensor_data(); -my $sensor = 1; - -if (defined $ARGV[0] and $ARGV[0] eq 'config') { - # detect the unit of volt - if ($func eq 'volt') { - foreach my $line (@{$text}) { - if ($line =~ /$config{$func}->{regex}/) { - my ($label, $value, $unit, $lcr, $lnc, $unc, $ucr) = &get_sensor_items($line, $config{$func}->{regex}); - $config{$func}->{vtitle} = $unit; - last; - } - } - $text = get_sensor_data(); - } - - # print header - print "graph_title $config{$func}->{title}\n"; - print "graph_vtitle $config{$func}->{vtitle}\n"; - print "graph_args $config{$func}->{graph_args}\n"; - print "graph_category sensors\n"; - - # print data - foreach my $line (@{$text}) { - if ($line =~ /$config{$func}->{regex}/) { - my ($label, $value, $unit, $lcr, $lnc, $unc, $ucr) = &get_sensor_items($line, $config{$func}->{regex}); - if (&is_valid_value($value)) { - print "$func$sensor.label $label\n"; - $config{$func}->{print_threshold}->($func.$sensor, $lcr, $lnc, $unc, $ucr); - print "$func$sensor.graph no\n" if exists $ENV{"ignore_$func$sensor"}; - $sensor++; - } - } - } - exit 0; -} - -foreach my $line (@{$text}) { - if ($line =~ /$config{$func}->{regex}/) { - my ($label, $value, $unit, $lcr, $lnc, $unc, $ucr) = &get_sensor_items($line, $config{$func}->{regex}); - # for debug - # print "$func$sensor.value [$label] [$value] [$lcr] [$lnc] [$unc] [$ucr]\n"; - if (&is_valid_value($value)) { - print "$func$sensor.value $value\n"; - $sensor++; - } - } -} - -sub get_sensor_data { - my $text = undef; - if (-f $CACHE_FILE) { - my $cache_timestamp = (stat($CACHE_FILE))[9]; - if ($CACHE_EXPIRES == -1 || time - $cache_timestamp <= $CACHE_EXPIRES) { - open(IN, "<", $CACHE_FILE) or die "Could not open \"$CACHE_FILE\" for reading\n"; - while () { - push (@{$text}, $_); - } - close(IN); - } - } - if (! defined $text) { - my $pid = open(EXE, '-|'); - if ($pid == 0) { - exec($IPMITOOL, @IPMITOOL_OPTS); - } elsif (defined $pid) { - while() { - push (@{$text}, $_); - } - close(EXE); - } else { - die "fork failed: $!"; - } - if (-w $CACHE_DIR) { - open(OUT, ">", $CACHE_FILE) or die "Could not open \"$CACHE_FILE\" for writing\n"; - foreach my $line (@{$text}) { - print OUT "$line"; - } - close OUT; - } - } - return $text; -} - -sub get_sensor_items { - my ($line, $regex) = @_; - my @items = split(/\s*\|\s*/, $line); - my ($label, $value, $unit, $lcr, $lnc, $unc, $ucr) - = (trim($items[0]), trim($items[1]), trim($items[2]), trim($items[5]), trim($items[6]), trim($items[7]), trim($items[8])); - if ($#items == 9) { - # ipmitool sensor - } elsif ($#items == 2) { - # ipmitool sdr - if ($value =~ /$regex/) { - $value = trim($`); - $unit = trim($1); - } - } - - # some boards show data in incorrect order. - # - HP ProLiant ML110 G5 - # CPU FAN | 1434.309 | RPM | ok | 5537.099 | 4960.317 | 4859.086 | na | 937.383 | na - # SYSTEM FAN | 1506.932 | RPM | ok | 5952.381 | 5668.934 | 5411.255 | na | 937.383 | na - # - HP ProLiant DL160 - # FAN1 ROTOR1 | 7680.492 | RPM | ok | na | inf | na | na | 1000.400 | na - if (&is_valid_value($lcr) && &is_valid_value($ucr) && $lcr > $ucr || $lcr eq 'inf') { - ($lcr, $lnc, $unc, $ucr) = ($ucr, $unc, $lnc, $lcr); - } - if (&is_valid_value($lnc) && &is_valid_value($unc) && $lnc > $unc || $lnc eq 'inf') { - ($lcr, $lnc, $unc, $ucr) = ($ucr, $unc, $lnc, $lcr); - } - return ($label, $value, $unit, $lcr, $lnc, $unc, $ucr); -} - -sub fan_threshold { - my ($name, $lcr, $lnc, $unc, $ucr) = @_; - my $warn_percent = exists $ENV{fan_warn_percent} ? $ENV{fan_warn_percent} : 5; - - # lcr: lower critical - if (exists $ENV{fan_lower_critical}) { - $lcr = $ENV{fan_lower_critical}; - } elsif (! &is_valid_value($lcr)) { - if ($lcr eq 'inf') { $lcr = ''; } - else { $lcr = '50'; } - } - # lnc: lower warning - if (! &is_valid_value($lnc)) { - if ($lnc eq 'inf') { $lnc = ''; } - else { $lnc = ($lcr eq '') ? '' : $lcr * (100 + $warn_percent) / 100; } - } - # ucr: upper critical - if (exists $ENV{fan_upper_critical}) { - $ucr = $ENV{fan_upper_critical}; - } elsif (! &is_valid_value($ucr)) { - if ($ucr eq 'inf') { $ucr = ''; } - else { $ucr = '6000'; } - } - # unc: upper warning - if (! &is_valid_value($unc)) { - if ($unc eq 'inf') { $unc = ''; } - else { $unc = ($ucr eq '') ? '' : $ucr * (100 - $warn_percent) / 100; } - } - - return unless ($lcr ne '' || $lnc ne '' || $unc ne '' || $ucr ne ''); - - printf "$name.warning $lnc:$unc\n"; - printf "$name.critical $lcr:$ucr\n"; -} - -sub temp_threshold { - my ($name, $lcr, $lnc, $unc, $ucr) = @_; - - # lcr: lower critical - if (exists $ENV{temp_lower_critical}) { - $lcr = $ENV{temp_lower_critical}; - } elsif (! &is_valid_value($lcr)) { - if ($lcr eq 'inf') { $lcr = ''; } - else { $lcr = 5; } - } - # lnc: lower warning - if (exists $ENV{temp_lower_warning}) { - $lnc = $ENV{temp_lower_warning}; - } elsif (! &is_valid_value($lnc)) { - if ($lnc eq 'inf') { $lnc = ''; } - else { $lnc = 10; } - } - # unc: upper warning - if (exists $ENV{temp_upper_warning}) { - $unc = $ENV{temp_upper_warning}; - } elsif (! &is_valid_value($unc)) { - if ($unc eq 'inf') { $unc = ''; } - else { $unc = '65'; } - } - # ucr: upper critical - if (exists $ENV{temp_upper_critical}) { - $ucr = $ENV{temp_upper_critical}; - } elsif (! &is_valid_value($ucr)) { - if ($ucr eq 'inf') { $ucr = ''; } - else { $ucr = '70'; } - } - - return unless ($lcr ne '' || $lnc ne '' || $unc ne '' || $ucr ne ''); - - printf "$name.warning $lnc:$unc\n"; - printf "$name.critical $lcr:$ucr\n"; -} - -sub volt_threshold { - my ($name, $lcr, $lnc, $unc, $ucr) = @_; - my $warn_percent = exists $ENV{volt_warn_percent} ? $ENV{volt_warn_percent} : 20; - - if (! &is_valid_value($lcr)) { $lcr = ''; } - if (! &is_valid_value($lnc)) { $lnc = ($lcr eq '') ? '' : $lcr * (100 + $warn_percent) / 100; } - if (! &is_valid_value($ucr)) { $ucr = ''; } - if (! &is_valid_value($unc)) { $unc = ($ucr eq '') ? '' : $ucr * (100 - $warn_percent) / 100; } - - return unless ($lcr ne '' || $lnc ne '' || $unc ne '' || $ucr ne ''); - - printf "$name.warning $lnc:$unc\n"; - printf "$name.critical $lcr:$ucr\n"; -} - -sub trim { - my $value = shift; - if (defined $value) { - $value =~ s/^\s*(.*?)\s*$/$1/; - } else { - $value = 'na' - } - return $value; -} - -sub is_valid_value() { - my $value = shift; - if ($value eq 'na' || $value eq 'inf' || $value eq '') { - return 0; - } else { - return 1; - } -} - -######################################## - -=head1 How to test - - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_volt - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_volt config - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_volt suggest - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_volt autoconf - fan_warn_percent=50 fan_lower_critical=100 fan_upper_critical=1000 cache_file=ipmitool_sensor_ \ - cache_expires=-1 ./ipmitool_sensor_fan config - temp_lower_warning=1 temp_lower_critical=2 temp_upper_critical=71 temp_upper_warning=72 \ - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_temp config - volt_warn_percent=50 \ - cache_file=ipmitool_sensor_ cache_expires=-1 ./ipmitool_sensor_volt config - -=head1 Test Data - - unr Upper Non-Recoverable - ucr Upper Critical - unc Upper Non-Critical - lnc Lower Non-Critical - lcr Lower Critical - lnr Lower Non-Recoverable - -=head2 ipmitool sensor - - # HP ProLiant ML110 G5 - CPU FAN | 1434.309 | RPM | ok | 5537.099 | 4960.317 | 4859.086 | na | 937.383 | na - SYSTEM FAN | 1497.454 | RPM | ok | 5952.381 | 5668.934 | 5411.255 | na | 937.383 | na - System 12V | 12.152 | Volts | ok | na | na | na | na | na | na - System 5V | 5.078 | Volts | ok | na | na | na | na | na | na - System 3.3V | 3.271 | Volts | ok | na | na | na | na | na | na - CPU0 Vcore | 1.127 | Volts | ok | na | na | na | na | na | na - System 1.25V | 1.254 | Volts | ok | na | na | na | na | na | na - System 1.8V | 1.842 | Volts | ok | na | na | na | na | na | na - System 1.2V | 1.107 | Volts | ok | na | na | na | na | na | na - CPU0 Diode | na | degrees C | na | na | 20.000 | 25.000 | 85.000 | 90.000 | 95.000 - CPU0 Dmn 0 Temp | 24.500 | degrees C | ok | na | 0.000 | 0.000 | 97.000 | 100.000 | 100.500 - CPU0 Dmn 1 Temp | 29.000 | degrees C | ok | na | 0.000 | 0.000 | 97.000 | 100.000 | 100.500 - # HP ProLiant DL160 - FAN1 ROTOR1 | 7680.492 | RPM | ok | na | inf | na | na | 1000.400 | na - # HP ProLiant DL360 G5 - Fan Block 1 | 34.888 | unspecified | nc | na | na | 75.264 | na | na | na - Fan Block 2 | 29.792 | unspecified | nc | na | na | 75.264 | na | na | na - Fan Block 3 | 37.240 | unspecified | nc | na | na | 75.264 | na | na | na - Fan Blocks | 0.000 | unspecified | nc | na | na | 0.000 | na | na | na - Temp 1 | 40.000 | degrees C | ok | na | na | -64.000 | na | na | na - Temp 2 | 21.000 | degrees C | ok | na | na | -64.000 | na | na | na - Temp 3 | 30.000 | degrees C | ok | na | na | -64.000 | na | na | na - Temp 4 | 30.000 | degrees C | ok | na | na | -64.000 | na | na | na - Temp 5 | 28.000 | degrees C | ok | na | na | -64.000 | na | na | na - Temp 6 | na | degrees C | na | na | na | 32.000 | na | na | na - Temp 7 | na | degrees C | na | na | na | 32.000 | na | na | na - Power Meter | 214.000 | Watts | cr | na | na | 384.000 | na | na | na - Power Meter 2 | 220.000 | watts | cr | na | na | 384.000 | na | na | na - -=head2 ipmitool sdr - - # HP ProLiant ML110 G5 - CPU FAN | 1434.31 RPM | ok - SYSTEM FAN | 1497.45 RPM | ok - System 12V | 12.10 Volts | ok - System 5V | 5.08 Volts | ok - System 3.3V | 3.27 Volts | ok - CPU0 Vcore | 1.14 Volts | ok - System 1.25V | 1.25 Volts | ok - System 1.8V | 1.84 Volts | ok - System 1.2V | 1.11 Volts | ok - CPU0 Diode | disabled | ns - CPU0 Dmn 0 Temp | 23.50 degrees C | ok - CPU0 Dmn 1 Temp | 29 degrees C | ok - # HP ProLiant DL360 G5 - Fan Block 1 | 34.89 unspecifi | nc - Fan Block 2 | 29.79 unspecifi | nc - Fan Block 3 | 37.24 unspecifi | nc - Fan Blocks | 0 unspecified | nc - Temp 1 | 41 degrees C | ok - Temp 2 | 19 degrees C | ok - Temp 3 | 30 degrees C | ok - Temp 4 | 30 degrees C | ok - Temp 5 | 26 degrees C | ok - Temp 6 | disabled | ns - Temp 7 | disabled | ns - Power Meter | 208 Watts | cr - Power Meter 2 | 210 watts | cr - -=cut - -# vim:syntax=perl From 0a1524f27f272dcae275b3a464b3685474d56abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 21:55:44 -0700 Subject: [PATCH 07/11] More housecleaning. Collapse some categories; remove duplicates; move plugins in where they belong, remove files that are not really plugins at all. --- .../asterisk/asterisk-multigraph-munin-plugin | 2 - plugins/{other => boinc}/boinc_processes | 0 .../disk-io-multigraph-munin-plugin | 0 plugins/disk/linux_diskstats_ | 702 ------------------ plugins/{forum => forums}/vbulletin4_users | 0 plugins/{forum => forums}/vbulletin_users | 0 plugins/{other => google}/google-rank | 0 plugins/memcached/memcached-multigraph-plugin | 2 - plugins/{other => nagios}/nagios-multigraph | 0 plugins/{system => network}/bgpd | 0 plugins/{ip => network}/ddclient | 0 plugins/network/dell_temps | 106 --- plugins/network/{ => dns}/bind95_ | 0 plugins/network/{ => dns}/bind_ | 0 plugins/{other => network/dns}/dnsresponse_ | 0 plugins/{power => network/dns}/pdns_errors | 0 plugins/{power => network/dns}/pdns_latency | 0 plugins/{power => network/dns}/pdns_qsize | 0 plugins/{power => network/dns}/pdns_queries | 0 plugins/{power => network/dns}/pdns_rel | 0 plugins/{system => network}/hostsdeny | 0 plugins/{nfs => network}/nfsv4 | 0 plugins/{system => network}/quagga_routes | 0 .../sshd_invalid_countries | 0 .../sshd_invalid_countries_ruby | 0 plugins/network/{ => tor}/tor-bandwidth-usage | 0 plugins/{ => network}/tor/tor-connections | 0 plugins/{ => network}/tor/tor-traffic | 0 plugins/{ => network}/tor/tor_routers | 0 plugins/network/{ => tor}/tor_traffic | 0 plugins/opentracker/opentracker_ | 378 ---------- .../other/disk-usage-multigraph-munin-plugin | 2 - plugins/other/ntp-multigraph-munin-plugin | 2 - plugins/other/xcache_mem | 54 -- .../postgresql-multigraph-munin-plugin | 2 - plugins/{hp2600 => printer}/hp2600_count_ | 0 plugins/{hp2600 => printer}/hp2600_status_ | 0 .../toshiba_5520c_byfunction_twincolor_ | 28 - plugins/{other => snmp}/multi_snmp_querier | 0 plugins/snmp/snmp_hplj4xxx | 59 -- plugins/snmp/{snmp_hplj2015 => snmp_hplj_} | 0 plugins/{other => time}/ntpdate_ | 0 plugins/{other => ubuntu}/apt_ubuntu | 0 plugins/{hardware => ups}/apc_status | 0 plugins/{other => zope}/zope_zodb | Bin 45 files changed, 1337 deletions(-) delete mode 100755 plugins/asterisk/asterisk-multigraph-munin-plugin rename plugins/{other => boinc}/boinc_processes (100%) rename plugins/{other => disk}/disk-io-multigraph-munin-plugin (100%) delete mode 100755 plugins/disk/linux_diskstats_ rename plugins/{forum => forums}/vbulletin4_users (100%) rename plugins/{forum => forums}/vbulletin_users (100%) rename plugins/{other => google}/google-rank (100%) delete mode 100755 plugins/memcached/memcached-multigraph-plugin rename plugins/{other => nagios}/nagios-multigraph (100%) rename plugins/{system => network}/bgpd (100%) rename plugins/{ip => network}/ddclient (100%) delete mode 100755 plugins/network/dell_temps rename plugins/network/{ => dns}/bind95_ (100%) rename plugins/network/{ => dns}/bind_ (100%) rename plugins/{other => network/dns}/dnsresponse_ (100%) rename plugins/{power => network/dns}/pdns_errors (100%) rename plugins/{power => network/dns}/pdns_latency (100%) rename plugins/{power => network/dns}/pdns_qsize (100%) rename plugins/{power => network/dns}/pdns_queries (100%) rename plugins/{power => network/dns}/pdns_rel (100%) rename plugins/{system => network}/hostsdeny (100%) rename plugins/{nfs => network}/nfsv4 (100%) rename plugins/{system => network}/quagga_routes (100%) rename plugins/{system => network}/sshd_invalid_countries (100%) rename plugins/{system => network}/sshd_invalid_countries_ruby (100%) rename plugins/network/{ => tor}/tor-bandwidth-usage (100%) rename plugins/{ => network}/tor/tor-connections (100%) rename plugins/{ => network}/tor/tor-traffic (100%) rename plugins/{ => network}/tor/tor_routers (100%) rename plugins/network/{ => tor}/tor_traffic (100%) delete mode 100755 plugins/opentracker/opentracker_ delete mode 100755 plugins/other/disk-usage-multigraph-munin-plugin delete mode 100755 plugins/other/ntp-multigraph-munin-plugin delete mode 100755 plugins/other/xcache_mem delete mode 100755 plugins/postgresql/postgresql-multigraph-munin-plugin rename plugins/{hp2600 => printer}/hp2600_count_ (100%) rename plugins/{hp2600 => printer}/hp2600_status_ (100%) delete mode 100755 plugins/printer/toshiba_5520c_byfunction_twincolor_ rename plugins/{other => snmp}/multi_snmp_querier (100%) delete mode 100755 plugins/snmp/snmp_hplj4xxx rename plugins/snmp/{snmp_hplj2015 => snmp_hplj_} (100%) rename plugins/{other => time}/ntpdate_ (100%) rename plugins/{other => ubuntu}/apt_ubuntu (100%) rename plugins/{hardware => ups}/apc_status (100%) rename plugins/{other => zope}/zope_zodb (100%) diff --git a/plugins/asterisk/asterisk-multigraph-munin-plugin b/plugins/asterisk/asterisk-multigraph-munin-plugin deleted file mode 100755 index e2855bd5..00000000 --- a/plugins/asterisk/asterisk-multigraph-munin-plugin +++ /dev/null @@ -1,2 +0,0 @@ -Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the -PyMunin Multi graph Munin Plugins and documentation. \ No newline at end of file diff --git a/plugins/other/boinc_processes b/plugins/boinc/boinc_processes similarity index 100% rename from plugins/other/boinc_processes rename to plugins/boinc/boinc_processes diff --git a/plugins/other/disk-io-multigraph-munin-plugin b/plugins/disk/disk-io-multigraph-munin-plugin similarity index 100% rename from plugins/other/disk-io-multigraph-munin-plugin rename to plugins/disk/disk-io-multigraph-munin-plugin diff --git a/plugins/disk/linux_diskstats_ b/plugins/disk/linux_diskstats_ deleted file mode 100755 index 7891eebf..00000000 --- a/plugins/disk/linux_diskstats_ +++ /dev/null @@ -1,702 +0,0 @@ -#!/usr/bin/perl -w -# vim: sts=4 sw=4 ts=8 - -# Munin markers: -#%# family=auto -#%# capabilities=autoconf suggest - -# Author: Michael Renner - -# Version: 0.0.5, 2009-05-22 - - - -=head1 NAME - -linux_diskstat_ - Munin plugin to monitor various values provided -via C - -=head1 APPLICABLE SYSTEMS - -Linux 2.6 systems with extended block device statistics enabled. - - -=head1 INTERPRETATION - -Among the more self-describing or well-known values like C -(Bytes per second) there are a few which might need further introduction. - - -=head2 Device Utilization - -Linux provides a counter which increments in a millisecond-interval for as long -as there are outstanding I/O requests. If this counter is close to 1000msec -in a given 1 second timeframe the device is nearly 100% saturated. This plugin -provides values averaged over a 5 minute time frame per default, so it can't -catch short-lived saturations, but it'll give a nice trend for semi-uniform -load patterns as they're expected in most server or multi-user environments. - - -=head2 Device IO Time - -The C takes the counter described under C -and divides it by the number of I/Os that happened in the given time frame, -resulting in an average time per I/O on the block-device level. - -This value can give you a good comparison base amongst different controllers, -storage subsystems and disks for similiar workloads. - - -=head2 Syscall Wait Time - -These values describe the average time it takes between an application issuing -a syscall resulting in a hit to a blockdevice to the syscall returning to the -application. - -The values are bound to be higher (at least for read requests) than the time -it takes the device itself to fulfill the requests, since calling overhead, -queuing times and probably a dozen other things are included in those times. - -These are the values to watch out for when an user complains that C. - - -=head3 What causes a block device hit? - -A non-exhaustive list: - -=over - -=item * Reads from files when the given range is not in the page cache or the O_DIRECT -flag is set. - -=item * Writes to files if O_DIRECT or O_SYNC is set or sys.vm.dirty_(background_)ratio -is exceeded. - -=item * Filesystem metadata operations (stat(2), getdents(2), file creation, -modification of any of the values returned by stat(2), etc.) - -=item * The pdflush daemon writing out dirtied pages - -=item * (f)sync - -=item * Swapping - -=item * raw device I/O (mkfs, dd, etc.) - -=back - -=head1 ACKNOWLEDGEMENTS - -The core logic of this script is based on the B tool of the B -package written and maintained by Sebastien Godard. - -=head1 SEE ALSO - -See C in your Linux source tree for further information -about the C involved in this module. - -L has a nice writeup -about the pdflush daemon. - -=head1 AUTHOR - -Michael Renner - -=head1 LICENSE - -GPLv2 - - -=cut - - -use strict; - - -use File::Basename; -use Carp; -use POSIX; - -# We load our own version of save/restore_state if Munin::Plugin is unavailable. -# Don't try this at home -eval { require Munin::Plugin; Munin::Plugin->import; }; - -if ($@) { - fake_munin_plugin(); -} - - -# Sanity check to ensure that the script is called the correct name. - -if (basename($0) !~ /^linux_diskstat_/) { - die qq(Please ensure that the name of the script and it's symlinks starts with "linux_diskstat_"\n); -} - - -############ -# autoconf # -############ - -if ( defined $ARGV[0] && $ARGV[0] eq 'autoconf' ) { - my %stats; - - # Capture any croaks on the way - eval { %stats = parse_diskstats() }; - - if ( !$@ && keys %stats ) { - - print "yes\n"; - exit 0; - } - else { - print "no\n"; - exit 1; - } -} - - -########### -# suggest # -########### - -if ( defined $ARGV[0] && $ARGV[0] eq 'suggest' ) { - - my %diskstats = parse_diskstats(); - - my %suggested_devices; - - DEVICE: - for my $devname ( sort keys %diskstats ) { - - # Skip devices without traffic - next - if ( $diskstats{$devname}->{'rd_ios'} == 0 - && $diskstats{$devname}->{'wr_ios'} == 0 ); - - for my $existing_device ( @{ $suggested_devices{'iops'} } ) { - - # Filter out devices (partitions) which are matched by existing ones - # e.g. sda1 -> sda, c0d0p1 -> c0d0 - next DEVICE if ( $devname =~ m/$existing_device/ ); - } - - push @{ $suggested_devices{'iops'} }, $devname; - push @{ $suggested_devices{'throughput'} }, $devname; - - # Only suggest latency graphs if the device supports it - if ( $diskstats{$devname}->{'rd_ticks'} > 0 - || $diskstats{$devname}->{'wr_ticks'} > 0 ) - { - push @{ $suggested_devices{'latency'} }, $devname; - } - } - - for my $mode ( keys %suggested_devices ) { - for my $device ( sort @{ $suggested_devices{$mode} } ) { - - my $printdev = translate_device_name($device, 'TO_FS'); - print "${mode}_$printdev\n"; - } - } - - exit 0; -} - - -# Reading the scripts invocation name and setting some parameters, -# needed from here on - -my $basename = basename($0); -my ( $mode, $device ) = $basename =~ m/linux_diskstat_(\w+)_([-+\w]+)$/; - -if ( not defined $device ) { - croak "Didn't get a device name. Aborting\n"; -} - -$device = translate_device_name($device, 'FROM_FS'); - -########## -# config # -########## - -if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) { - - my $pretty_device = $device; - - if ($device =~ /^dm-\d+$/) { - $pretty_device = translate_devicemapper_name($device); - } - - if ( $mode eq 'latency' ) { - - print <{'rd_ios'} - $prev_stats->{'rd_ios'}; - my $write_ios = $cur_stats->{'wr_ios'} - $prev_stats->{'wr_ios'}; - - my $rd_ticks = $cur_stats->{'rd_ticks'} - $prev_stats->{'rd_ticks'}; - my $wr_ticks = $cur_stats->{'wr_ticks'} - $prev_stats->{'wr_ticks'}; - - my $rd_sectors = $cur_stats->{'rd_sectors'} - $prev_stats->{'rd_sectors'}; - my $wr_sectors = $cur_stats->{'wr_sectors'} - $prev_stats->{'wr_sectors'}; - - my $tot_ticks = $cur_stats->{'tot_ticks'} - $prev_stats->{'tot_ticks'}; - - - my $read_io_per_sec = $read_ios / $interval; - my $write_io_per_sec = $write_ios / $interval; - - my $read_bytes_per_sec = $rd_sectors / $interval * $bytes_per_sector; - my $write_bytes_per_sec = $wr_sectors / $interval * $bytes_per_sector; - - - my $total_ios = $read_ios + $write_ios; - my $total_ios_per_sec = $total_ios / $interval; - - # Utilization - or "how busy is the device"? - # If the time spent for I/O was close to 1000msec for - # a given second, the device is nearly 100% saturated. - my $utilization = $tot_ticks / $interval; - - # Average time an I/O takes on the block device - my $servicetime = - $total_ios_per_sec ? $utilization / $total_ios_per_sec : 0; - - # Average wait time for an I/O from start to finish - # (includes queue times et al) - my $average_wait = $total_ios ? ( $rd_ticks + $wr_ticks ) / $total_ios : 0; - my $average_rd_wait = $read_ios ? $rd_ticks / $read_ios : 0; - my $average_wr_wait = $write_ios ? $wr_ticks / $write_ios : 0; - - my $average_rq_size_in_kb = - $total_ios - ? ( $rd_sectors + $wr_sectors ) * $bytes_per_sector / 1024 / $total_ios - : 0; - my $average_rd_rq_size_in_kb = - $read_ios ? $rd_sectors * $bytes_per_sector / 1024 / $read_ios : 0; - my $average_wr_rq_size_in_kb = - $write_ios ? $wr_sectors * $bytes_per_sector / 1024 / $write_ios : 0; - - my $util_print = $utilization / 10; - - - if ( $mode eq 'latency' ) { - print <) { - - # Strip trailing newline and leading whitespace - chomp $line; - $line =~ s/^\s+//; - - my @elems = split /\s+/, $line; - - # We explicitly don't support old-style diskstats - # There are situations where only _some_ lines (e.g. - # partitions on older 2.6 kernels) have fewer stats - # numbers, therefore we'll skip them silently - if ( @elems != 14 ) { - next; - } - push @lines, \@elems; - } - - close STAT or croak "Failed to close '/proc/diskstats': $!"; - return @lines; -} - -sub read_sysfs { - - my ($want_device) = @_; - - my @devices; - my @lines; - - if ( defined $want_device ) { - - # sysfs uses '!' as replacement for '/', e.g. cciss!c0d0 - $want_device =~ tr#/#!#; - @devices = $want_device; - } - else { - @devices = glob "/sys/block/*/stat"; - @devices = map { m!/sys/block/([^/]+)/stat! } @devices; - } - - - for my $cur_device (@devices) { - my $stats_file = "/sys/block/$cur_device/stat"; - - open STAT, "< $stats_file" - or croak "Failed to open '$stats_file': $!\n"; - - my $line = ; - - # Trimming whitespace - $line =~ s/^\s+//; - chomp $line; - - my @elems = split /\s+/, $line; - - croak "'$stats_file' doesn't contain exactly 11 values. Aborting" - if ( @elems != 11 ); - - # Translate the devicename back before storing the information - $cur_device =~ tr#!#/#; - - # Faking missing diskstats values - unshift @elems, ( '', '', $cur_device ); - - push @lines, \@elems; - - close STAT or croak "Failed to close '$stats_file': $!\n"; - } - - return @lines; -} - - -sub parse_diskstats { - - my ($want_device) = @_; - - my @stats; - - if ( glob "/sys/block/*/stat" ) { - - @stats = read_sysfs($want_device); - } - else { - @stats = read_diskstats(); - } - - my %diskstats; - - for my $entry (@stats) { - - my %devstat; - - # Hash-Slicing for fun and profit - @devstat{ - qw(major minor devname - rd_ios rd_merges rd_sectors rd_ticks - wr_ios wr_merges wr_sectors wr_ticks - ios_in_prog tot_ticks rq_ticks) - } - = @{$entry}; - - $diskstats{ $devstat{'devname'} } = \%devstat; - } - - return %diskstats; -} - -sub fetch_device_counters { - - my ($want_device) = @_; - - my %diskstats = parse_diskstats($want_device); - - for my $devname ( keys %diskstats ) { - - if ( $want_device eq $devname ) { - return %{ $diskstats{$devname} }; - } - } - return undef; -} - - -# We use '+' (and formerly '-') as placeholder for '/' in device-names -# used as calling name for the script. -sub translate_device_name { - - my ($device, $mode) = @_; - - if ($mode eq 'FROM_FS') { - - # Hackaround to mitigate issues with unwisely chosen former separator - if ( not ($device =~ m/dm-\d+/)) { - $device =~ tr#-+#//#; - } - - } - elsif ($mode eq 'TO_FS') { - - $device =~ tr#/#+#; - - } - else { - croak "translate_device_name: Unknown mode\n"; - } - - return $device; -} - - -sub fake_munin_plugin { - my $eval_code = <<'EOF'; - -use Storable; -my $storable_filename = basename($0); -$storable_filename = "/tmp/munin-state-$storable_filename"; - -sub save_state { - my @state = @_; - - if ( not -e $storable_filename or -f $storable_filename ) { - store \@state, $storable_filename or croak "Failed to persist state to '$storable_filename': $!\n"; - } - else { - croak "$storable_filename is probably not a regular file. Please delete it.\n"; - } -} - -sub restore_state { - - if (-f $storable_filename) { - my $state = retrieve($storable_filename); - return @{$state}; - } - else { - return undef; - } -} -EOF - - eval($eval_code); -} - -sub translate_devicemapper_name { - my ($device) = @_; - - my ($want_minor) = $device =~ m/^dm-(\d+)$/; - - croak "Failed to extract devicemapper id" unless defined ($want_minor); - - my $dm_major = find_devicemapper_major(); - croak "Failed to get device-mapper major number\n" unless defined $dm_major; - - for my $entry (glob "/dev/mapper/\*") { - - my $rdev = (stat($entry))[6]; - my $major = floor($rdev / 256); - my $minor = $rdev % 256; - - if ($major == $dm_major && $minor == $want_minor) { - - my $pretty_name = translate_lvm_name($entry); - - return defined $pretty_name ? $pretty_name : $entry; - - } - } - # Return original string if the device can't be found. - return $device; -} - - - -sub translate_lvm_name { - - my ($entry) = @_; - - my $device_name = basename($entry); - - # Check for single-dash-occurence to see if this could be a lvm devicemapper device. - if ($device_name =~ m/(?) { - chomp $line; - - my ($major, $name) = split /\s+/, $line, 2; - - next unless defined $name; - - if ($name eq 'device-mapper') { - $dm_major = $major; - last; - } - } - close(FH); - - return $dm_major; -} diff --git a/plugins/forum/vbulletin4_users b/plugins/forums/vbulletin4_users similarity index 100% rename from plugins/forum/vbulletin4_users rename to plugins/forums/vbulletin4_users diff --git a/plugins/forum/vbulletin_users b/plugins/forums/vbulletin_users similarity index 100% rename from plugins/forum/vbulletin_users rename to plugins/forums/vbulletin_users diff --git a/plugins/other/google-rank b/plugins/google/google-rank similarity index 100% rename from plugins/other/google-rank rename to plugins/google/google-rank diff --git a/plugins/memcached/memcached-multigraph-plugin b/plugins/memcached/memcached-multigraph-plugin deleted file mode 100755 index b9ad67d9..00000000 --- a/plugins/memcached/memcached-multigraph-plugin +++ /dev/null @@ -1,2 +0,0 @@ -Check http://aouyar.github.com/PyMunin/ -to get the most recent versionof the PyMunin Multi graph Munin Plugins and documentation. \ No newline at end of file diff --git a/plugins/other/nagios-multigraph b/plugins/nagios/nagios-multigraph similarity index 100% rename from plugins/other/nagios-multigraph rename to plugins/nagios/nagios-multigraph diff --git a/plugins/system/bgpd b/plugins/network/bgpd similarity index 100% rename from plugins/system/bgpd rename to plugins/network/bgpd diff --git a/plugins/ip/ddclient b/plugins/network/ddclient similarity index 100% rename from plugins/ip/ddclient rename to plugins/network/ddclient diff --git a/plugins/network/dell_temps b/plugins/network/dell_temps deleted file mode 100755 index d5690e1c..00000000 --- a/plugins/network/dell_temps +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/perl -w -# -# Plugin to monitor BGP table summary statistics on a cisco router. -# -# Original Author: Peter Holzleitner -# -# Revision 1.1 2010/10/14 19:19 -# -# Configuration variables: -# -# iosuser - username (default "") -# iospass - password (default "") -# -# Parameters: -# -# config (required) -# -# Magic markers (optional - only used by munin-config and some -# installation scripts): -#%# family=auto - - -use Net::Telnet::Cisco; -use Sys::Syslog; - - -if ($0 =~ /^(?:|.*\/)cisco_bgp_([^_]+)$/) { - $host = $1; - } - -($^O eq "linux" || $^O eq "openbsd") && Sys::Syslog::setlogsock('unix'); -openlog('munin.bgp', 'cons,pid', 'daemon'); - - -my @BGP_nbr; -my @BGP_pfx; -my $tot_pfx; -my $iosuser = $ENV{iosuser} || ""; -my $iospass = $ENV{iospass} || ""; - -&fetch_bgpstats($host, $iosuser, $iospass); - - -if ($ARGV[0] and $ARGV[0] eq "config") { - print "host_name $host\n"; - print "graph_args --base 1024 -l 0 --vertical-label Prefixes\n"; - print "graph_title BGP Neighbour Statistics\n"; - print "graph_category network\n"; - print "graph_info This graph shows the number of BGP prefixes received by neighbour.\n"; - - my($n, $i); $n = scalar @BGP_nbr; $i = 0; - while($n--) { - my $neigh = $BGP_nbr[$i++]; - print "n$i.label $neigh\n"; - } - -# print "total.label Total\n"; -# print "total.info Total number of prefixes in the BGP table\n"; - - } else { - - my($n, $i); $n = scalar @BGP_nbr; $i = 0; - while($n--) { - my $pfx = $BGP_pfx[$i++]; - print "n$i.value $pfx\n"; - } -# print "total.value $tot_pfx\n"; - } - - - - -sub fetch_bgpstats - { - my $hostname = shift; - my $username = shift; - my $password = shift; - my $session = Net::Telnet::Cisco->new(Host => $host); - - $session->login($username, $password); - $session->cmd('terminal length 200'); - $session->cmd('terminal width 200'); - my @output = $session->cmd('show ip bgp summary'); - -# example output of router -# ------------------------ -# [...] -# Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd -# 11.111.11.111 4 98765 12403694 509571 308911893 0 0 1d23h 329193 -# 122.122.122.122 4 1234 13242856 383827 308911879 0 0 00:08:22 330761 - - foreach(@output) { - chomp; s/\r//g; - $tot_pfx = $1 if /^BGP activity (\d+)\/(\d+) prefixes/; - syslog('debug', "$hostname: $_\n"); - - next unless /^(\d+\.\d+\.\d+\.\d+)\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[0-9a-z:]+\s+(\d+)/; - my ($neigh, $as, $pfx) = ($1, $2, $3); - syslog('debug', "$neigh (AS $as)"); - push @BGP_nbr, "$neigh (AS $as)"; - push @BGP_pfx, $pfx; - } - } - - -# vim:syntax=perl:ts=8 diff --git a/plugins/network/bind95_ b/plugins/network/dns/bind95_ similarity index 100% rename from plugins/network/bind95_ rename to plugins/network/dns/bind95_ diff --git a/plugins/network/bind_ b/plugins/network/dns/bind_ similarity index 100% rename from plugins/network/bind_ rename to plugins/network/dns/bind_ diff --git a/plugins/other/dnsresponse_ b/plugins/network/dns/dnsresponse_ similarity index 100% rename from plugins/other/dnsresponse_ rename to plugins/network/dns/dnsresponse_ diff --git a/plugins/power/pdns_errors b/plugins/network/dns/pdns_errors similarity index 100% rename from plugins/power/pdns_errors rename to plugins/network/dns/pdns_errors diff --git a/plugins/power/pdns_latency b/plugins/network/dns/pdns_latency similarity index 100% rename from plugins/power/pdns_latency rename to plugins/network/dns/pdns_latency diff --git a/plugins/power/pdns_qsize b/plugins/network/dns/pdns_qsize similarity index 100% rename from plugins/power/pdns_qsize rename to plugins/network/dns/pdns_qsize diff --git a/plugins/power/pdns_queries b/plugins/network/dns/pdns_queries similarity index 100% rename from plugins/power/pdns_queries rename to plugins/network/dns/pdns_queries diff --git a/plugins/power/pdns_rel b/plugins/network/dns/pdns_rel similarity index 100% rename from plugins/power/pdns_rel rename to plugins/network/dns/pdns_rel diff --git a/plugins/system/hostsdeny b/plugins/network/hostsdeny similarity index 100% rename from plugins/system/hostsdeny rename to plugins/network/hostsdeny diff --git a/plugins/nfs/nfsv4 b/plugins/network/nfsv4 similarity index 100% rename from plugins/nfs/nfsv4 rename to plugins/network/nfsv4 diff --git a/plugins/system/quagga_routes b/plugins/network/quagga_routes similarity index 100% rename from plugins/system/quagga_routes rename to plugins/network/quagga_routes diff --git a/plugins/system/sshd_invalid_countries b/plugins/network/sshd_invalid_countries similarity index 100% rename from plugins/system/sshd_invalid_countries rename to plugins/network/sshd_invalid_countries diff --git a/plugins/system/sshd_invalid_countries_ruby b/plugins/network/sshd_invalid_countries_ruby similarity index 100% rename from plugins/system/sshd_invalid_countries_ruby rename to plugins/network/sshd_invalid_countries_ruby diff --git a/plugins/network/tor-bandwidth-usage b/plugins/network/tor/tor-bandwidth-usage similarity index 100% rename from plugins/network/tor-bandwidth-usage rename to plugins/network/tor/tor-bandwidth-usage diff --git a/plugins/tor/tor-connections b/plugins/network/tor/tor-connections similarity index 100% rename from plugins/tor/tor-connections rename to plugins/network/tor/tor-connections diff --git a/plugins/tor/tor-traffic b/plugins/network/tor/tor-traffic similarity index 100% rename from plugins/tor/tor-traffic rename to plugins/network/tor/tor-traffic diff --git a/plugins/tor/tor_routers b/plugins/network/tor/tor_routers similarity index 100% rename from plugins/tor/tor_routers rename to plugins/network/tor/tor_routers diff --git a/plugins/network/tor_traffic b/plugins/network/tor/tor_traffic similarity index 100% rename from plugins/network/tor_traffic rename to plugins/network/tor/tor_traffic diff --git a/plugins/opentracker/opentracker_ b/plugins/opentracker/opentracker_ deleted file mode 100755 index 0bfe0f78..00000000 --- a/plugins/opentracker/opentracker_ +++ /dev/null @@ -1,378 +0,0 @@ -#!/usr/bin/perl -# -=head1 OPENTRACKER PLUGIN - -A Plugin to monitor OpenTracker Servers and their Performance - -=head1 MUNIN CONFIGURATION - -[opentracker*] - env.host 127.0.0.1 *default* - env.port 6969 *default* - env.uri /stats *default* - -=head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION - - host = opentracker host to connect to - port = opentracker http port to connect to - uri = stats uri for appending requests for data - - I need this information so I can later build the full url which normally - looks like the following example when put together: - http://127.0.0.1:6969/stats?mode=conn - -=head1 AUTHOR - -Matt West < https://github.com/mhwest13/OpenTracker-Munin-Plugin > - -=head1 LICENSE - -GPLv2 - -=head1 MAGIC MARKERS - -#%# family=auto -#%# capabilities=autoconf suggest - -=cut - -use strict; -use warnings; - -use File::Basename; -use LWP::UserAgent; - -if (basename($0) !~ /^opentracker_/) { - print "This script needs to be named opentracker_ and have symlinks which start the same.\n"; - exit 1; -} - -my $host = $ENV{host} || '127.0.0.1'; -my $port = $ENV{port} || 6969; -my $uri = $ENV{uri} || '/stats'; - -=head1 Graph Declarations - - This block of code builds up all of the graph info for all root / sub graphs. - - %graphs is a container for all of the graph definition information. In here is where you'll - find the configuration information for munin's graphing procedure. - Format: - - $graph{graph_name} => { - config => { - { key => value }, You'll find the main graph config stored here. - { ... }, - }, - keys => [ 'Name', 'Name', 'Name', ... ], Used for building results set. - datasrc => [ - # Name: name given to data value - # Attr: Attribute for given value, attribute must be valid plugin argument - { name => 'Name', info => 'info about graph' }, - { ... }, - ], - results => { - { key => value }, You'll find the results info from fetch_stats call stored here. - { ... }, - }, - } - -=cut - -my %graphs; - -# graph for connections -$graphs{conn} = { - config => { - args => '--lower-limit 0', - vlabel => 'Connections', - category => 'opentracker', - title => 'Current Connections', - info => 'Current Connections to OpenTracker', - }, - keys => [ 'Requests', 'Announces' ], - datasrc => [ - { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of Requests', draw => 'AREA' }, - { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of Announces', draw => 'LINE2' }, - ], -}; -# graph for peers -$graphs{peer} = { - config => { - args => '--lower-limit 0', - vlabel => 'Peers', - category => 'opentracker', - title => 'Peers and Seeders', - info => 'Current Peer and Seeder Connections', - }, - keys => [ 'Peers', 'Seeders' ], - datasrc => [ - { name => 'Peers', label => 'Peers', min => '0', type => 'GAUGE', info => 'current number of leechers & seeders (peers)', draw => 'AREA' }, - { name => 'Seeders', label => 'Seeders', min => '0', type => 'GAUGE', info => 'current number of seeders', draw => 'LINE2' }, - ], -}; -# graph for scrapes -$graphs{scrp} = { - config => { - args => '--lower-limit 0', - vlabel => 'Scrapes', - category => 'opentracker', - title => 'Scrapes', - info => 'Number of Scrapes (TCP/UDP)', - }, - keys => [ 'TCP', 'UDP' ], - datasrc => [ - { name => 'TCP', label => 'TCP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via tcp', draw => 'AREASTACK' }, - { name => 'UDP', label => 'UDP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via udp', draw => 'AREA' }, - ], -}; -# graph for livesyncs -$graphs{syncs} = { - config => { - args => '--lower-limit 0', - vlabel => 'Syncs', - category => 'opentracker', - title => 'LiveSyncs', - info => 'OpenTracker LiveSync Requests', - }, - keys => [ 'Incoming', 'Outgoing' ], - datasrc => [ - { name => 'Incoming', label => 'Incoming Syncs', min => '0', type => 'COUNTER', info => 'number of Incoming Syncs', draw => 'AREA' }, - { name => 'Outgoing', label => 'Outgoing Syncs', min => '0', type => 'COUNTER', info => 'number of Outgoing Syncs', draw => 'LINE2' }, - ], -}; -# graph for tcp4 connections -$graphs{tcp4} = { - config => { - args => '--lower-limit 0', - vlabel => 'TCP4 Requests', - category => 'opentracker', - title => 'TCP4 Requests', - info => 'Current TCP4 Requests / Announces', - }, - keys => [ 'Requests', 'Announces' ], - datasrc => [ - { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of tcp4 Requests', draw => 'AREA' }, - { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of tcp4 Announces', draw => 'LINE2' }, - ], -}; -# graph for torrents -$graphs{torr} = { - config => { - args => '--lower-limit 0', - vlabel => '# of Torrents', - category => 'opentracker', - title => 'Torrents', - info => 'Current number of Torrents', - }, - keys => [ 'Torrents' ], - datasrc => [ - { name => 'Torrents', label => 'Torrents', min => '0', type => 'GAUGE', info => 'number of torrents', draw => 'AREA' }, - ], -}; -# graph for udp4 connections -$graphs{udp4} = { - config => { - args => '--lower-limit 0', - vlabel => 'UDP4 Requests', - category => 'opentracker', - title => 'UDP4 Requests', - info => 'Current UDP4 Requests / Announces', - }, - keys => [ 'Requests', 'Announces' ], - datasrc => [ - { name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of udp4 Requests', draw => 'AREA' }, - { name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of udp4 Announces', draw => 'LINE2' }, - ], -}; - -=head1 Munin Checks - - These checks look for config / autoconf / suggest params - -=head2 Config Check - - This block of code looks at the argument that is possibly supplied, - should it be config, it then checks to make sure the plugin - specified exists, assuming it does, it will run the do_config - subroutine for the plugin specified, otherwise it dies complaining - about an unknown plugin. - -=cut - -if (defined $ARGV[0] && $ARGV[0] eq 'config') { - # Lets take the plugin from the execution name. - $0 =~ /opentracker_(.+)*/; - my $plugin = $1; - # And lets make sure we have a plugin called that. - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - # Now lets go ahead and print out our config. - print_config($plugin); - exit 0; -} - -=head2 Autoconf Check - - This block of code looks at the argument that is possibly supplied, - should it be autoconf, we are going to print yes at this point since - we've already tested for our binary to exist and be executable, the - process will then exit. - -=cut - -if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { - # well we can execute the binary, so lets make sure we can curl opentracker - my $url = "http://".$host.":".$port.$uri."\?mode=version"; - my $ua = LWP::UserAgent->new; - $ua->timeout(15); - my $response = $ua->get($url); - if ($response->is_success) { - print "yes\n"; - exit 0; - } else { - print "no: unable to connect to url: $url\n"; - exit 1; - } -} - -=head2 Suggest Check - - This block of code looks at the argument that is possibly supplied, - should it be suggest, we are going to print the possible plugins - which can be specified. - -=cut - -if (defined $ARGV[0] && $ARGV[0] eq 'suggest') { - # well we can execute the binary, so print possible plugin names - my @rootplugins = ('conn','peer','scrp','syncs','tcp4','torr','udp4'); - foreach my $plugin (@rootplugins) { - print "$plugin\n"; - } - exit 0; -} - -=head1 Subroutines - - Begin Subroutine calls to output data / config information - -=head2 fetch_output - - This subroutine is the main call for printing data for the plugin. - No parameters are taken as this is the default call if no arguments - are supplied from the command line. - -=cut - -fetch_output(); - -sub fetch_output { - # Lets figure out what plugin they want to run, and check that it exists - $0 =~ /opentracker_(.+)*/; - my $plugin = $1; - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - # Lets print out the data for our plugin - print_output($plugin); - return; -} - -=head2 print_output - - This block of code prints out the return values for our graphs. It takes - one parameter $plugin. Returns when completed - - $plugin; graph we are calling up to print data values for - - Example: print_output($plugin); - -=cut - -sub print_output { - # Lets get our plugin, set our graph information, and print for Munin to process - my ($plugin) = (@_); - my $graph = $graphs{$plugin}; - print "graph opentracker_$plugin\n"; - # Getting keys to pass to fetch_stats for data retrieval - # call up fetch_stats with the keys we just got. - my @keys = @{$graph->{keys}}; - fetch_stats($plugin,@keys); - # print the results for the keys with the name for Munin to process - foreach my $dsrc (@{$graph->{datasrc}}) { - my $output = 0; - my %datasrc = %$dsrc; - while ( my ($key, $value) = each(%datasrc)) { - next if ($key ne 'name'); - print "$dsrc->{name}.value $graph->{results}->{$value}\n"; - } - } - return; -} - -=head2 print_config - - This subroutine prints out the main config information for all of the graphs. - It takes one parameters, $plugin - - $plugin; graph being called up to print config for - - Example: print_config($plugin); - -=cut - -sub print_config { - # Lets get our plugin and graph, after that print for Munin to process it. - my ($plugin) = (@_); - my $graph = $graphs{$plugin}; - print "graph opentracker_$plugin\n"; - # Lets print out graph's main config info. - my %graphconf = %{$graph->{config}}; - while ( my ($key, $value) = each(%graphconf)) { - print "graph_$key $value\n"; - } - # Lets print our graphs per graph config info. - foreach my $dsrc (@{$graph->{datasrc}}) { - my %datasrc = %$dsrc; - while ( my ($key, $value) = each(%datasrc)) { - next if ($key eq 'name'); - print "$dsrc->{name}.$key $value\n"; - } - } - return; -} - -=head2 fetch_stats - - This subroutine actually fetches data from opentracker with the plugin specified - It will then parse the data using the keys assigned in an array. - Two parameters are passed, $plugin and @keys, and it will return when complete. - - $plugin; graph we are calling up, we use this to store the results in the hash - for easy recall later. - @keys; keys we want the values for from opentracker stats url. - - Example: fetch_stats($plugin,@keys); - -=cut - -sub fetch_stats { - # Lets get our current plugin and list of keys we want info for, as well as reference our graph - my ($plugin,@keys) = (@_); - my $graph = $graphs{$plugin}; - # Lets create our url to fetch - my $url = "http://".$host.":".$port.$uri."\?mode=".$plugin; - my $ua = LWP::UserAgent->new; - $ua->timeout(15); - my $response = $ua->get($url); - # Lets print some info since we got back some info - if ($response->is_success) { - my @tmparray = split("\n",$response->content); - foreach my $key (@keys) { - my $value = shift(@tmparray); - $graph->{results}->{$key} = $value; - } - } else { - print "Unable to Fetch data from URL: $url\n"; - exit 1; - } - return; -} diff --git a/plugins/other/disk-usage-multigraph-munin-plugin b/plugins/other/disk-usage-multigraph-munin-plugin deleted file mode 100755 index e2855bd5..00000000 --- a/plugins/other/disk-usage-multigraph-munin-plugin +++ /dev/null @@ -1,2 +0,0 @@ -Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the -PyMunin Multi graph Munin Plugins and documentation. \ No newline at end of file diff --git a/plugins/other/ntp-multigraph-munin-plugin b/plugins/other/ntp-multigraph-munin-plugin deleted file mode 100755 index b9ad67d9..00000000 --- a/plugins/other/ntp-multigraph-munin-plugin +++ /dev/null @@ -1,2 +0,0 @@ -Check http://aouyar.github.com/PyMunin/ -to get the most recent versionof the PyMunin Multi graph Munin Plugins and documentation. \ No newline at end of file diff --git a/plugins/other/xcache_mem b/plugins/other/xcache_mem deleted file mode 100755 index 148ad864..00000000 --- a/plugins/other/xcache_mem +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/perl -w -# - -require LWP::UserAgent; - -######################################################################################## -# -# Installation / Configuration -# -# - place munin_xcache.php in a directory on your webserver -# - add the url config to plugin-conf.d/munin-node -# -# -# for more info see http://www.ohardt.net/dev/munin/ -# -# - - - -chomp(my $fqdn=`hostname -f`); - - -my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://user:pwd\@$fqdn/munin_xcache_new.php"; - -$URL = $URL . "?what=mem"; - -my $ua = LWP::UserAgent->new(timeout => 30); - - -if ( exists $ARGV[0] and $ARGV[0] eq "config" ) -{ - - $URL = $URL . '&config'; - - my $response = $ua->request(HTTP::Request->new('GET',$URL . '&config' )); - - print $response->content; - - - exit( 0 ); -} - - -my $response = $ua->request(HTTP::Request->new('GET',$URL)); - - -print $response->content; - - -exit( 0 ); - - - - diff --git a/plugins/postgresql/postgresql-multigraph-munin-plugin b/plugins/postgresql/postgresql-multigraph-munin-plugin deleted file mode 100755 index e2855bd5..00000000 --- a/plugins/postgresql/postgresql-multigraph-munin-plugin +++ /dev/null @@ -1,2 +0,0 @@ -Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the -PyMunin Multi graph Munin Plugins and documentation. \ No newline at end of file diff --git a/plugins/hp2600/hp2600_count_ b/plugins/printer/hp2600_count_ similarity index 100% rename from plugins/hp2600/hp2600_count_ rename to plugins/printer/hp2600_count_ diff --git a/plugins/hp2600/hp2600_status_ b/plugins/printer/hp2600_status_ similarity index 100% rename from plugins/hp2600/hp2600_status_ rename to plugins/printer/hp2600_status_ diff --git a/plugins/printer/toshiba_5520c_byfunction_twincolor_ b/plugins/printer/toshiba_5520c_byfunction_twincolor_ deleted file mode 100755 index 9814c5c0..00000000 --- a/plugins/printer/toshiba_5520c_byfunction_twincolor_ +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# -# toshiba_5520c_print_ munin grabber script -# 2009.01 by steve@kosada.com - -destination=`basename $0 | sed 's/^toshiba_5520c_print_//g'` - -if [ "$1" = "config" ]; then - echo "graph_title Toshiba 5520C: Pages Printed" - echo 'graph_vlabel Pages' - echo 'graph_args --lower-limit 0' - echo 'graph_category printer' - - echo "printBlack.label Black" - echo "printBlack.draw AREA" - - echo "printFullColor.label Full Color" - echo "printFullColor.draw STACK" - - echo "printTwinColor.label Twin Color" - echo "printTwinColor.draw STACK" -else - infopage=`wget -q -O - http://$destination:8080/TopAccess/Counter/TotalCount/List.htm | dos2unix | perl -p -e 's/\n/ /m'` - - echo printFullColor.value `echo $infopage | perl -p -e 's/^.+\Print Counter\<\/B\>.+?\{Full\ Color[^}]+\,([0-9]+)\}.+$/$1/'` - echo printTwinColor.value `echo $infopage | perl -p -e 's/^.+\Print Counter\<\/B\>.+?\{Twin\ Color[^}]+\,([0-9]+)\}.+$/$1/'` - echo printBlack.value `echo $infopage | perl -p -e 's/^.+\Print Counter\<\/B\>.+?\{Black[^}]+\,([0-9]+)\}.+$/$1/'` -fi diff --git a/plugins/other/multi_snmp_querier b/plugins/snmp/multi_snmp_querier similarity index 100% rename from plugins/other/multi_snmp_querier rename to plugins/snmp/multi_snmp_querier diff --git a/plugins/snmp/snmp_hplj4xxx b/plugins/snmp/snmp_hplj4xxx deleted file mode 100755 index 374921ca..00000000 --- a/plugins/snmp/snmp_hplj4xxx +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -HOST=${host:-"127.0.0.1"} - -: << =cut - -=head1 NAME - -snmp_HPLJ2015 - Consumables level on HP LaserJet 2015n reported over SNMP - -=head1 CONFIGURATION - -HOST - -=head1 AUTHOR - -Oleksiy Kochkin - -=head1 LICENSE - -As is. - -=back - -=head1 MAGIC MARKERS - - #%# family=contrib - #%# capabilities=autoconf - -=cut - -case $1 in -config) - -echo "graph_title Consumables level @ $HOST" -echo 'graph_args --upper-limit 100 -l 0' -echo 'graph_vlabel %' -echo 'graph_category printers' -echo 'graph_scale no' -echo 'black.label Black toner level' -echo 'black.draw LINE2' -echo 'black.type GAUGE' -echo 'black.colour 000000' -echo 'black.warning 5:' -echo 'black.critical 1:' -echo 'black.min 0' -echo 'black.max 100' -exit 0;; -esac - -BLACK_MAX_OID=".1.3.6.1.2.1.43.11.1.1.8.1.1" -BLACK_LVL_OID=".1.3.6.1.2.1.43.11.1.1.9.1.1" - -BLACK_MAX=`snmpget -v 1 -c public -Ov -Oq $HOST $BLACK_MAX_OID` -BLACK_LVL=`snmpget -v 1 -c public -Ov -Oq $HOST $BLACK_LVL_OID` -BLACK_LVL_PERCENTS=$(($BLACK_LVL*100/$BLACK_MAX)) - -echo -n "black.value " -echo $BLACK_LVL_PERCENTS diff --git a/plugins/snmp/snmp_hplj2015 b/plugins/snmp/snmp_hplj_ similarity index 100% rename from plugins/snmp/snmp_hplj2015 rename to plugins/snmp/snmp_hplj_ diff --git a/plugins/other/ntpdate_ b/plugins/time/ntpdate_ similarity index 100% rename from plugins/other/ntpdate_ rename to plugins/time/ntpdate_ diff --git a/plugins/other/apt_ubuntu b/plugins/ubuntu/apt_ubuntu similarity index 100% rename from plugins/other/apt_ubuntu rename to plugins/ubuntu/apt_ubuntu diff --git a/plugins/hardware/apc_status b/plugins/ups/apc_status similarity index 100% rename from plugins/hardware/apc_status rename to plugins/ups/apc_status diff --git a/plugins/other/zope_zodb b/plugins/zope/zope_zodb similarity index 100% rename from plugins/other/zope_zodb rename to plugins/zope/zope_zodb From a200c77b5149b86ec5766ba6955506767884a5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 22:00:49 -0700 Subject: [PATCH 08/11] Uncompress assp-* plugins that were shipped as gzip. --- .../other/assp-envelope-recipient-statistics | Bin 1894 -> 5006 bytes .../other/assp-general-runtime-information | Bin 1800 -> 4609 bytes plugins/other/assp-message-statistics | Bin 1988 -> 5000 bytes plugins/other/assp-smtp-connection-statistics | Bin 1813 -> 4734 bytes plugins/other/assp-smtp-handler-statistics | Bin 1804 -> 4610 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/plugins/other/assp-envelope-recipient-statistics b/plugins/other/assp-envelope-recipient-statistics index b66863603e9a5f2f7589e5cf1451c8002b8a9384..84ea277330184a98e744fe1f70063abd81ee87b8 100755 GIT binary patch literal 5006 zcmcIoZFAa468;Roq7O&{i3Ql++Yk8cGVv0}wHUj=_ST)rrDSOkT1y(OW@JJV-*3O} z9tk8MzPqYDYPTZIOh41FPq$qEOD9!H=fRIUu}FeywGQvBKjrrhp}s@u*N4kA@*_A; z?062>LF(blOeWBuOs-2O%P-$Iq3*#}Dz-%QBmx-=D-n(#`y$eo(zf=M_8kSE${^;A zp#C2Q_ESBVNe>25;yV(C_JeT0KKi><*s)eJa1h#l&;t>Dm8V`Rg0>&cq?ZH8JziV|5tb>EyvKy;qDBls0BYJRtJ$yQZxz=&7(^)JQZ7)jOGVwYA zolrt`yg0B9+ugSQqI1MQ)$P?(2~Zjxt&jM5VJDbYo-%JA{6O@2?`&WY#vJ*67xtwZ6U%p3tD@0`fB;XZ&su z2<%i#1o>mpgoStrF=s?l$h;C50R>oK1Y*0PA1T1%6aJGUTnL3ywkH(G2a zS9L>}c@k1Y40a;y07fVTteLsR*WgGrfnims#EZEF z=fkV_{o((TTTdcUK6(~y+;4YtXBl@?7dys$dhVw6OvSRyeX)J9okE))rB z0W#Hbs!8J1k&#CAQJ`5!zIFKW{e^gg*^vm;_$dozBfpJ+UipzLz7R|vwA@?NbTW6r zLA6qOLwWF~a(n_mb@z&g>+m#k{8Cz-iFb=&Qq z537~hkOIFxt)TBXBG$sK?cwg79r&(|Z-o=QaT_^v;XH0{Okz89+verV%^}99^&_F?;7jZ$ z!reMB2p{akliRrLr1vStcSkg~<5;p{%zW9`T7)rD#%eE1|Ks8hCjHUH&EMhdJxtc}+hP8>^app(DZJzeW=XWh=eXCX)^myO>go$6P9aW!+kT>Mv=Hmd)2REDR ze5~rvny>;9e{hK+E;V}QR|LkvqSw1sBIy(1S|^cMAZOv-e84*4f0{M(N_<>HM#Jr# zrVt`OihUZdBhDp&*ZGOh+(w%%FqXnf)H?CiXO&_tDx7>O1=dt?;3HON8g=%H=X2g9 zmSHObbXn#des^TbwA*09`$kmvOzM)w%prJBxI`@<#S)R9>>w5RZ$M)vDZQBE?A3&Q zc7NqHM#NWhRGl4Zz)v6p*YcTVDveBwMyB39KA;+(5U*k$-@T(}XD-7S@8;ulTLo)D zBX+jL0a_0}$aIke%CIF)ED`qgO@ZToLFb>-sL@#qu?)uWC4r4q&4ftPi=9m{4*~~O8UzrN(MzbMwG4LSWOM4iZB5nN_S;Tle|0OV zpCHR)zYZmjb~q>^sbvucZo$FwQvwW^EHn6VYi@9O2A4(hHdfM>&&RIPKHyP^~=g=FbneqqCcftI;+yBR8Xg zU^w7gwSs+1;{b>-v|MI4+-8a}UqQs(6`at7?aYD6mOeCaL^?&wc#{a}6@L`rOao?C zKS3MmskR3<_&Gzb{DFe+ANccwR*2DXVUj*jQ{_|UPZHTcT=+o2W0&T8hK~)#$Ea5&}IV8vc*}vG@0nFmsSEF?rZEz_Wzf6 z88rkP7cmPS_re|L9IQT1CQH62^JB4T6|;#L5_73A7_)!>tExwT=I4r)y|KJ5S==bs QpRtFC#aNMth6|(mZ}=o;asU7T delta 1883 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 diff --git a/plugins/other/assp-message-statistics b/plugins/other/assp-message-statistics index e48b0f642f535c140aace3278eea693043f54710..542144e08ef8c626a2758025dba39800be5a2e0a 100755 GIT binary patch literal 5000 zcmcIoZByGw68>!eiau}>JBeRN>hi%{C=3{I#Rkd-_U__bN|wjA4oRccNEkL@fBQb& zBiR;#++Ee43(A_A?q~YFTi*UlGc|E@;)Tsf#eTWGO>gRd%I6KBzEk1Tp+OpYA)Uld zw4e(=ontZ6F?B|xivneF@%=|A`b>^7Q9V$`ICE7uiIaFH@mxb+ip<3oL;XJ#?4-#; z$8G9{vFB>)I}RAwbP=M+?CZU0z zdNWT=+w`ur)2g@L)!)7Q4qu z9;tB3R^H`!e?HpjsC#gALf4()=qFSee>u3Pie>mnt=&@Lvn^phRg-j%n4eRW#*sEk zc)Ej5um23A^i0+kfx-3@ z4Uk`#Ra&Y^fS6J7{$!pizu|>5y@9qZj6M>LL7Zveg@$6~D(}`+Q_7OjkPgWSN#vZx zIso`qWi4>sN$Lx2lJWlPj;%~!djTJkFfJD=R^%n*YJdx1z$GNqQ}He%vvC>)q&(`_ z1s3rP^v@!iAc>v^%6(`-gf3RTb5AfB!fPt#;QN0XM|9FZKj`%TmpHmrvGHIJ$< zmYz5fTS{i2UnuruwT#do*zQQ9b$6`S_cAR%d}uTvaJjT~;M^{fmsXC1P*42i zo-Q$)6i*JEDRq*>aTft1)ly%3F`AH}Bb5l2wFD{x%rI1QbtfAKI+$!M^D7RtJzjao z)trU}k;UM|eM-fJgC6oFhNv_^*|FEUu@_}>jV_Mq7zZhGLk@=r{o=;eu=jXt;M`F+ zj&*FPd*>=O&8&OGr7nB!1`&)iRIV3!u!3Np>4ZjTjU#U!!kh;>#eiV19gI$TM{?jK zkVVLkKJ^Bx2a1r+hYRK2$kqi`r^;bvB{R0^G2LP5Qi|asd)8e3&e=j;vky zkqdG~is3gdgAXh&Yb@0T_XPKl@(EE{!Yz*jl)WF%_KbV;m;W2A_LxGl#hAtu{ahzevHpumP~|fnt3jmo-}3+ zK3F;NJ3BE`np@1aJ)$(?Hk>SCrAR!%8nR~yR~u+%n$7txZETHAg|}><5>-v)AbiNN zVts{l=d0*%a17U(@1 zQD`-=omW&xS(!SC^9c2`Q~#|~|L3?mu8m)OS!=_%EP9B-jw!vnFRmWd9)ZvSf`YLu3g@HjRH!y^y{v!)do`D*L-cHYsnss(>u-(hSxe4$p_}tXRv$jijj*-bi3iThU4{ z`3-^PtBRC0LXntyYK_7jeElxkZcB}4f1ogztS!3hcSEal?#c5{4eIMT8Ry=#QC=Qn z`Fbu$0D1r#{_!W)-`RzqQ7;iZVj9A(Nz7B8rNPx%?~G1{or}}%kPgp#XUDyhyiJyW zY>g=1Gj9$9za4l_Rb8}&5Wi4}bVRUJ8bZKLA0JT`{Q`<%p|7`yi zTSF2%!7q?$KG;tf3>fgl2F3>3J~&V2ES+r?NvG;g7~0Uky}Nsok-((Q%u~%U=%{jD7XfpbyN?e)?zN}+6d!m<2f2W!{0#t8wz$4vrusxdSUE23I<{--QRCK_-9W+ z!CoLdzYUU+8ornk(B3pwuF?%xeh<_@Xahs#dNWVDZP;mTx9Y8(`p(YxOEvHu89K5J z$LE9F_pmS~YB!t9<+3pklZJ}tO`j;V)XjP1*WWi<4RdGy6||!`S~5>>*zFHqV6=RaWPRjju86aTG(@h~(^T6kR5n`` zsC9A(b7{aVBxE$8X1ult1h!`sg8a6u!ctBHj2Rj4P3MX98(uh5IkXLC^fA#0M7V($ zYKWyHy<11RkS3!B6@mzX<($PTK=4XV;JPsNh0Ld5F?ngP}29-X^wh#t|G3&i1>5 z?}?*Z8EX%%h*E7gT9r;QCN8^hWeJ!VO&*%e8u`Gm)i$lOR~e{9W0Wx_Q5sK4>=S#M z*S>OuPi|=ch|l}xN`eijx^gBG-)J(zimt{WvDA^m8n7;q*@7}gAwVT2N(@Jyqe6qy zBSW>ejw3r?$~Wk?SfaqUsV7&r5zs3ybmbkoeogwMwt}5v_ri2(=7_oahZWY)2Qont-m%{^S;Y*IYg7cO*- z5zZpONVI!bUX0yD!=W^cW#O?RpczJTF7GU-3Z}VbcE!H3>y>vL6=&AWL}r77MJycj zF&|>Y;ZA0+bz(0{5M`;#TRDAD&?&`o&2Pj(Zo+a2ea1Rbd4pf8*>$+*RR4V4N=6?Mp0fUD~MchH{D3 z4DS|p&Ht*E$3k7fT8GEEa+#50v##1=OaQMliZ7D}s3^s)BUcRl?@Ck|yKGUV#1 zj(iWXnv<}(m8Z`r$jq#Tk0wj4!)piqNC2B$CjOu@_(0+^Emaq$Ln&|MJtAXRCUT38 zG=r9w3mm|zu+3&Fy+)6CdV!*|AuafB25!^?^OQ0vHdFDgE#+rEt_rf|AglMCgEnYQ{+J(ev2V4GSHCbV<&on_$fYh zS#%I))68>_X{|A9c_)4)C#FhU3_gM+qMl+Fv6R5fBrt)|)f(^C&E~uVxvh!bq^+E) zIuaN@Ance(V~t2ho2kUffhGjRWb^`RVK0S!LRp=-Z)+3%w(+*PxxKoT?u})DO#=dj znQs=@BUG4aU^_4Chh@bTMm#~i7WLn|_5V()liK9f=Vk$yL=Ukr2|q&ABnTvaC&1jl zj}~ki4%4C*k6W1%me4j*vRo&(Vd&m>tSk7>NS|Q$A&>KWE{QD4A+29yv0h zdQWbC!hKD;7BpS?4uc50fmIM@5;Lri^?!<7pof{bBVB@LR>s> z=91WVfr~ADZQ%4oA1i!F1?d%k8R4{JhjSdkDm>0tw%|h9CG+9>h(APVhr$at#>wT9}jBsQ)O{Ur6T{^YmHL WSt`21YVnZIhVox1L2v^ diff --git a/plugins/other/assp-smtp-connection-statistics b/plugins/other/assp-smtp-connection-statistics index 649276418c06c27ffda513a14d8b2cbe89d94ce3..82919c277c8376dd863430afa468dfaaf89b3b86 100755 GIT binary patch literal 4734 zcmcIo`)}IF7XBIjinBmlXk*Ajl~&{?3Qb8GEqN#;UF{9Mm9YootzY$wL)kX_x9@jm zY%qjm@0IqVR@gJ=eCPcj^`APKOgm#g>Lel!s?|EZvHp?I8$kV_l~0e(v&fI=G_{i{ zT?Ltkmr0ybZ#cYKpq_LzP%g97V!WejHg+*~*v7cO-pU1z5f@)c?c4 zUZ$pT+NFM!`c6y(do0{PzW7VQ&pxdf*bi+#=#tP#?Z6&0(9t-J-B`9=@hlM03e>=s ziq2!#pZLP<((d-owza)$?e6{!h`C;c@*NR5qD!Y&gZn+2DwT9Qo!M;G_M)sEr(P#u z3MpjAO9E@Jz1>#dR3Yadb$d0Ff~10@)xLh7*(uV>ljiNj4@9^7&XyvwLt)Mazh0S# zbM|d_C?c1=ywCambhgv`{=3^#`q;Z3K0}rBSHn3q48s9!?^jknb)Dv}7-t@G-lHT- zlUNGP(?9Q>4W3{$e1dhQ1-Ir(boH=>bU-i1xwTEIHMVQiT8gieClslvpn`_tiGDW- z40fbqfP9@bX(q-Yaz>;_UM7OJA5G#_Fa`=xWDH`vp&v;~g(LiXN4OLUDQ!e&hmcTfEVZ_5WldwLMoUSxTG_mL=eb%+_6 zJ=9+4%t%G*aU2Zd1?Znd^Z?}$T3%I%krO1CORElzUvMCmt?vZ zsYG96t#;bmg?EfPb-L}*M?;`J0>4KpPlvLf^Ol=8+mDSL)SzjUAu1{IG)R^PEG;kY zAa?A4!_a+;&t7MtL7keenAlmMBs*b2*U})VkV%Y20Hn1t$UP`hC_!`;a$nJIwNiP-Y4xgda7epv zx60IY`j=&qL7AjnTRH)oWRsc+`-`sP7&VZOtQ=HQi&0gqG53Cc9ugiynW9Lmt-t9% zPj{vbH`H37 zl{-=mMUCsCQUOtrVl+VTH$ii`K!VrmYCzvfMlR-H9{Zc^bOvzjM7mu)1uqE+oha=g{(tm;?FV4l;r7fHx~v zdN#$n(WD*i{>n>4#Fta3t{rK>4=D#%@q^~6G;%E(xq5eafEu5GS22%o-te#v)aWdkG!J6<97DRwfQ?-Q z*j_fHr|bAUPDm!g!5Zp-X`?e+2+AUeKRAfF(cDby=8Cd}=Z%`CLXeIGTgZ_i7$#wv z>~y?+DjkhvgO5x{)~3qDM*5I#mLi_tc0R+$0=pTHLSSn271Wip9CnSeIdWgOM)Gz0 zb*Hhjkjm<(B8)Mz!Wi>QO|cur$U-<(}u zJnqcs%`lKm5BOfKh;LY0x48}T@oIO&wQdn+@#o%M!7pK9J5$olmUnCH2}iI@Uvfiw zp??Qpu#?$V4`Cxe)wbvc8$7@2ogD8cdgJC3?r1m|X5-)SJ6ThiU*Y*mSlY=!c5YU9 zP1e7@zP#?{&04RPD4NE~>J5LIj#hcet1#==)LOO(O~UmB)e4kz+%123b-TL9b3D+P zE5;Z7y#^Pcz~9Dv~EDd+KDHa;s~1;YGM!&=_~ zN(-1#d4==dl-)5;11y=8n;`WF{Dy@dvx&Kwk!miUynj delta 1804 zcmV+n2lM#;B$W;dABzYGIqAAf0t1n^AAbO~SbcBWNE81XKE)hOThqos5>-0EH7ZR> z8kM{#Bz^Q;=v9lo7+-C#>s^O(*F2y7nVB`jCM0*2?pBJhcV~V(?=#MmpW3<3+LJJ8 zr!tG`^(XMs{YTbIg!&GZ)rXTj2@^QVL^^}>C=c*usxs)0M(6PG`o0Er4MOYG)qk-` zT~8&6^h~G{R~unMZ9-4Or^lfF4F&tTnW?M`gCq+*1w%2B{vTgL_A==*=WkzS1pU{s`1iXagt852vB@yRh5Y>A0O;cX#*4r5c8wOg!0zqx0d-9?XnM zyY2RTK5qp{-cni6j)+1_-44>o-G6I!TIQSiSIl0|wFGU@Jf_FbbCF?K1=_wHhLP-c z-wG`g5lg!_{Li_4I3e41M>6rr$~}trhp&QngSS^l@Ued}g1?lj9xq_aGQ5UPuU1)4 zILv)H$peh}0Ma~5m6psiIO!h`A7He6l4QN(X0DX8hcra4XOlu(2O3+Q27ferC4@j4 zFf$2D8cUnam`F20Vo~Fknn| zBvHOB4A3A8wJJ!<(7QuCMSuDS5viDL2C6F0beW9A0?=w`QJ=So?a^R@qv6@x{_sbF z=|*N6>l#V5)9N&O)xfyw!$(WN#Ax@#EUi(F4qI}IV*7CkYS9>Fgqc(XRh~t}UL<#< zJQ0x_y038UwO0~60mqk9kw-?85mt0f2FavO6&8X`(aaW<843X^H-BkvIQ+1N8afxw?&jo`#7pzd>zN?iIFz-FmI|oLHaNUhl*1tL-Z3FX${ zayZ(2aH`DXh-*R)!#Fhd=nP{;L{WL`?E;R^?{6Gt@@tMgYO!|oPGNE;Yb@(xz-1Uq z49UAg)Y5&F0JVLP;GImuN0s$OoMP5BiWqoZUNGvP9$)?!4u9Sc4nB;kXSnKl5@Dfr zupvytMEcH~{>9P9CN%%7*S6^Ky7P&$xY4WM-or-p%l88~8eHDPW$bY3zzRfuEz%jAhQqX~#og9Y2}@{u23f9G+OTx(@#oUDcBo9S zE*puRktx?%-1{ut`}2vm;*leB%!-WMyvBV^x_?$QUHJ}!NJNE#FqOzLrC>lX;rnb~ z#7c3XF*pS=WXqb;T6CN=O4hSW41$On6|6c4Uf4**ukHR2M!lfcr)N)OS3i32{fAXAr+*j{2hRe-AOc&{=NmS#mHJFz1?lMOB|&Mvy;(GruUI(nl$ zZC$E8)5SNH!%{Y>Ncf?=L#cjwb-Qc@@(0DAwMFSm$m+cGaBy~fdU$-aB&y$U zjaa;=VPG3%A!tDV+4yWi6G=NEx{nNCR^$rjjm?4sY5_Q8qP$nf+`pCb52W>j`Fbz;EEQd0wYV*3Mg9MqGH2O-5&!_T4~by_ diff --git a/plugins/other/assp-smtp-handler-statistics b/plugins/other/assp-smtp-handler-statistics index 85be7a7ec7c48d38e2bfc1d28def7dbe5414539e..e9fcb4445f7ac5677dae61f7d256903b3ed43639 100755 GIT binary patch literal 4610 zcmcIoZFAa468;Roq7O&{Nd(xr{esUf6CWnjVoVu3_hND>Aq}97khC)+6K~@C?f3MI z1c=za+p0avE=w~#&-ClljjMlZrAoGDLDWiw49n#zy>b4K&l^B}r^2U87iknk)R%6u zq;Z%o@G_4jbtjW?L9+Pry#RGfu2PAkRyuK(ZsdnTI!e1bP&)7weJY;adt<2ohk@Nx zFJsxEUL*rArlC6%{%>D`z1yF9Eg0Baxk1<=VUU`kJ7b{JnT-8dHGT0EMz&sn8oEl; zMeGOjK=>UxY#+3p_Mvll_+LQmb`dJ@MC6GM^~b}zceK9ktw^}4x;(q=3dt&k;@ zP_0E0I`5k8rv9q)d;Uw1%|2DR} z7wp{5L_|Kj`G^z#>2#;R_TJz0>0|e5@{Ck=zP!4pnmuq#?W0oRQ#E<+i&?rr(l01U zWfCi4&h#$2gW(eg?K#1^(&n@|m6-Bj6X}><&N6fBRH?Nq)Yx8MrG?O>mx6K`is$Ct zA~4vgjsf!Px=w2`TOnzLJYA$BYzEOhE`l*oh*Dz^*IxyZA}Kr(+d#s#B$#E`78D#v|~1q_cF`^>fC#8QXrWWuO+#piEFo(ZYbFGUVH` z>JDSi4LJ;*pYVCt+GtRvx-aH#8fwK(*vK^uh!iS`!303sD}&5~LP80OQ=O!mPn>#j zq@g_y)ORv>8@PObEnXoJq=3SAStM)uZ4C4xh$-p|fq}RgzV#+v15oAp(!&KB@P#qh{pPomA$55sy(sG0O z=V|)+eLKdJrY_Jk1jn)Hg(~$$B%~YCRT}94rVUWta)r(rN99trV!H5H#$WI0CSiff zTVB4%iyB)Vo`rAMM{(o~IYa1z+37v9;7h)DHol=7rUDkNoW+rsO34wPTwIT70uts^?8z=h%gxO+~Mdle=ei8RTzH`G= z;BUxt1%s}aXts4aFzzqCL_`9$gzCnT8TJNT#}7Nbq)NTN53Xr&j&O{6S763T@9cVT zIimByXfXMJda7mG)-pS8@c?x{;o_2geDj8%y=A;gprjFJwMvn|>=DefB@@YQM?^P> zViK!F-=md9=qURKj{i-qe@&xWYkSC?L9m}YAd3e;IU+=le;i%z<1^`!N`!}L&BLKb zz1~2qHqrjh(awx!%Bk8dN)u*fy_7c4JG)$8W#R_$POE2}TXDh9EyVz9i% zY>zo2x4`nSF&%@3?`n4s_11NM>pK6O)~Ai>i%(l?7?)L#Voh$C05x5$1cpaig!jqP zxW?r3u5XZfoZ@CFH-hiWnU$SsvM^gAt4U1QGWS2MZd z{oKr@yu!?fg-JU5MRB2Z~J}0+MGx7^5-TE;{_@AUUfh( z`&ePTFh~G;02+SrW4wQGggApQkvzsVgjJ>0W09qco6%rI{j2WyL+^^tE(fFYK|k-O zvcH_!ig{baKGseSxEt6oc|4$sUBe%;Fd&^q_ Xz(%o}t*T5@+0{G!G7q{bx$=Ji9AnlG literal 1804 zcmV+n2lMzJiwFq3>AFh-17UM>a4mCfbZ{+bVQyq>WpXWZbYXO9b98BAa{#qiZFAE` z5dLicimekshRAY4`^7E{CUuMl$H~|UeTgY^md>(@tP^*qn6#w7y}NgkBP9-$8PE)a zbhrE5zTLCy?EK(mN_z7s@lr11dVL3;xZmV?f>58J^7P<1OQHk@lBG*Hjk6Fx7D7UA zIz5H^pHCI23t&p6u3G8TU9u#Ixpb9gI#N3F6}$!b0@U|#u$SqjkR9kJGV%qC*qjG{ zzmMSmJrxK0D;C8a;0CD`vpE61m`f1|)e896K#iEva4dpo5%Hh{2krf~+dgm)4!+*1 zQRMT)=N%ZFjxL|VQtPzidF%DM6((6r$k2;PLUHAVY3x32wOjh5{w`s!XNrT;7#`g< z?`tNptU_hKj-r@%Ixm^x30v_ln8nerr*`+4g4>z$B%m;Nso?KF3x4UpJRiWD-ed}2 zG_1b5f?ccd4BFjV<=HWH9`JbUQ* zp1bQnW4GOaX19b8at(UPp^yQwFy9t|z+Py9ARpEatoeL}MZ@KbFynD6N*1CDMv5_B zH3DJ5DoPYc?(^u<=K-v^QY_>OL;@@UE~Svh*o71;JfTst+GW~Z3Z-W^CpEg|Q)m;6 z;(Ey?he(4j@B{<6A|gpd!1Dk!C_=3YQc-(1h+~w$7m@g6J5bemBPV&xt^lKk5e>{T zseQJXU@$s)*&BULFpiN(C~(wrVyJsaVcH}|gD>+;ZcZbh2T>C6j|8*r_T|xngLZxa8w z-{>)sH1`5~29NJVVFw00;gZEL$r2r*Aww*1xx&tgB~;sK7>7=!_;>~9DG4<8X!*Ff z)VSs2I}hyoSS0Rk&*7Z3=(BMs5RA$_x`S-Eh!P$+FM5-~nsn>St^`iZjO1ROjU*Ew- z^s`re81&EX;2P{`;lKuje=tcx+|BhuU~D9v&N-HFj~3kL314H);@Ql8oBy1~&2?;G zMdNnqQWT=d%Z|Nr1n{tscxPzSX@d3iro!Flk$R^xpOSzIrCX!YI6^FMmUw$*`9gy5 zts61MEDw+Q_C;n8c1?l)L&bibZ<#7G?`Y+Feuc=FEYA2IZ7B=7UShL#VBdtP_7F1? zsU@0j0-0lPz_qw8^^zUv|28~>;Sr`|+@BybPWy*v!;>)_4adXjE5s|T-Oc^Du#j)N zv}azQJfU}gDORbIJ4a^K5{|P+w8)oCCM!gq2<)k;z5?1;cNCue3*MizWY_CfbuihV zQ;<~!YTPjr(>=ns@riUXlibH?%}1rJQE!&B{fV-jJ8dz{7Gx=Lj9yC4!6=i#1V%?I zJX?8Q*oD&4OzqNA$yJpytTSMCbf7NB@=iDB*hr{hAf`dDpjOs$*jtj$EO^|UsmHCy z-tPY9R61Akl|W)&31oSVvpvocg$I_0jej_31WdDAs29xryXXEfb7sxigSTDRN|Ec97Ob2%dsjNvj$XvLnq&JglDAdd zyDFwbW^-lDqeNzSdnBd#mi7htTJdy~J1ipPW$Pd;IBG1Y7!ZsFfr&3-rP%g0&I$&y zWkYErI!hX*=vg_k3z-FbzAY|Zcyzs;Xphdv<~mQeP;DI@1WOjk8~h{IY@7I+ma8;~ z+lEW*cx+e(dlqN@5)3QT1d83123WI6%=N%b%h>+xtcDG_VWzvr9-ImLY4q^>$jqg* zLgj@E(`^11_qAE83{Itq3dQoCXvF%H$;qTs9>DO@R0mXyr{$&ELzVyXaEz5rB8ed4 zHz?KLC!LOo0_B71&&Hzkd%^l#Wb)*73q~RY#jaEb>E$+7EJA~X8rOC6?>dkEei!qM z1eFLo)B~<6t+r(rj?c%#F$^ZX(^vfo9G(ovN5erORKMFpk-QgCc+*LXmean~XUcgc zVsa|ejPbPER@%7urKx5Un~?tI@J>fM=5}&(Kc`rPsiJ&oEjgs~asH#);1YlH>aEf~ uUi(nUD|1>das7We Date: Mon, 6 Aug 2012 22:11:14 -0700 Subject: [PATCH 09/11] Remove plugins that are managed as a separate repository. activemq: http://sourceforge.net/p/munin-activemq/home/Home/ twilio-balance: https://github.com/jsoncorwin/twilio-munin --- plugins/other/activemq | Bin 18582 -> 0 bytes plugins/other/twilio-balance | Bin 66803 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 plugins/other/activemq delete mode 100755 plugins/other/twilio-balance diff --git a/plugins/other/activemq b/plugins/other/activemq deleted file mode 100755 index 34b71f4bc85b2590309f49d7653155479130f72e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18582 zcmV(zK<2+6iwFS1CnQY(1MFG}IFxJqw|HC7L3I)h=F*LKbYzlKp>LoP_}yp=Q2e8Ys0-zvqPw21CJM zYH$P!24_=)siWZPY#`J>wSYg906GIp1A*8`M4UGf@8|tBy>HF`mkQ}m@DHHV{t*s* z7yfD*0R9>XB!Y$iLddu9r+Z^*`2Uav-*^6jakv^1p~1p`A>^;&Pr?S`$zU3uO8Glf z`0n!$hofMu{J$Xb-T31ur0?ax_v4R%Yam(pFNFLp{7F=bhYudd_=_dt_u~(ge{dH5 z3nBj@{%|3HWD#vcJgAWN2#-({|h1zCwm!iYJjw(3ag~X9Qj=tE_$$0aQ~@9f0tV4}^!zk{S)2p9J)FHP{N?0A1`O-XcQ_QaD=A=SG?%=X_P`E z0t(m<3;w(kLPNiz_KAnNAb6cW$p9bR%pBD=!^|uN~F^R@RnFIuqzUt%$U6~ z^bk4&PtviS^<*^f2`EDWcD$dPQTwi_3?j}K43;mLs^Q)N)jRrP=B@?$|KLnXW z)f!|q$NLXZe%${115KiW=g$UkQa(EV!XrQdDxT~Kq?S42%wYNHz$~w3-01x5jQGDL zKjQiSMbGv(-v1)tNY?xR1(E*`{U2QI-}HZQR{ysUvH<7*&)?aw`oW(n3xWSP`#;2& z{T~83^ZOrG|M%mC)&DJc|Mz99#_9uEeITn3Wc7hRMOgJetN#C~^*`(P06$fJe*KSx z!8HC@|HF~2`hOwB+MJV%Z}vZgslsQ^TwdT~X=tYpHpLi0=hYUo!2vaiMbFgt09OUT zNAy!QOMQ%~k)f>}#L~!cUn5_QnlRfi|KzSIz4f6>2Tl)JDhIz*@h!X6hW3#*eAi{a z^bCR%apZ~W@qCP^2+wcVogFytdn;~Mo_=xj);ak}5sud;DMY&mdHaXTlu*c z2XlVhBkYSkasi(iLVsOj$$O2Dl>fS}=pS_Fj>p$6q`qSD;V6CGROVZzKBVAJV4E>d zeX*K*jE9XaRfvsE>09QOSRznV`eEtxbO&FCorBmkrq4f-Y0fLd8+9L^#IBfFXI-c) zvoBg0M3UCyKyJ9rthc1Krk2)L27xZ$eyvy3T`qLm>~!(6^Rba@d9UPb%JVos2z@uw zv87=8nKQ&*b^8-c7nezsS@S(YX65+3&`ioO{Z(K184O2zWL2JHyfnAJSV+H3(TYlL zwO^Hz->NKfKjpeaCD_%FeJkI7y^Va?qK+!J)++Lp3omh9=gD^>$n`2b%^DVk6;lFs zDyPyg5+$hvKA4$wn~;5*pfFm>f!^KHNXOJamgpTZ+gUSYFED!KAs z(2f2k)xUXfaF{a%0XHzQsmmRnzocS`#Z#rEtH+L9Z0XkIXlAfPCeRhdMyl&U2Ty2#7&Pa;t zL|o((-k_S4BfoF2%6n)N$Ki9h?76=2@DmxW=d=jh%MTU_`s_Mb)N_q&``QI0V<-0* z873^W)Ze@?|548bm-d|z?PA{voo1C_{aT@sqtUCnC5OG#c?B<=7HYImLkmJ5;RSWq zmsejqu5W!gMDW-|QFP|RT#NWK4_hx#~{B)fBz9H|*I0 zVXn1eu5D^EJ(Ggc2mC8kG!#)4(RWc(;sn$bCU#2NA(t~v$TH$(l347Ge1i*QO(P1) zdxx!lLW@svD47_{nT(ub55GO4w4xq0lg zt3U}JjaYVZ<2J8%yEFX3rg3Xir?=l}Gl^VxMkwI!x<1n#H>8!wOh3)$-M&w^ZS$&_ z_CDbvekAplHpSP+Cyp=Qd2wp`3dBv{c0UfDy(O1>LJjh(EN+>UVn`;nTSgqXDfOWf z%<8i8z`SyHi-xFGo_m~qV0@j3s_u4c%8>mlaz4HK0;abCRrSc75Q+=!AV<_}uO+R7 zKX7GwwU9G{h*Gt2zVi3B2{ce+k&VuL*#R9{!P`9dJBR8DUd@1i ztnRXQ=wVGwZu=Y8?j$wHYY8}97~OERGF}1Y&=DHlUkiSTUh`X;sku|O$BVuKfqo1V z*1PrO5&r3b1w%<9SbX^nVY_a`n!{m@_D;=<3lhp0DY*Cg z(H^_;@JRQ;lMgN;9g=;lHOo<*{xysq&M@y9JN}jvJGIY`6gvlR)_)uz@;Vkj4lm|{ z*6@!e+$H5W?AzS>$ff2e5tY_?PW0KiXW1A@zb*1hAM62z!sI6en1!wx&2ETQ^%$4< z)``LEM;{)r5!a-vYMjVzHHy7zSJ@xXnN!u|P93}HQOJ}vr!zBSnUf)^;bBw4y#@{b zzc{$8d(|Nv(ZBqP;j)kkVdF_B-cBCf!!NKKoiU3$Y#K}1w5*d64?{Wim8VL=upA+7 zxRLX_@APNCle}YRRQKpiSyXihmvNT8*HXz{G}vGVJZ|a^uc);%iQn&4^6O)XPpmge zfk!E&ku_*ZoyQW#G~QXd4WY*huAKGnOuYKiIlS~8Uo2Nfou=t&;b5soAI^ixHm=gw zJ@DcRPDycH72BVlT!*>G)ljBVS7>(lRI|sZaz-y^G9;<_LA^(l^6R6C5y|9LJ2P!M zU7n8LZg`8E&?7xu_B^kld-||L1=6_EwWhJ7(w0$zuC~1!ceGk=JtDBjHqiKH+aX-R zej72}hv8yR%fpfcgZAP$kL4+b3Oz(4@YW@-4u}wkick`-+(XF@fxDlr z+Hha@g<65_*p{Si%tKw5F*3g@*LW|pc_!Z0u6p69EqZUQheX+O%e?kI>NlH*OLU$| ztd6#ka_Tb8EY^-pIeGl*$V+(>}KH8Z9g;mrK}~OR(Lvi~DHB(sC0w zIbGvQg8{{c$$>`kcnNobVXVejb=@n~qU5%o#Pbox%e4}q83z2$F}$15JJgFs#NOnb zQq3*Re93d&6x$T)n0LfLpOB!XDk>?eQ8?&kDpeL?$*rGs2D0C!LsZg!#Bn-YSlQeD z*HOrG2Ws!4hLZkEG3%B2bPk={P|Fv`ahZv3*GL}Pre<|Mifdbf_vzSWK3B!K(&ZI} z@t5tzMY`J#_MCW>WN1M)lWz`;^YB_UAs-rrk^fzd-yd3sU&q`$HKLpK{pu_^7XU()k4LEbbL2~XNeaOPJL zQeaEoW$DDtS60!1h|K_kDgj=5S_I4WpC@lgYNDf0`+wn!}Wrv4keGT z*lUA7H8AO+G45slUm@P{ua@+LBf~{f-jiv@;cgD1>fnZhk5b<7AgH%<4SBG)QZ=?uHgMs55 z9x63Wat^;AmzXGCHMo&cI?QvnUEDBJZ*XwsrrmFK4>n#$biR#053|VJ*VSecoyxC1 z##1;-25}$f>)987;J~j^_t%K`AFIE4QJlxtryggfmLBbqW0ez?2)6#+T8_O@hh0nm zndl1~A1+0KnI+@>5>QrQfwYwxUz9J@hvUl~3Gi|@w zm>CA*cNe=!$swey!M=NWnG% zcv^@&Y>ur5Z9B-VdcxYw68{5b$RrnK?noaR(L7(4T?mw|ZkDZgE4D;5Mu(KPspp~j z({`CDp=B-qiV|M`mQ9BbRvuXlJtBJ#LH7!5-b<*{-M(Fmow~|i`fgF0fw%_E^R!8@ zZ5^1GY;JSQ-*{JjA@M%tLHmlp$^8RSmj+hte7m38T{NH+@k>f)%!8Pb_$G;%-CY5- z5$+~Z#VgKQNwx@fPOLU4bM7Ggx>BX2-Ji24abnxjp%<5oGmc~Wsgz9Pf-6<&t6_M@ zfxQz^F496vPN)BhNy9dZbsbq@i2XeUdpWN3RkWtbAU z;^zCVzD9`q_FA1rkW!ce?rQh-K}VzO>Ts|eBP-P*m6g%^-eK{|?_N!$me*U9Bws)L zwC%qBlQ1WwPZPO{47Y2^%-VIcTCgOyAae}cwY`+2v2|$3t0kv@GbOLhM}tq{{{OZ2 z6>w2)UEhQtpmd|a(A`5wcXu}oFu>5l(1?W~T>{b_(j^Uolpr0_ARsL%3L@$^gL;kU z-sidZzTbPF@AvyyGR~ZH_WrN6_gZJ4wf5Q3c6FPUg<$10SB3)lQVs`>PbAQwHM`85 zVc|`B^a*YHA+hcB&PCfn!akf7p?iXDVRtB*M1r2z1zsbl2;ttq_=tclpI;&0K`J9A zbK5G|PiBO;Lb{T>iejKxskgUjB)Ccl|AEInBqrlr$y<5yx*PpPWmMYFJ|X>VTD^RB z4x6y(u8kD|f%`9-))&K?GlY0u9gl0)+uUJ(+-v0PSf0rhQ({sxrR*ye1Ewjr0`+uN za^;OND>&8`&NO==<5e-d#sNGO2M7Q-1xyjV+ez@^m8~uNX)pJQbJOzlU8YS`;EV`g zZPFXhjh~HCS?%^)@Jlb)W;<%}9T3``?-Kj4*{UQByo>F%A$uYm>6Ed+bm$xR>1D3* z2?xi#nBMvmos;YYf~}8gS);_Jf|6#dqZ%h}qU71jO9ye1&Fif>oNL3l0~!JoN|uwk zl}587OIcn9E5aP_Cs|HbLqh{ez4b-0*KkcKda?=Lc{8~zXP0uSZp>XOR-N7}B!}=xHw7QhC1C*t-`~&4U4()3N zd#rIzy52R%!g4G1%!69*spE>YOLgmIl?Ba=?Q~2t4kY6^bn8`DlsaA~6gJ5}EYz!) z=rFH1o-8;3GjnLvE38;Au4=|5Jo2lTqgqHdrt&8l`@^?BU}n+??XGYvOG|KenljmSH=yl^(Cj*Ww?_lL`{$H?3V0DHKSRX{2v*-7t~TahtQ~+u01M$;`CXV4T*O zA`Go5<&x}?2J7`+PLA_oBsF!0mJ~Iyf;;%fvl&(o`>>K1Um1s8>&fVRWW^enqSJI) z*DfaxH}q-VaMY$9?^3^yeFu)IoRp7MA_aD+=Z9>TDN@<1%z-&sn zc%nZe7{<&o??or(4DTs7yhy*%V{431G$_Yk$LpG*r@VZ!T+I~URcJ20FvT$9vcq~W z79&5yAd1DoJg+IwCFl`@*7ZJ4cXOOdRVpMNT~svz(k^r9R%`bR+h=c;kSv~?zsFa5 zt$#1j#h#hzQS&@1J*Tvo5H-69g&eC~SzpbrF>bpw%|zQq*gNI*S?+0NQxTEtl9?Yd z%7SR6T=u(xh3)c!9-W3Srzf+Pis_qg^jRc{L8Vo%-drLMeXPUnKp|2>xjpQakY-FW zVVP<{pO;i-|41PDO?I(2PX;*2A5Xig-_nuezNv2=vgGs&eoAV+#5kL~{bIzU;m;nH zGBp{<$1>@OD5ozt+tniA9+6Jf3)f-du3S&l)hr3d+2iYQ@V0m%<5PrtTiqIJ7qPXy zy@)d#MOmcTQ(%jry6q!iQB9SG?1^FhoGs=GRd92t_+xOO;q5>Jm$ZrlT21cD4_<$G znehN+sco%5xT4uK5)FgI@dh~$e`r20g^B&GU<`e{O#(FriqN;Z_+!?{5yppc689fk z3|g&uI!TrrrILqC$|cn@C4~fqp@66yX?Roeqxd2cVH>AyhWP0a(tUdJO61k z9}Tc4^{kPjW}xb9mH_wSINMZL}!g-BeIWIZWQjp5_EK_A3vT)yi|#Y7XGBY*7i`a8L{5f;w39rc+D+>J#hhC9Igpm z*I{0gTLc{UbZs;&!grTH5c-QR?;hNpbQKo@>-(C}tKC;=qEF(^9BU_A9Gs~WpgoP~_x!SyoUPiZf2Yl5y_#v`J~cxCn^*RT<> zQ8%TIOsp@`eCwT74~V5~>^Z+)T-ifi|HVShVz?L!_e-qBh7CBR75P~#4ybw8(u|Zg^UKHY`cPC= zs9u0pvEfuEM&USZC8h*zS)SCJ;-j}KU8k3)wmp^dmt1D3zcPuiHk{ZZAUW@MfJQIm z&MAn+bU!Hi6OE6?hT-hc4AS<#ZNg=nn}a|WiZ}KNV{B65U5Ufu8odO;$t2-2iTAB4 zy43dRX`_?PbJ0w=)%p<#c&lI7vUJs~u z!&Gwv5@7|`DJeouY373ya*i>0IOEp(?(VuilwHVjW@%E&R`cSIzzjdSFCR8o=y(rj zcJ0_Z-0YJQ72 zZuthH_TfrBfAS(YWZDiwiP@TwgInH9@|@xF)r>9in;ac^1?wT0xt(oG-ZF%AFZ)I3 z2ese17XtM~A)bdN6$Oy`6Zch)hgcD5lKX)Hn;m3mS#x5(Rgv%8wr(AAd0P-6IaVGe z^fl?;%Fvi`6~#K34qwdC!EX%NlxEHfBxmR%B(&iedY~#YZ0 zzPwkyiY{Yt1ONJ7Aa}-~CgPahm4+#+j)_o9fjRuV{1ihqmfP-}9Rmj3(8TE67rim_ zSgcqgK2NiP$|&PKiZF;@-%)JKPL(GHI-=bbeCtz;aDm+g%@}}g97XSP`%ODi;rlp7 z&is_=K^*Gmk+mQ>Ia;bM)R)e&HjJlk*>{?qg6V58grAH}2Ba`rcf?LkYN-aRW@(0B zsX+5mC%nzVQxzuI=`E}~{0s_;zowhkJKd3WSW|S8|@Qqj^mL1iXF zU9rr^ddyBb-jM}MYe&*<3ijE~77XKe0d~rsQJcMU4pm;WiYV9^TUMcN?mVpuxmePa za-w{-oqXSxnV!`qGWZfU&PBBjPNA4oWjZPR%z7S*IY0y}DYLD;o-z?c>b`!wneql} z!)+&8YGM@v8?iLiY@-c6iw5$+YXlu1$VqprhVkE0q{%H_=@m2H?KDbp9aenB!8E62 z{FFmob>j-~HDIOY*x0w{h8I7X+lEkG1Py=bs0$kdhf4k;@GkvOJv7}RHg@RaAwsm@ z3A+dyzR|w$ojPK2Hv%8|%w1fC57;yBINDo{XW!hrp{79kdN&^HQfNC^3x~+2ZOH+` zWbW?Cx-t{rF-oIvj+ORAEpjPh!yCoNcgVxB=gk9}iQMYrvE~P!bvZ#z*wKNz?@K90 zJQ8;DLCSBzA0TxujfmJZ4^8u;G3i!BfXwTgc^eY7>z{xc|i+ufO~zrx<1WmiZ?sg83gIWz;Op8;h-c34t+&4RTUtH3lQ z4Rd`aAimQUlEc@*D67OM(O(@LKf+tBjB3G7R1?*^&UJ!_q^&|cv|Nq(W>E4u_H93Q zLQn_(VNSrRA%ppZCcg+uWLj4hJu*X!Lv0%~{a^uZ_p|IFp5}~rr91Cf=Lx1IiiaX2 zH0mXVBBK-=X;m9Rcrq0z3{Qgj2^X*dP54{55em6zuSo01ZgHkENnM4$H}Qzl3uPc( z5g*$2JQ^}68+ug&%*@elN@06)s4js`=rLN2n3;a3JQPbSb#EryPbTZ;F3lWNLaH8F zULmpk!^r!c**7AVB9?QJ$m|pPgJBtWKp|J%vV$6ZZ_>27j=qKBOM>=A(J1gtg3I&} zS;>o?bFUE~(V~h&asYIkE_$O@CryCUc0-w;q8Oyrrd#s7;?$2 zB%5OT63Yw|c1i7RtRoGo?RI(MEc^^)C=Lxpo&w2r9G3;-^7$Qh%i5AJ9Z`o8ti?Zwe>>zY0&V%Y)0nYK>hShxBT6lzF-{gKI~Zr| zQIsyIwj*g!BI}u~r0_?A8*Z;g&3gLR@t(v_rjdvncGwj<=dIzGOvV^(UV1mgdLd_w z{|a`?wU&AjVA-QilNZ&I?9(d(OVP0l=~Mw)X@NeksIM7#3 zO(junFI|?b^TzmG~sGQE~T`IoSJAe-IRFaR9>6PB?)CK*t_=$`nWsH@Ak3g{? z_T4;E107vx4|7#xgRkf13>r}KA?^V*IVzX#RwEHJ`_83?NBXnG9-{_Q`0DFz_2$QZ za!prkfu)hi?T(Y}YPa^)vbwd_tB{-1x&~&jhW$}Ld@?Xp6RNoBDV233{vcg$>(X%p zvDv%DZG`6VxfG%|C<1zHTw)2U3h17QufUpY9g_3c0bbqlE@IZlzQQZ=T(!4+x{2J1 zwpENU^P)Y+u9G<_cylZ*s$TNVtD(#d$$p?!z}TB}+5P78+wb$e-Yk6xrE3ZGEhz2q z3~n-IE(`6@Dfom?u&W?tf?aU0?+LVp;m8kM%>CkxK*^iNZf2f4cEM#5mya4xncrD) zmUWcTKk*tT3%GT&xN}2;Ps{Q0rY(aiR zJ1+DY8+wmz@MJ}T<>2O|?1Uwa$c3l7ZAW(xOFN3mD~5)*9074bjqJR}orr!VV=nwA z7n%hDagBkRn(c&rO`W0zm!j%(DsBw7y^{ejmZt_3JYgAc+RY$xbe_J*i`THM4S0Oz zR+@wz*-$&)P-;XP!w0PE!_pV-J3<%k5{r2beZ1=Y{`iw=a2XTwoVB-!AX>vrkmS(| ziJ`Ye_5S0v#W2NYu1M_Sn13+rm_PcoYp&*g#P_z%X~lFG`N2(TeKCaBlt}Mx%C?Fj z2~Z+GGedl5hCFbyjp)+_(k*9~l+Q%c$0WD>Hm`07VqLv-LQ;}*vo)63l3$3{tCgxv z1Pgr!DqlWM)y5ulVfPxX*C16}3%>l`yqV-3p+NdJj>>3r8B}y#toqK+Y6>o$W~z4< z5Faei6yL=8yoW-2OoQ}^;no|JTf#_qe&|t=Nb_QMFLaCFSq8KbAF@-Qe2%=J{6skx zV1p^FA&y$6LmRHlAYUY{d*O8%LEw#zvZDRR$)b1+B6f8}s4>|r%LTQnCmD^&c^5>G zRlS=(GcC-02w|i=-T63{guMOses)^d1rdKWGfmiem&5`pNou$C=0=AMd&iN-(}zX3 zCn`V9tMncYY|^LPdLKEGJq>1mc$dKL8s|Hz-6nDk=9)ySkPCO4b6iBjt;4(aT#`Cy z3c}=uyw5xH7t+x6@8Xn=C{{kjaPp-4JQP5&;@t!|P%6 zcLQl;rnnB!RwBh@MXM=td*mwaj(DR=MTnIbJ)_YNea16idAv5w_VDG_q+F`UHV)C_ z_9S`(19oN=y?E7qf8Pc#?E97YGAq+15Af7DMh#Cfi!bO+#sN0Pqwz252;WZ;c(@jd zRe>?gA(Pd9!02@TYP zMDts0i0!K3Ju{#kxo}QEd-s7kU$hQ!g^@0h3 zSpic@Ti74wZ0Gg_y-R{npUm7f!gjpe;1}(RZb7lSm8Y4W=sy=Q5$syiuj{SN&P-z? zJF)eE!)kG}y5Amk^3cSd&=pJ)nCbLHsrpuV;~fev0GsPVKueq<+1kv!B#$g(NQh$#Ru~Xl%${>^Bd>+M7uO5`eMpe^lpbD}kUh>U)_>#D)x`Gp zX^`?UevX6_x);@>X7l@UOSLr1yS36Zr|k^3mWBi;dSo=8#sf@l40Ly72@Jnh(VQ-8 zdZ!4QQhx8}F5CI&nyTI5?ubI%CmJ?f9I<#u@0P81!*2&Q{AyX>pM*?MD<7nfbl5;c zfls0MbK*eFkCZ?6oYFtHO1p@LfPjnpCp+a89lfM}8|M7AQ(h0<=*k44$lUguJ;|MQb>B|c`dm?^fVRFy+kx$jTEG0i_kcjE-38dk)t99&I zk*M9<*Q!{CAnt{Q*$|F_G`qY}-adWhhP3#e(-du421Tr0X~m1Q?3vf&%VOR3+@^X% zjED0$gZ!O)p`89qY0gZ?g#P4R&IGSpXFyFf%O;@1S`6mv5?#Br7rKj6XsAYbOI2)x ztF0sGVW;lCl+0>&iG!!v<{xF^hH*zw1Ze)H8 zga}-$XQ*LUQn@RSIp^kM&UY9Dfky zpfbH6PwevndV3MkON0t?N~zaM!6wQh%*#i{gBz-iN=_;cyp2maxkyA@c@ zZTOu}Zz=gbS`{(T;YS_2o_?@?CsCy$&q9L$gTff_Vr;R8LSH>J-g&Q z*9f{`$M)mr2FbnboV7Ofo1eyO^aiiaGAv^Y-$}hm8>SM;;P87 z_o+lQrK}?5`qolKuOC{d|Ey1yi5$^kox)OueSFI1x|QPK$>QZ#orq7@F5A3TpC`>e z2W@dX2zQr}%^uh0M;1~R*4WJUehdHdCH z3re$8Pfo~3fsCh;Vl$l$SuB}8(QiH2_+?iUgZiS0)SBtQTQswdwi_uS*Nii-4W}!! zNg1|h$)#4k#wFF$NqO27X3s48v>T6)2wlWpr<37W`{`;NJLSNY4O|Vze&oDo?+Ywt zK33zGaYeIeg!fPn#Ee`pG}7)g+tcGZ4Zk){`|8PEtB+Eh?oh?ao3@GmK+CX*`pn9= zRo-{~A4|tJ;F|!r3lnLEQJ9Ui{Q_?)-d__got9TfPUV`$3+|}9W3N#;h*Jg-@BTqJ&kaOg7`YXI#t4nd9D#@pq?t`*$A!Xp~vxuDG0;{ zFDk}6$E$r5CF|E+YU0KnZ4@Q#qn(U$J`>r;jfc9C7nf+@`sT%^jxv=FcTZ^$PIIhx zhcLRcK3=sSF@A_5T#)-ldHU9KBYWJ)i5`hJK87#3RKi}ZTSYs&49hlB168)RtA!@A z89_49Bd% z=QqLdDTM18jcO=kunC;c&(<1a|?C#m8`;DV{-E^DxDFG_)jIFmp6M zb@(B-Z)n}&P`_K(#8W;~e$O|qS0vT_z{f-clw?O!o6mheGCZN!iEU09bd^6XnC;)E zP+Y?mM^9JTH;~_#?*U&}8gKi+K{I(u%Dk!}NPyli`H6Pkk96_)a<6EHD?*TfliWkg zl-8LH^+H)5I~SpvEEJ(=@vw`+%Hf8C2oWz$TW<*UA}a`V9VyE5*JVm~-Qb?SMwN-2 z`e_QwHG7f_uM7F9OR&BEb(`I#xn}p^+v;uNXh)-Nrbt8gmW#?aH)a%z8-v{k$@J%{ zY0G^=(v=K?-6<=kCt5e(4!-SQ(qCbz@VP(Uh^m_&87KWDGR_5@0rW?|eRN5k%F}h| zo`whtrR-CLH9co6)w0P`m*IYFg2%kS#y(tZGREr3YyZe#$F5-?qoK40gxt-gh#KpYLKkgK`mk6cloU$D z5WO67SB~>G16PmP9WAefk)TshJ;_2SiqCvIy0G+}mKCkFeqm$A#qsSsf6#* zy-ty%>7OO5cSNlSBn8TNMdjdT3%&A-sKPSg`S0yNkiJW^nbH}kDiiK@^`am%6%QduZ&S+o0M2TXY%uFII_>|+ zXG#<2{E~Sd8tlwqK|VFg*(W?Z;Dgg~vA*^W2~FQ56RJ!%q%=lLO#F)1FopZ2@{rm+ zuE3fc9A<3G6cTD}HnjLT^U{O{ww*9qn*KUO{<1bYvSIvzMxg==cP+j!%jsMj8r| zPUP<_PHhJ=yu24weUt54kdQ9XjF3`DNsIa;1HG-+pMQDVAC{AW-GhvPpn4Gjf%QK* z7H2PFRp1k(zBm**j(S&gaQx#PDnSN@NtzduaRGDVOTogPz;7Z|*wKH;|fWla?qnb^7Uu;|WsT z?GpcIb-5O(RT%UHuXMr|Y1mh_XS;-n?;#RsEGO#gp!t54f3?%EYnGV_@EcpOOUgNn90jH`KLwF}X3YIkxc% z$vk%Gj)7Tz)m8O5apL`2MVK8oWQ-G)IjY~rb!j68E0N#H{H^i^xqOmz<=p_|iPYXyOY zjkhN_iInFL5+ioWg2wjf&3e%>1$F6^)39`3#1c95pYnjXbyR@EOxwMoE$_E(z zUh4wB1}>vRts(=hI6z?7a#o-KF}iUMpV~m^PMz;5R0H$5yDek;hVt9D7{I#ZvU$HA zi;@=(W#qyJAqNBG6H5#Yi&{+927ciTja)qArCvzEN#sd18_K)e8aq`lV)maAht>`p z8IWi!jL+D+S5^(UVmJHC%5|x>7VGA2)TL=y_}%0lxhY|2rB#2as)Bq#Y!=LxUZYtqF@YCO;}b8Ar6SOmvgc|drE@a zbp-?plQoSZoNg~SO*rDrnrQbW8Bdq+nXXTvDZEY{mvc#NI7RN!`f$d4_eIH@$G;43 zCm`QzT1G@bU_$;AW7Oco+kYGNqiNzi%1I#NG@6G=y47`y8`TmxGqR717zv=&eyl!> zovFGEQggB^p$HZk$!WcGGss3<5-sy1f)?jkLRh<-vE|20VL}hM5;oX(y<;f>#x|`pE9m2^7t4HWY+Qs(4^93uFGd@ zY`Z;jB15;E(FNt$Xp$ew2#(`l!Mu_ds^U;z@br2G=7J2q(B+~hyPHd7eu1coxG4{D zUs+!e>qApE+9g6JnJv|%hRFEw;qwGetF3?rz>~*C1b07o3qA2NOMAn}Q{r^o|8f4w z!LvTi{N@>-j`BBRv_=g0kGvjy=DOii&wCZxfNig5Tg(i!F4pB=O$ys%sv{sqYnF}X zZvBkraXRH4`BbPXgwougoxhx7tz5bML3=G@)Bwgnw)FB;D^Vx4YOLh72?!{9zztfY zS`kPmSgTeEo@Ou3=Nrgy##$;>FS%9Kfyg?7!e=X#V|_)t$Pf8vOBpXK#74S+fY1ed zc(DJehlj+E@u-fG){HLBrwC^}N!ku70>%q&N)E`^N8@YIADCa2nkBPk&TyCKxF|<* zoAoy9=%ME!6UU8h`=vevM|#J!H!LSYf~hsWSQP9P`S`CBO?Ic|oS)29#hZS9GqZ~@ zA2fOgXUF!TgkjtLI|i6Ho}pdWlOl4H?5ka(aFz7S(>PosJJ44zFR)N(BYxUYmWgRr zSjT)Cc*|H97vD#w^VU!iGwQuhik(qIW-N@H0c(}d6MZlD_zkn=_X_Qt#2Xy4JaQec zNFm@jd68x?uQFGbG#?46G`5MMiZL)udEU=cuo1UH2jXPx>OJ*)p>K`0;wH(|UbJzl z_`;mTM2Ps9qPEET9!NM%K+l44S(KZUeU+`-xHx`7#W}HT2AU<`k&79);pHE?yZ@j+ zRkL?b)~RBByYIIP?C$x@Y(PWjE6j~xX4-(4S` zy_Tdm5mL2XCniu~qQT+;?3$^-P4f7l@G0h1zU7sgm+JA-P-B@V5f5>YB`;%e1^5SE zvSE-vn)jlDddtkX+sc#gOMmJ&1U?HMor$XO&gGtR;2Dh1YEoi&+z|{q(GHoZ(ciHT ze;Dj1C49T!1y}!oSJrz`rsSqdThVtb+@d%_?3m-8;U`(C+poPAXBLFBY20diw-rlY z)ukmaTI81jKhS6vnuYlbw>hnt0x}kF$DaX=XM1A6} zy9h1RH&WlW7cCoQ!iBtg)Cx0(h_VE=CbE^~LV8SR6wc(xgv`D|*o$QboT&Vg1YAW5 z>QfA=XdHo9PFYPcjCKJhd9iIO1;p$45+_KCuGL2f(KerBOVwST_*LA0h&>dJ9hrEl zY>LREq>PpMTB<+tQwUKY!+JI)8S-@_k{LOBSIQIofbO(U2fOJUL%R1((V9CtB{?Bi zvpymud;&bku)@iGbf@4Q?v%hdMZV7+m9WzrhpI^cK15sKaO7Tvl|ZPP)!ka!wU-M+ z1hYGzL$kD%@s?>y#T1M)4v{h?fn>t1D{JdfU2#!B!Q6dSeKM1g^$7WFIkH{mk#!xj z7{cPrcE$j^bs)wfSwom)P9Q~g#@LX(@I_w_zk4D;?TmziZUE6s!C_psTu9&T6aD84;Y`C*olN^7XnC4#-|IT6){|12j&jI{0J@b28$N|H1XaS)wA|W7z z!rH=Xe+$nAmc+}^p+rYRZH5!aKhSJ(UlXFat(garq%W|LoRQ8jnhFT;a>3{4>hK^E zVw)*jmtc<_>{E&M&$#qg%+hD+BilN?8ig0ScV%I3MB#e3JZ!E&`fNj z`WHV~UppaKs0;I<$S5hIcKv9bu^3ib6o72jRk0NRz{-fe=kcomyd%^!3`;u-9u&F< z#s+4xZ`$?Qv+vmmVk_Hj8dko&HW`{_7%l8#f71Hu=-C)8rdw9ro!wVsY@6Vjum_j> zs9FqIh;Ni|zP=dIzqzrF0H`S(N1jRzic-N(x`U9{q4oj=(z1Eggg15cMz5)Vqm0!x ztT~kC7x=rJBVe|WG5qS(*8_`7gCA4cXUYYWL`HaTioM1XOYwYSm=QN4F_n1SoY%k- zJ+8x0nJMqesNj3g{enVST}2zheV_=-LoT{1?+cx;#6^Ja;ynQetNHH;uyVV(+@{{X z#7TS|;DLc!|DJEM|A~>6mN2;!$3;r*cVc>^ui~;^aPRM zsP!wcDY7c4Xvi08@2RjV^)G8;T|8*QdqZ$pneZ}e$*pIT%577;(rwRLhoXvD9~TJl zhz-6F9~2+d=bs$p0!+4x1+X+TKB;cy>Eyd6rpHkW5MyHDt-SgCUuOV)2PMV$3-f_~h5dEb#&_7J%YSbU z$FCfI9lZaY12OjB8Or}F{;#jNzT<1q{=FAozjFAsuj@O9Le{_5^Ytt8uOahyUtnV0`}e6K&wO!HG_i+|1h`@Yy819JZanEmGf z|HU`^UX#D)oqey#H-8KNtFQKJ>;3D)>^mD4q5t`#OD|L(r_2X!g4x5+@JtwYk-7`2EYmi3~@SJFVc-2 zpyLJxn6rO3xwE9^0H`y-1`Gv&oB&`i2t2*b*#&kuGZ?i?|D9d!~4AN^L&PT3-y!fhPNNxXnN3?lf5=rFn2MBN1Hp}ah_&lTm;Y3kR!P< zYFP<#{Esh-0S%RY+#%QFo{oOLZ@*wsFT)vD!*WARNPkUJF7Zj%`0OGj8_pPshX}Ej z<4Fmi>^2xgvOI;vYN|$fk0o$>ITrK=Ar_Jkk!{o+ea7m0Kt@p#3t&Dz&AZX0IJcOy zxdB&gTG}WrZe9boJl*zXeRjVq*3{jp#leskNdOVu7t+~XQs3Mh5Yg_bjrd!hwUxOQ zO|c>jDP5XH!_OEUKYzmw>@nc@rjZ*Diacojp{QNHRi)D5+m$NwdP>6DW&L34sX%zu zKT(lM8=2^@_^N-70{ivq)9e*6Sp$a^(ELOQ}| zD?U*JrpQ-2px&(&57|t>`ZsIwCs9D&g&SBt+L9bZ=LR-LQ6% zktYh*tEt!72J~CVwIzV%#C!t@#Yz;)jf#wyEG;ByDc1d?a1r<7TgN8W`m&;T74h zOJ0T7Nk+edyk)S#n!654ooBf7Ag@%iZY#@?ao6b6cIzOhDP|YbU8x!&UMV*h18du|u^T~}L2GN+>zsRVROL3(`6c<{}#>T)}dI_zgi6H^cpIkj}Gpkf14 zCB(h8x;pSI_9=v6JJj(38z?}i$W9wB)RDOXn&F&XiZ6#Oa0wQj8q9-oDmX4_I3z@K09MmRC=_GS!v!wTSWf17^W)_gQ>}%+TbK z11yWzd!(2D-9sp8(p>gR_ynm z8eKn1H&fkYW;xN}GFKFPBp~?=KDI5ijuB7ka0EokQqyxAIVwOr?WsCmTJ;0Our6E0 zy3Di}G4*#8KikoYP~R{~O;~^@)*lFeAj7jF00vkVz!tf%f}$EQ*DQXbMn^ zdF{k^)HUXG4QtIIgW~xF5&`oS8#s=ZK5c5cE^oY=fu!t1So&W?nlj>X`y4!+Tpd%f z=tpIRrq3T2EB9pe^xtv&Ov?NOeR2U>(*I{Ewp+)Mkz?ZE^cg5DDcs$q2((^QYL{R5 z{!P&wVp|e7xP54jIa0&n7aaa&$Q*+`8dW>qY6T*VbFyyQEL?*QS+(Xy8OGe7gGNOr z);I5)Lqt!F6VNKo3M;Oh&F9|(-*Ma`#8Kw7;s2oLVuUd2ad>NPn9-1u_=FF+;@yON z@y0V8%2m{b(ok!c^M5yGzgI{wai$v9@%D<~h)M^jGApmU1FZ;K1sNNeIV z_gcSPhmrMj(+NsA?zWOg;t~ag@E*5pv!)@%H>x&+=TB&cg_itL5%b6CZ>RTP0EOF4 z=dXHV&)GH0%|@Ht+5Hf4tn`f!^P$m)ZPgKb1$`xbyIPW%E`BYZ#7}`3{~&`-6mg*Z z+g7TJ-;oJ?`CBE=l75o52e!h?^6pa4Uba(hM8Wewx$BhGEJ+#OeX#tSNKjijw|Qr@ zT`~Atj1q?AeIxYt{x*lcU;kxZq$Qm6CTu4EzXh9?BLurPVXue3i;cB=hllgM%Fvx5 zxca2ozbnqSvr| zBOABGW~PBqX~QPSd?g6^DRN!XBNA<8)8iA?8K4X)RuY4woAtS~1qC2?UJs|Z%=tzS zj#>kydDQMzaD4^T*#Bc=UOfFBvYbB;78KIU=!6w|@BC(-EF3h~uqSr@)jbN*8L})H zNZm$n>LCljoju3<4*OXOY_mXq#Pd2P=xB_nmVF| ziTJ$~L(E!8!UdWYsNB^yj8zoYz*)3eI;yUAE=Jg;kl1Xp9)_XQ>w6y;Ci_UiJT}iQ`b>LFV3Oq(a@gw7s=l7 zr}X`Wov7e+f0X^*)n9GinhsRW^McTmQ&Y1G7gxPfH;TR40g`<$Xixq_npW^i#KmF0 z_UXe1se5?>S@k4yXl&!pYz<4TTOhDGQK;;NX=t#IvtJwodI%=fbOvTj^E2tI- b)biGk7W7%?{l5b@SLndu<0+qj_WwFy8oU>!acdfnFnZ37e7CvTn zPOg>~PGB?Lu9BrJt(3IE@w`9IhH+;tz~>SE>U?(N{h=i%+(S!@E}yY~aS0&_KE-C3<2AZ|_;z78&StT%pQ ziq+b}!-Cbz!Qzj~goK2uHf}a9);2Cy=uXZbSJ}qG)58HhuA!@^8!I2Hy@!XJw19xO zw>Q6)yQj0WFF$(T5`ehcdU#v7+X(zpU4YQd*Tde`J#Cx> z{=OdJDX~s}t9@z@PW%qmzUZH>?sfubvTs5x>}<}bSLhAk=bGC4BVzqFwW_7cGK)hYu zt$)h+Pr*95q8kv3{I!?g21C#8F18MKthNqLHm4msxL7%PTHE~HaD<{4S+CoiT7d`a zAGYt}YHfpNR?pSrA1Q~A^-pJkjvFmptZZ1_ZNQ#rrXZ(;ySrF8+X(!XT1y)%i$B?6 zwX$&G@nE&H@%V$#zqCF@hSD`H^kXL{2zulj_O70G_8$Lma8(;y3r{DHQ-ImJyE?N9 zvhvBZiU|s`x;vnovAVc=|CG_6-Csd7>i}VOw(whXUHo1H^-=GcdCL@)W{S5e=hd}5HKsm(ZR#Y9{nd)901^Q_ zxBvw}2?zif7FG~9rEAx8{xMJ6-+xjI^zxnd^;e_ zY~|*T1_0JB`hK^!ha0+#-GVMtyQ2w2mxoWwc7K#tPs^4+%Q)CS>)g1mf-cjeg-dK< z;f}T=5>E7eRxc|%bU!4j0Dw#BV(s7p093cpWqGuJvPR1y6TFMQQMX665)IR5qJ?Bw~EF(}a=Viza9Q{B*_KeN^rs@mw^ zAoSKcXZXh{>NCD;(#{b1lRzcfIIr93&02H04jj$ zpFjBkTfhSS#0&il0yqLQ=(01qg)6#^E4s}3XFZkQ?x_E4XNPY0Ymcme6}q11U&s8* z-M{tV09d1c|K+~LpU+OIgP1vl{%wT6@9$?z!8d|)f`@;3j?IlNj4g((j4g*Pk1YkT zV$)(@0Qj&)u_dvUuobXn(9fjMR8IY*@=qF1`*$w3^-6X1mA+;FCl8i?<>1!O+79P( z^e63|i)D*{r4aD2@%iaoPa~*5=5Qsn<)UY9Ef*{PE3CqTLjT7&)SuU>&-$aZas8(+ z!l3Q?+dYeY0FY`%+iw5g?m2@2;O#NmRH*)TkH-;h_p$&`q+;di?)AsLQ+ER30E7S; z8lemTGr$4xqU9_MhyyZ!BA^Cb1@wU%z#YI8Ep2-=2HgQ~AOHvfB7jFg9Pk)O2eN=% z;1%!=Cry2HJsc;2SUmj04la0Y7*rSx7%UiE7?&}GF(fhM zG1M@0Fs@_V!7#_L!*Idy#0bC$!+3;|fRT=ojggO0gi(P}kI{p9N8}kO{Jxn`HFs2`7I3^r36*C9(EoLcZJ!U)RH_UO&1>z9yb~^Se>{9F|>|X2%>{aYz91I4^NN z;(W&WhBJ+`jf;y*i_3#6fvbso2lqa%KQ0XSDQ+Qd9c~XU5_by^503%wGM*fsKAr`h z2VMkT8s1yHTD-4#(|Ei1MEETD!uaa=ckx~DL-CXGU*p%{f5k`P9}tiea1lro=o45I z_!7htJSV6m=pvXVI3T1TJ0;V|I_5fKqPkra^ukpodMQ7X}U zq86eFqCH|t;!DIT#3sa^#Bky~;yU6V#2X|eB-|v5BzH+XNZ=&-B#k7aB)g zq}HTR(kG;)q+dyw$q2}}$dt%T$^6KY$v%*Eku8!FkaLr(kXw)kkv}1?AnzyNqM)J> zqR^*srhrkrrf8*@rNpD;rc|S}rVOXdrEH``QejbXP^nN^QH4=Gr}|7aO^r*@{v!RQkE1>&I zw?ofJuSjo0A5C9K|BZg1ft5jx!I2@Jp^RbV0``SV7Yr_VU&y@h`NAS2HKPop6=O7G zG2QWDnQ567neQ_vG1oB9u~4zdvpBFMvDC86 zv(m6Cu{yD)vNo}A*vWK!4vX5{Oa!7L6awKsyaIA8&aO!df zaK7Oj$NehEK*(=C#bMERU>>>~mS99J`!_T(;b}JgdC9{4@D+1vUi>g&c)RMGi%4 z#g~dGrHe}UmEI~XD+?;SD}PkpQIS>&RH;+NQq@q6R_#=yRJ*B`t~RR9u5PFPMtxO7 zOv7KJP7_B{TQgp>UyDi0N-JM$^{T|xz^hH##M*}1>DrSzmvr29Ds?e+uj(f14(oC0 zx#*SY1NvI}iTWegc&>r3RTc8pYw5{$-g3)~L8-G1l79fv#Rck%Aty8H6(ma&@gW8-NPF_Q?B@Ar7_ z`P^$Yym=(r8#$W< z8bK?%M7zAsCQ*ka7=dba2?=$?N&RbHYpB>xtK{_bu-a zJ`_GKJ{`W7e4~6(e(HWN{IUJ5{2Kz;0zv{N0+j-@gD`?DgBqY5&~WHJ7SI%)H<+2ht^ z(d4WY!W7Sx@l>7E@-)u0xU|D``}A*5l%Eu4fHI;ocAi>4{hFzmS&+q)^(brqnZvVz zY>n*F9PXUtT-;o*+?nUMo+DmJzQ})h;pL;3M|m!JJSUFW@W4E~G7d^d5Nc`F_60yy$zec5%Z8$qxl3TqPMFsXj)RVwC!pu9n%C zjhEjk@2R+2(NHN<`LT+>DzBQY`pGAnPq8(GHQ_ZUwSKi*b#8Tw^>+2h2D65t#@mg3 zO$JS!pS3@?G^;l^B9sudEpjc@tPGBALuvfA0MzDnEm1OV{OoD@L(u-7-u+ognT4< z6f~MMc5$q5Tzve~gz7}cq~YWc(h9jS1(`aW4xb^JNk*}t@@Iu-tLN0`y627Orx)B7 z4i+PpD3&sod6!F86jwS{Z?8_Txv!n9!!{T;@-{^`8@8@(jcz+{AM8Z$GVH$EliWk> z8||YGybtjXQ;#klRUT^}51%-noVZ!ITl@?Ku+Se&TXf#Go`;V2@1S#sZU7*x`y;3L z^TI+0ADBPuk^x-k=l~4l1Iri^7*QBAn8uh$tcTcYI83-=cnD?HRjM|_arezjhR&%yQ_Ii$0E*5TG9xvX^i!GPduF&x*@H+{l2qJ_|L}Wz$ z#VW)%B)O!nO9#k2lWmY2lRs3XQxaFcsp6&jM6F8wtHz|}s@Cq+BOO5JME6AR683M^=BoB=qyYOFakn>QeYE95hDd1oB3lAW0hh173>Pxbh?XSe~)$lI}(hI2wJBcKV z)`?9?5K8h(U6rqWv z*J1j8kK-q&H_lI7VqAmVz+ihc8g6?SdK!3L^S+ckBKk!zNJd`(>Is`Xl zFLXH!6+ZD`IO1Dm=fl>hrs&E?#juw#sqm;+uQ*7&V}ecMy(GiO8p%>A7gK4|Fw+*% zKCn6?`)Nex{Vbhl0@-vqgt^Ci}63; zmtdFdew;4tDQhVIQ1P-dqbjBP@u$Z%skK>kuj&gMJ~bkmzI~o>YT2a z$w57u1|iJztOBfNa`q*=+mlJm1~gPduFYseeoW51>Hj zTcUt2Is;1pKB2w9MGR+*GIVqvj)j9&i0y%M8`lo+75)LCE>SFT2Pq~QC%HU@I;94c zBDDz31)3w;3A!5kBnI0H;*5lhFedESDg6d_{sUF1hPI}#7UNZ%t4rFwI;Fag_3ZVD^xt1IG9WOh zyACx}zd?Ru^yZseK1S-d8E!A$`E(a%Y-GY}GJCJcG{8*5oYs8CqSP|nO5d8^ddw!z z*2PZR9^d|l!<+m5j;c;1PQA`)E~c(rt}AYzz;Jgfh?ob4M~i2Sm##OVce783ue|S( zU!8wsfMuXc5D%0Lx)nSaQWcsQW)*(v0oH@H2vp?c!||x`=diFibf)y9Cqo&fPZKi1S=XM4WYcG#=UCue2!8KZ^r-mxhvt&yQtC3Xa)S!nO7E(O>Xc9UHMO;abtet{ zjTTL*pSuxQEkdnEZIJc{9V?xc-Q{2RzGV)y4*!@`nycCpIMx3j@0Lz4TyX$MnF9dh zYXETL2>`%vq4Ugi0H7lTfNLb^dr|Y`xBy53*U=e06o^M>k0n48 z&A(HG<{d}DNAJOsg+*qA;rYcdb9xUu4~X0yq$jj#uE=y6JNUEtc} zM({l5HND7varsi&)+vu|u} z(rij&W@`SzV$n+6I?`s$PTRiazKLU>^A(pM*KRP#-33zTN$cg|{oPm1Zz!N5=uxm* z$Z}Z31KNn3hk{Xck8Z%G;bC!?($rSy>HtJ zn%?&nFMXsdQ>pN(diJTl_DB706Hl{!OLaTP7g*Q+SF^s#@7q7jhNZ{qkfk&CXRpm$ zF14e-iq?HTWk6^|Cr1TPnF0bd+H48Mnfjlh$jjgXx%h;WEVmMD`LllVSyA3EnPCgmVa zC!->ZBPSQx)OsG~k zN93WXuUL>cOd>@xM=D?XgG{w-qudwyL4^gyBV|&ROR8#W_UdsO)tW0;$+hKl>~vH0 zzFZ?T(7GOPIC4|)R)o>i9nHH1CKv9-m>!usSbVg?vA%)!KZo|W97-H%oV=Y!TvgqQ z+*u&;o>*Rf-mAWjej5R?LBi0^5T`JL@Z1Qg$c`w}=p~pR94|I4o-LsyN%?VSihUYW z`bb7rrol6u?6TbZFD|_N@+#uB+FSB>Q-uvh#UI{%tSxJnc_h))#CVY*Xxf>@6G>oJ5>yTxr|{+$B71y!U9^j>O+1a3z={v>}`%GA9}%HYY}r z_>hv4z9lmtJ0gEaVL?el*+%6{%}w1y6GY2LJ4u&GZ^IyU0dxVymgbOrU2(D7)fA=!=Bw+wG%-YGUVy@zEQYPN6T zVmV=LY%^>JabUSW?d0e@?rPvx<9-E_?n&qs=7Zr2^S2Fr0j&$E348t^Fw!83Cwd=N z3x5=6k)V`xDVa7ENSlAs_4Iw#MV%0&m6!vIj{^vCxVKj#{90LVD~ zjtFR=ApPwf>B$hF0$^ido&Lkd!p6bI#=#}T!$n`j1O#}5WF%x{q$H%Ig!YFc`R3l}bsQ!%lC7?|lUTwplu1Opof2NwsI7!Qw_fr6BR;lF&H)BzOu82;Fp zSQzX8CIto-1;$Aez=Gx$2jl1U7m_hB(RAYC;S&%Np(}hO2QV?PurRT)aL~k~p9Z3z z1K1Qelx#vuxKsufc(bC%XwYTrv_x^z&gAvQ-FpaWIYlS9)=pXb$=SchSm=L?v%fO-H@*e|Vsxy6Nr6QHC;$g3H>&!e zAKyBOR=jgQTyQ`oXg~6LvMhQPAe@WcipocbZs2>6JTA8&r+|LNvG-TbGU|8(=8ZvNBFf4cckH~$0ObbW08VDW0s!0g_@J>yZ6 z64IhOvU=qaS{TGO7T*Ph;9K3d#LG?qHUU!TfZ7SLnLJr)59CDiVqHKTtA7zVuJ6y< z7alBi{PoYDRsL`MU@;n>0C6di3XAL~z`i!vSS;q<3DBb5n6*s-J>n{Vmk#jeL<7wg zCqVoMwCdh_qK;vu1tLhBl$h8DFTd3=?RF~Qx91KHkKTJTyE^u0TJzBrXf;QBz2OG& z)^rSSxSnUNn}ToosaQJ@Ua9F^+ffA^S0rSz-wTk8*2o>P0req^H__4i)O z2W+FNztuWs5jmI&t@TGLd|2j@r|u>#+J5mA+q+4FY7bvJ;%FVV(c*e_{!nC9xL0Kt zJBaGObbjAEGo6a}fr@wcRQKL-5McWc;b@2ABHOkKnJbUNJ)Vq3j?%4m9P?)_?cd4= z`$AtAWU9;?=)RZbl3huhil8CBQ}jW`_p__`Q!TF5&Ak&K`DmZMVV=T$tgvm2&ugi_ zBda-!Nv!Ir`=~De%AM8e=Iqsmm8Rr<+aU+%rRnuNpOGKA8^mwICGlLbI11bYa1K<) z=5~T`Yt~MHhaaD$vP^7_vVLQSkM=L_@G*80#gQvKSqCuV@`zSUE7q{KePR*JvgK>C z(z{=giS=cs^x9nSH?S=&c&S`B=wwv0AfTm#MzOZr$B0rQ{z&EzlTog3MOSciC$zGo z>y$U%#$0B60O7#q=$N=#c1ddK`eg)yt;)h4)xT#39QSVc zx`l?gh6^q_*6|#OR);M!ix{@AWFpgnDc5?c3WH zLKlKc*SGr62uui#=6#0wf5C^?+4Wf26oj_4M<>7>-)E=q|8;j318p1|8nZhAq6+d~ z`pVQI8&ItqBC((9JB1K^-MC+9nxPHVCqVw2&kDODC%~fp3Gl%81TZv;hOVMp4Rqt# zse!Xr3l-+?ujwBXp8y9J6edieecvXt4jE2>ZBdLLJtlUCm%H}Us|`U|4+!MdcG@haQRxq#xW&H&_UbC!K11bVV<`54gQ`CJC0#Opz2J1 z(ER-bnBtn~I>4_zP8h!R1)w%i1FTHYm43WH4@qx*=H(< zU-psECXtgYNrZPLQ*+$#>T;b)PPs1QWK8J?@Fg;`1uxp~JI)ReU$5k~dgn{yab!d^W*b5J<_kL`4^pxb1Lq6BgFT) zN` z_E5(A*<9tf<~NQn@7y<7DU;ZEQ6(1VagUzhpGwxPGdnI_^ev)V!r37RzG{haw>WbKbwYL@OoV6aCg3KkUP&NAK%#N<@aeWiY)a(J+kj9S5g!! zMbYtn`~zwOMV$W+e&`3s4#TUZP5=wK6X2_H^pCe^1N?3bHR@})VqJ$Z>1Ib^g$kQC zAGIbaMANu z*a-|XzGY6gZwMh7R#p^g3Yc(i{3e= zLn9YsMvDR+EGT3+9N&aLunwRk7l{*Al(j2*UAvlqH~|!oG>#9+)^d+2Z=V3OEU!+0 zv5;fYZ1R{lJ;ryb?FM2y`SIg=Icovj<0tDgh_M89&SD>3@ebAM<6X1e2ZF0{c zblfkn#pRKI?Sh$txZ5c1nq9=Ab-$;sag#i#mtX8jkJ}ZiZ||Ng&KAAB&+xc3MMgqg zSlBP~W1~;(-EL1;>fM|bgGajGb3fg7_SiG}oSgjr3K28u(TB)-FL(8?U>MNnDpgqxF{WUkIA z4RHFl>p!ET2WfeXIAm$;U$K78XMC@A9GW0Y+jYB??!xv9$F~DR9qHKVL64bs9*Xu} zNxb^Qwuzrou*zt9Zmv_Yr+;#FlJ8?mc(uyJ8~l#QiLxV_+tR3 z&AgI<5?fOECoq(?{M6^XvF=#*>82=gkKZE~28~pw~ znWkImPaki6D{iA~)`+&T!3cXDVbMRvau@iX^S-}nO*%rGL@5at%8E^~_w@w$yP<={ zXW#1oGj9S6@EX7JjpY*E^b7ASf6w|Am&#h09OcAEZr|MZNG0#miKFO~A&Xcy9>n!L{3& z0B1kf#8~twXzf-JcVaH0P;BvfsvVs?L*F~AvN%<)A6Gso<}=d&pvN=U^l0|x_rJR_ zMz#w%(7v|&!J^=fPNmDocdrG~7;aXUIkV_L_(4E#GhEEAu6{G}nmtzc>rYi9qWzZh z^p;UJm_Kq;tF)Ovb7jylGWvQB5|O-qS9RrP09O6n8dXyeNB3qHv%}8ii3R^uek%t) zFZ}1dx%MykcUw0KiRmb;4|{Sc>b`hnVbAnoreo*h#;c z9en$?^0e##hnkhN_PQH_cz|Q(8EJoA&82U$n#UX^YqW`W&+p%*eN`FI^W#35FLBj7 z=jEH@>SVVYPR`T)_E*GTmo66F z9GB(u8)RuRW1RC#&U&rBzgWJ!1k9Ha&;P`M$faCWNVR^+n$g;Z=Q3=WCURBJ znNIKfq3;VHyT z*N9POe?D(C;A~dE=fBvkY41WqdgxY`elq?RXy|HT<#e$2yB&1~Do6QmhC6;nJ)#)( z_GS#SY?B->ndDJ7qDhR}4{*M1he2(ey=MR`iZ0oUjC9z}7&T5XJF(IJHhJt`u_svs zhkR&!m&gX@n>sk>G9F>wUTwVXP#Q|c+4>~W4#Sl-+oR*Fi+vpV-WU5_X%=$R!|SWb z6+98pBK{Sz%Z-z4cn=ESy(lyKQ0WUT5&WJ2d>}Z7i|wj*D`fVQ5}r`of#e|DtfGWg7Zn}-)Q58u~|7h}GzW6|p|lRK2! zbtMbm6bMOAPMi2qG7?aaQ~R(0=fk^}@Y$U!JtIPlp?nRB*=FJ9(L#0apbz}yWAjYy zdlqUazgh0a61#}SxZk^E{^3hec=3}-*$PXq&X&f~k=Awou_UY^`@*y!%3Tf9uZIp3 zKR$jFKV~gGK>H{<+GEnH(mupQ2p||RlDsBnIAzV8!7rJrDLJqajt|=?DT4GYa z_~_ArqxQ!>`K}q?OpT|MtslH_7hRg&MBt%iZ)VIwqy!yAP5Q=iTOcmCx!qJ$T|7r8!jNSv4G8P#?r9ci_(lAA(Yp>~d-_GL^E`KX7h zRfqi@FFc6LUS6_1orScZh$nF-GI>R@wm4k$y6<(KC$hW|YH>8Yq~kZs_l%i5efiTS zbX9Kb>P`l7y?gQT8&|*B!Y4U9ST+@j>HOqZ6Hvg5aABk}KKjhuy5^yPvvu@|I_qu-8ipt`c?Sm=cut-Gq$JwcdndlGSk>0NFE0(9 z9d0hZJMzWpGpA7Vo!bq!ZK%gL-z`W~`lQa2H)7W~h1_C*y|yB45a)b7ktY6uU-0eK z2y+P*p;g_H%&eT<4-KQ2d&IP4pK9Ezsf@lyh?c;1+vNVFCq-pb&oEu|ghs-PjHitj z^=}0t+dUQPYZ-jJ>jq8pCPqw0@A=HGj@Xyoz2WxgN&Am0I`SR{1(>251jlb_h^fb~ z;Z=Mif!r-x9etGVDBX7g*!Fr1-Emo-8R(i;xj^SN_^hZQUlK?hFiHpz`YPIP#;5`r z*C(70qV7&qPGGW>`6BE{;Td2PUU#+S4XW*78QaTyb$gFC%3S)9G%?@vS05p^rJYOq zQ_4(1eHLY9p(31#n%}=(%HeIbJe2|D@`|hz3zLY3YvPB=ZltsuDeX65`KGA~3_ra>cSH4QLmx%^| zdc|Z|qTcH}KPQn)UkoL0*8rz`w8I zg7oSq^@HEDCqChQ-sh?bdp*3Hs9)Rv(OBE}3Qu(JwL66c{LbHHiZiwBsG7wihe;O; z+Z;ci029ppHob>n+^C5?%Mah=nHJ(Y)1hHoB)lW@^ua2iT8Ctfs`92poW%Rd?c=p< zfP8&Uwb8v@Ux|onEw?N}kNTXE`5@x&ISJeNZ3zCHLhCEf%M){TQ_9(flQ}x1Bqd{2 zdrG`kS028rq4UwWxtayDS>5Wu+}^pG-f{FU4!^045-7XAm+C5ZSI60^+GQ_Tt}=R+ zB~+fV{Hv@nUlTc#_<#cm&Q=LCadnSnCbHw<^Tc*Agty|UViF!qkZrgmavE>!74Vh? z(VU%Z@8 zd3pW%JsI7EHnCVNLIYH4awoFNjh@w+zO{b$vz6!T0QR*b_!DQb>81WiF?#2vaab$o zSFw`lSJA?EqF4bb&Tc$MHJ{kf0D)XHpPWe+l3o34t0zE2L4X|CX7aNCk+iW`ZB>G% zs(*NJV2&E>9^O-L+zmRE%hy9t*|(3nP{XXINiCjL=h{Q|(hn_45;|`=(@_eW-`Onn zb2*}c?exp(yCK=Sllr)h7d#)bxcbNrQTlQ9S!-hjQRc8TR9orAPMXD%egMC{bI-y1 z`~IyL`MaiCOP?z~ByY1^YQ~dfsSQzUNmLNtYt68WBg?&vhhXMH2VNrerkra$KZ1si z9=#a3&tkVBTdU9-_54Q_o{JY!QnE|M6mQ%Wf8l$PPpXfS-lP046UJ4la5B7mvtaog zufR+PRC#5RiC#=Cr8+%%=UtTtco%x>D-(PaCOM_Wv%thD@;H5qFMHnxQ20MTDqYLL z8qt;hUJcqexKG&KMr~iOC36Yl!^EkHBjz?}Hl-xQ^!Hd~ znN9%L+I`MzcpCqm@40T=9Xotb5_{l$I?*Nn{hFMd)8>57p+l}m*w?W8&}~oKQybB& zi5RYBro3?Y8X(cj*0;iZ$hDdnzzUow3n7bkLrrY13(y0^5v< z)j5C`L-h?(JZxIIx_MuH8_Bd0Y?FOC6c>(yZ8IY_k5}7*LJaE00HcVgl0iW-e)}G-GAy1x?J&%c*Ne zUS5=s#y>M?>N%sex=ja0@xC-UcT8X6iVpX+%=n_YEZ1%Qxp`p|DKqn&oJ^w#&7{W5 zzVK^tk+939fyWadzgUCoac60}G%Lkfi9>Ut>O;p%292a4ck+z2%*KJ^tWgHzNFTOj zeePT9-<~kycVc-rD}WM8of00|qjZKsk@E)Q2Nf1^QMaEvqySrr6x>wgtGJxV(sAq2AEKkaVc53X zN||coD%3_vzV^VYt9FwU4P=DOqD4z;Lp-~&?x+y zs!qAXp#kZwD<{y~+-olneo$1ujHlqSxzH>Pdt0z3>p0csEp%O(SrD`j*&)+6_$hCT z&1)+B5Ky(N`YgK6>Ma2{E^_uC42I}xX3Yu%BSh$#7jiM&zX z%NoxwW?WkJDcLxR+t-?v>=TC&A%Jns;s!A;X!+hgt05O5%`?)0_`} zsl;w_zs%X&|4JF9&U%X?i=VnBHGui7;T8QgJeud{aAAFxuzQV&V+3L7R3nw#r~c{1F&H|c}+9Ltu^!)48-Hc`vWnYn$|EP#07|KhJx9T{w>~n-;Nf!St}A^1%2GR#v5-Cz9zW zGPKmxWDAMoFGk$j0A;h0(Hl7(95qO8G3UHEOZm-icP$UXi%*7iIc*t&)JV`Km$HP; z6EOCttX}2)W-I?=;P~Jl^&HkH(2`wDp0R#Zlr^qk0`sIkziwR_OI65J^bO&0fWsEZ z*fJM_lgUZ@!QMn(siOK8s7$|ng+IG|Y+8%x&EoYhC84B1D-Y9y+pko$+cNuc!LrZDGqHS@)0Ph&B542hz1jB%5^aY*ClkR?fUY>p^ z`VIoVP*?w=vV^?E&Z48W%j$M($(M_vB)+VLxBE z7Q4d>bBdK3CxuHH&fLLr?&-@#xw0?{YRV1-KxSwvLe?a3VQk@pk96Ixp90nGt^odz z1aDCX)N96#R>F(nx}O-Da|ttA>SZfP8AI;Mi}ne~vj^Zv*ChIKha7#(R(qvY`lEpJ zwsrW`ZWv9o(tueUhKn4Pml1!)jh8tiiSvH1rCXxc-g}r67H5RYsYzD|L`6vTfkAu)nYJY`Ny@%a8c=i{&1p5#{pP(KpFo%g)$vg(4M zBTk%~effqZgYY*MeAK`fn1+Dl0wZZT8cy~>HIc+oqek%oY3knz2~;|jS@h(07iI%V zFHN1|{iWve!?$cn%ho2;mv^G!$fKe?7L~~0vt8i)G(Ayo-*h43T*9{mDu)`qAWtT= z_A1>{D646|cCbF)W^=0|L*l35QF5d--Mm^=x09m*+h&fG49}QI6Mtxlf|*K$ zD?}9h&}Of%^eP41uvFyGYA!4@;wgFr7BxV`ilV(!y1B7Hu6B^6FuTc3rt?X4n$eXT zn2|+Tz3|+*&Y-#apVQQd|-;4|${tA<8L6PP-1n{nS< zA7!`DunOy1e06T7ofb%h|j8gwfu?($u!X1W8^($IeI`ls|G_722 zsnN-G#KF!+v61Dm1bA-BM-p7FcB>9$FuuPGWSgwY#3M$T{2-Z;q(7$>MdE=b_YHW_ z`-NE7?Z|~$@CBLbFZ2-x4{l*+A9KvXrQtOvz=$OOKj80f+s>_S-KnPPNSHtEc%(pmdN_M zPqk^DlN&PXF*4OwVfl<&?jduACyO3rM-TTLVVj)lo)_Z@J=_%hU7QKLbliOuNXi~+ zl&+Q1`Z%BrA8l-mtIRTt611@hkU7X5g=X-V3moxF) zB@Y@4^&s8j=-I0&>DpPfsm;_5T866#tWacum4!mX=w(lUcBRewPCV;#mW)7PPvLY3O73ev|KLR1{3n;1Pc}X<1b{if87UefNoFwRbi>@ zIFuLjKDzB`dtq6%i7El=fft#1;xC9V@+L7U+^l>b7l&V;Fsf=)RWg@bttX)zy5eyHS z!F`2Haz|ZLfgcEbYrf%M3KJ?~y&7mJ>pk!9=PqK1`vjIln%0=*w7q|<(jV+S(-AjqhVCp(sPfDE6FNk%xy~!q0*%jSN(aqEss%ipt+Q$b(0` zAdz5DWfF;$|FN`n7+FZ6xq%mUDNLY~Q(*+vD|h5aD%BQzmD38=fRvm!f@dD1*5!Y| zFW#=Mt%BAFOI#dUFFerb+xL+5;8yGfCn@zxLY6Ye%v$``s0D<4-SZn^lgi-r0%+Ri z5<==3rf;foi;i9`+f*^kO=g)nuYA^bE=?5%PBpP(y1LdoHhioxB&4@N+Wk%m+asdfxqyXTUmy3ET!7`h9}p(=C`hI%F9angCV?|siMO+Rb>?au zxp>g^B44Q22@qiIVpuk9wjG6NmT!oY_b6yFR-z1hlxy1Sb2jkX_-lUhsVFiK@dlz6-0dz>r^Oo&7a@Wn^G&7w53*VgY%g*< zuiEmM)OwjMp8%h_3>S9vnMkf)a1nkeZATjTVQ68G%#=NTh79*6u33gAw5sc+|NbTj z@)$U)$MdPx33-X+4SVT^8j`E2joX^!HMLxyHjHFw3P(R)d)^8A)tC%_P<*~jm$Ku!)2u!% z6Lb?jIqqlaMZ&{d&h!>dms(wMW1<<%Cb?&%(6R4@%;?Mh1$E<`@X=fLZ1Tn#IU5!F z7RNnXa$PE|$cvm`YKWT_QkL6~#&#l0t4QiiC9SC~{E>HCuo)JTD{kp^!ZmCxq)|QSvOlP6OZJ zy!WSEXQHyF*3z(k5l_>tE)nB~tJ!V*nsJ$pvKyI4T}oZD0OtpZG$&%cs^^F+xx4xY zDt~}VOz@1+GniU%y}$G*O%Qw$H7&K-1vL!|`DXj8)5XxYR!tNtce4bq^Wdbw5{JAi zmJWFmKcB^26tk7v`0K!?7D_6(p3mU{@i^q@#~H_{#Z>*aTREUiN)6?n*@&J;{4*mH zo3Cp<31Eoo7Z^!7s9k~d?H~0bRMgJH6?UwkkMJwu!%3B+(Vu8RX1v1AIpb6lY$ZsE z_2gB@i`NqTU3TPZ!`FTCf2E^IbAvGw$8ecjF)qU$fGm_zrdsB*8-Iz#Ce}6un`YM@LdK!ECS7b1%)Myxm~5 zA(s;2RPU@%b)d}!@L6P2+Ua1~CN{9FW zr1-Iykfqz1|Bde-%P+HpnNqyhwV)+2U6!*EpC<^MWKv#pVWbFQyOU?mWk9TCL+^?I zOc1kbuxZUZ+UbztnTexx2ILF20I@brWkkXquE*?AbYP<71XYtFz>YJR;2AN)F}aUC zN-In^MXy4zQT9Vr%8e@Hd}f1EL#~#T&P2apdYQO7Ue;it7f4>dlCH?gt&b((yMxBF zI}~acg7Yun-@X*m4G01Se)_ODojL3f?16k{0v@t_A$^uRRiX8>i`&mYzrevgK zN4RHm(5)SYqoAjCV&zCMey5ER40T1a867-6%WB!bVKCgl9MF+1! zo```o1SF&y_c!-6Dvq=CrYLAWckpI(Jc=}#t~=)Uk5$=YCcBz6tSpjt%}T1BR4C&F znB`fQPttP>%LrH)V`-8@>@E5+@M6{uvQxEIS_7<|Cg65d?E%mGSzpPCGH)Ti5>%%e zyEw{+zD{mkXa_xYt_vBWHLeNHd{}KaQf0SKmcKakq4YcCX?YAB0s}9^$94p&5raoa zCCFhjH|RUv8)0?|`vixvFI0B~-!)(f6LU<_F+J>J*p{ne*6@S68 z@59G~eYA-J zJtQlGGuZP=8=&}w(oE4>6ahZ>P=n+-q3W& z+q8)Av~!c11l00&LEw?S*~kjxN2vx_C&?IDLIJIs;mvdl@lde-F(ot#(&;Pt`^ z#N6icJ*fs#@J3+(lzfK;RWz%dIqt&7(D6zrV>*()6S_&Y$8t4xiGpBiL>M5q_Tjm-b$06k?e7dTowWFr-<<%{Y*T~5phdRh3! zZ%xw?N0-<#iz=G^)<1nXBJ1-`56x_Ohtr{82TMy_CQcaNmO}A#@5qsf77wcy(%LFT zO6}FnzFStP4D@4`Y)KfN8Rf{B#*^yw*=jwuo3~Gzm_RW=O=~aiu=LLjV~3Q7+X+8w zh9rZmq|jbKe=6{jWC1(=&`UigG-@rL45Kr;V~r3P5e*2B*SD*4WaCf+eJ``|84xi) zLk*)6=I2y&ABWP(A+ir+@v>8Y2kuZ}shAXEh1?UJIf9S>#lQ#B`H0p3yBo;m1u+?%VGJDGM`NQcMlqA$Ni+4w%cWyWZk9Iu+ ziSOGfgecJ1U@=f){qJfI_zmnTju3*6;c0QliML3rSeI%0jTHJ5;5lp84HuE+Ka`gcdUfp_uY+Ai zartvvoJD7loAhP>*ySwKNVqU(@HCm!-cSwn;X&5MfCu(3HZXn;_2=8f$7>A`uDVVz zD-$I4abTx{ex5sZsTDuJh3bs8i8P8IZw)f+$I`OucjM(GMMhf~L+5QU40Qr1Da3E) zK*B*tlPZ_&LDt_OoD>&0!=*cf-~nlX0h z4^HzX`h4`X@?5e@)l_78Xd?=DjSLO7yM+@jz$ z6^blkK+3)M2br(S48FR30=!Ta`7R;ZWoq=(=S*mWn}4JC)w7Do#kEA?!1@FeW`yk2 zJ~JwN=53!BN_-83;+5)zAPV$16bzL(-Osa?xMAgrkt3nsMRzd!HOU}5l-ufM;XtxLCp}r(Lk$j!^m-9~m z4pdm}(#{E>8eO}ccEzs3LG;JAF8_8iE@ea=A%V#<-u*&=`LW6`U(f;`e*c@6n;L%m z=*UN;UER0!D0Ol1O18r?Puzr6jQX9}Zo+97d43=1!CsZB6eHIUj$YTsezcVuk>(8E zt1;;%M+>^hlkvrXNPOP~VCfA#fx?9RSMlNp$1OGE`8-FSnZ8{w42pLjOngyk>h*E& zy=M2#(wF0sv+ZqD%{pQAL~07zhxk{bKc{4bgc*ejt!>At!tl1$b^u~%!H4ZbUaUNM z`--T$s;x0m7@A!dGbIB3LDudH(dHk(DJs2^DodFsfLVthgg~9{T9{1MNKySzC!yEj z0ZX+n=thG$eMcu4p6xrgvp6{`M)xr>5hk?BqBy(|s)nYngGSk$xau52Q; z_`Wh47Gtq0!=AEmA>Nn>5s?h5SEhdc{wy5_=9mlt6I}0w^MuVOG`rd$hgRMD+elbn zy)BYI@}*nkklb-?>gEiCL9({FU63_GMtvpeNThpzOV*9BgTn&Wfuf(M%gh`_Y{(Cs z=F8Pz*Jo5E-N@RYm9Ag^8f*li0VPtvkM|$_kuUpGDnur`-03l&&caDD>@O2mkM%wZa0nE{S;g1BKhU& z88V_(ZG1#zj*bu1gUlLFDfM8*JS!QHse>vt+x?{9H8z{eq%zlP>9){ACzck+?)0rSE^*@3N&2<>&@>Pd- z9F+~Q+k%9ZxC7W{2Kos9*BRsjTEu%H;0f)lHuC-W|QwSO2Jb_g*r!}xR?d%_0 z^`_dW-{A{+x|axAVyrRT>{40iTdTV)ct(R47avY;Xt$@4Pt++~Jf1%RO2A{iul7qq zepMl_L0Nm+$a`eL*mB`?_kJJ}p>h_nn3_w6z1W;BFv5$SUmJbSOD4*QbrG>^lte?p%=6Li)fZtjr5;)8|cyru? zfa>MWe?6nbbJ#fxSptsp_-Q-G$*2_zm4&B`)Tm7@NsW7>(4nBdoS-JG5Z4Y`J7(Y2 zzU#+gng;S%;~OBH#;oER~3d#*twb5{-~DknPJ~`xk736&qv8Y;a2rN(AK1WuBra z_?E@5{hz)WVtukiO8n3*Dvo+TW337vS(e8`!+WQ^J$o*LZMzFvI3p(&Me(39OeTZf z&1*k%bXP9YunWuStQjWAKt<~bggG#yAtf2BGRyKuT?YN2=b`4SwyM*64e?niS(DrH zpURP<#vF`3T2F_jO!ay*@qz-$AblIX*bm!QZM_eUwqb|0k=a}GKC_D0*}qyHCskl} zeLN|JFlLrvrUbZqdvj{?#Tf^$`mkZ5{%I$Lq)ec`YXEa&J}RW-H;<)mA#&F^OI*12 zqHA12kSXG)=s)RB{3@Ey3|0_3r!o8Z_taUH-T}G!s9srSRAv$eiMaBlgwUmu5WR1< zg9M8N^>sV-c{gY$1oL?6C`?nFV4kcIRbAr04Z`rkY3aJpce4z0po~q;>&V#uJStVZgQ8`wu z5kUtsA9s#}OE5nD{nz!kdTXax98LfeLv;8>^T*dTgow3U@!&$Apab1vY4hYcOsku{ zFkOPK zL^S4pR{C!hxbzMV9kI%9~ zc}=YcxLIW)luo_F{)cy`qC(S;(L73((G)4w zc>|sEoB+xSXM43c)P!=$jQbX-IP%zK{7i?te(tWczC`n&;PRG=O%CkRW82R^F@OGcb zb>$y+VZAsNh{nen{*U`faF^+frHXpFX`SPjGwxd0i7|h)p3(T?X$M^*%#Zc$AjT zJ}RY8Ax&)viA@6!Lp`Bv_07D|^rqTzR_aGHq>6Gk>?)4eP6IXfTj!|tX2jG=`PzAq zb8vJiBc`Q~=+gmm;XX*&z;BCa{UM`bs(GZMNFf=oP*PpT;ZTtU1AI2eD2y0V19yC; zb`V11jEutbpGis({Y}ZVM zENm?^Xl*fQZOSg~H#V*|x_jM?8yp;ZuUBieWl zEfi;~y;(-g%qk_3Z04bKWw6wqGS*gB&=hDRF{|1?GcPfnJCt(GR&*}|#R^$3^@nYp zW)O|10-5|e0xrdm5Q4EH=@G}FwL2}Fua=ga8v@XZt+FDNY$W!U6EEzwAGgA^awX`r zRLMYHLZ`zgKsHOqe&4lvqFh^1rz#XH%cRqeeBOpEX%ZS6;1t@@wdMyFQ9_*N7K(_D zRCJ(usoDie9N%DE0^kx)MKUFrq@1Ob~->t>_N?fq|{oaTMH;`^{{mBmA6FpPK4Egyau_-%7ma#?H1`Rl0i`=%$?#vfqOV}Yiu7>&vga^s_K zk3Yx^XpY&~h$Fj+ItAUl4~nxQl;uN*j>8TkXRr)tBYxf=o|o=LC$cPi*SJ8up1fHo z9Arh0PIrxt_n04FxI6T&5hsG}BNf1l%#`e6@$@IFl#-l0M;glbcPG)7on#V<=e~!O zN0mWZ7f+>eo{XKAoR8aGZqe6%%f{xFO94%t0G|F?=#Jmu{_a4XEgmdcaEk`^glYjO zR#ZmD5fU8-W&D%~S@F=jCM7fuA^~0|LMzzz;HN554PTt!C9UJbCV`KJ9mf>8)RY|z z9W(ng=f!9K?nPyY(stO&K9&)zH`28&!FZ9xLc^PbwYs?>FpMSVp79}K?MNgco*J_J zcz*w=2f;u@OkOE&rQTlSj&aQ01(}D6)Xk}$=Sr@Cy3V(3@$J${t%gRrR#q%Rd6P?4 z6^Icty)gJpeOWk4h^-Uy7=$`~%ZSdU?$c*Kn5w`PbsaUI!uqD}pS5zD#-g}x-`DH9 zmi&E$!mE*TqL==f&<4Lu>~i6hq~zywU7bx6`QnV|biWiV$4`>}B0Og@tl*>4IB58gr_3gpw$@2x7#vaT%^B`Hy_bMOE^TO~K8PycO7_ z(;Ll!T`s7^f%7o;52eBVeZ(c3h*!mI_9`u%9Ho5!xq%}_q!2|MH=Qq})@!9-+T4Na9 zi4!n7mAa&)4iM<1M=I}h;y%~+uq)ZQ0GOj!h^?lWivEJRbbRg4sl79hjF7IjAIl5{@?44bWbxT9G8=84G23o6J?GK9yx|A|~wq8sB-BO;*GWU`P?iFV~lhWFThj7;o6fO@WB`JTuz#U~E4zO4l*WU`9CY*{Euu$4hE`k|}s zURaTN(czo0d#xX}WT7u)M4y$$2IV<*;_VM9)!_l_zWaW}F1Hxg6(-CbnC((#pw?!d z&CvcI$gQ~*#a>6NR|z8|UoqEXdRp9gz{6f6$32T+1P7J~qqWoY3zQr;xL^JRSYqkz zwybfM@5NUkmHiNmzZDCzJL*J~alkrit@pfqnM#qa2aTGcVhEgByk@-@gUb3nquJq?R5w>LQ8~pV!?1JdU|UG>oM+Lys>-b90&O@ zcj&<8F|#zKjx$bGk{~fpo00*Xj$Vpo(VL~QW%B8Rj)TM}zY!<(t~bEEI?O)~EJFJF zNZw*T(2rCSTPmn^eQ{mJxp{0G9D9gXDbx0=j6uAz0dod$8IJFsx=_mrVAa3tGpl4i z6WIEtSls>VMrNYqLKbv8c5YVaf^ly3o^Q|z;E)9?JQxl{&JDpa@&ta!-^6J&J{c2v#e=lE%NG88>v+46yy$TFwJLTx;z6^w=_N5Y^+j*TV9v(15KT$hKe}E`QfMCSJEXA&g4q+<= z!xTq-%~A@Beo!(d0&elpkv4i2RIOwjL4-_Uc$8d?-2E*}c5KFp<`f)*_t%6hQAhsaOO{9u%F@a@vd@a(ER z(AeChkKyYX4XCb#mUJ~69WBeRZ7v~z-ju~G{w|KvVdoRT4jm036xPP>N1sdosUJW1 z2Uv|8;;`crkeU;LSL~p*d7K$Wem+oNm=y<9$-;-gWk(rkXAMG+82AcJEs`fhwnfPo zcMo5o#vRb!8B^I2;x)vV&KHL`N#y zsE|-ck1=`y*3l`DPUGuZ{Zzj!(=a#&@y7$UP?DFJUi^Yei{;DEfn{i9W|CA1nd|#H zVWbP;#yZR@{upt}LumcEW-NLR_VmsXXq(L-5l_Fmiu>nXGM@tO?Z5l*?n4Ck`U@2p^q)tR)?Puc35o{ zpEbUPmM(?xZ_@pl48&-AcxMR+j4g?*Jw5^aW2*yYz;$B3`-aHHCsTvw2McA`P){Ma z{sD7VBSP8c9LeMlm~@p7@bxSqxu#{}+_{6scZQ+poMCuXP}k)N5@(8WI4mmF(`ask z%y6L_T*sDNYb~f$Qm6O18DB1isq28LYjxvmqPh0SxVmPI(|d%@QGJ z-HXPyhr`tM^}sqeZVMQC!gPe^y`PoZQ|~{|P1^P@5tG+9aCZ~#uZ3jo$dFA;t^ETi zNS@2X^Z`%%hnA%>M(B@bg|)6j@4=jNL3iqUd+Rc-S*ybW!db=yyV_8(KT#T+M3eNJ z3DZo8hiYGoz(^A;za+B023LoMolXj>?c4e(cJV_l;wQid7!;YcyYlfeN$ZdM5{t9F zEia}Hg2#0l83c~|ne;8XA?q>4zfYR@U-Aa&*}}qgpV4d~u@siQSQ=ZAl!d>$-qZI5 zPPDVzYYFR5TcoHI-29gnM&-I(eCWB$bl1?1ep#uhL;B6;US$5(tmHU(yIC!3N0 zB@&yt9gaGJqjr7gRGuhq9}r{li;ov7@HV48k>3eG#)OadXBARsA;obZExLZuSAJZQ zO0Ze`1o((B9Pj`g<~pA1Cq*2#Bk;{9sO)h9ed@Xno<^>&`_!L1XR7<(9{oP3yq-Y# zzG)@YOI{=Z-k@xJ)qu-@@EoD*td+!tX6F?xPE%9k?9#82gs!a4P=<703l$G^fU-7z73%0etb>RK``LBfw()_xFN)50Qg+q0$9QJ}iYv0qjn0QnJ#iw5; z+~#bfVdO|6*TT-Iek;YngT=Y7Yw*iPq5BG?vShEaK76K0TW8X_)+l`C^F0+Q{%DDd zNKjVlRNsGRwN!;dR1m|bwb;;)OpIE|qnFzwLb``V*dP2J&D z6B{=5v61ClHPt62isGlzSnV1}HvfFVjC;u3Ds0R}vnv2{ZwoRicYPFZjrSHWw78&x zzH9&G)-wUC!m={m4B0%=5nD)4icvNo}J zfn>6U^fIG`72Dr8Bk9~55G)&M6)Ymc9Q`!NYF17COPGd?^Htb>y94rDuJu{U)@Q-crpE{igF1mzH1pDgs z=@EDO@4K7;)?TPgJzepc5sr_kkx9<5jI=Qr#+cjj?6S;8YhJh&n3bx0k1nJPma?=9 zA8U}3{c6fVWE{%laWn*q$#uo6WfGQwhh>(egRGZ7a?-YxH)=Oacc5O%od7>r3iCUl zc50boWIV$>xVBRD`r8$=GR%2dsmrO&2+6c&NVfn};3veC+y+%HV>qTagT}b?7SpF< z8RoD|Jrp_zLw+vi7yP;g{~$FN3*FXOn1?WZs&tx|mh@T>$%H8kDvYocVsYMR7ME)3 z6v+(nSy)j7=hhnJajYEFc-(TPQwNM=D<2 zVjRZ7jO5<6jSUv1xxTdx%67g=^=OqA!C9%a+UlCOB0C!WJYfk0lp5Y-?=$Ok4Uis0?r4C=GWD!~8>XG#;6Zhh-om;BhdlzX zmN~b4R%#(l#|aXZVJC;V);}~Hq%y`8mbSwx$UfYZjgB#HA^uLY@#V`&#_UKE0eZB4 zQqdEMbx=*7P^H9RE?T)Uow#ELLqi-zvr-H)FVD#H&FK`P;_MQEZyXRgWtb%e_c7as z2hA=+x_EdvhH_--PeVB0EVN|~AN4GZ!L?q5FuX&udr#wWI4t^a%*$kkC3b4Xmwk>J zaYwxzTP{QO`5pBj3{T@V#G~JAQpVroM`N4Y(sw&KdT0r>Qo$5gGavRVpF+y8mVu|o z2b+W74T=7j8b|Arpy<;$_{X>=QkhvPiUZU!HmWod;YU`WkH^WN_8VBg3c@I4URo

rrZ?_TU9RPD7l*m|ug#y@W5v%`eZQ;X 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%0A%N(k=r`$kcrP7mv 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 N{{t81Rnq{F0RZMezK#F@ From 038c3ce96b719bc3573280f02db1ec17b41899e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 6 Aug 2012 22:16:31 -0700 Subject: [PATCH 10/11] Extract tarballs committed to git as plugins. --- plugins/beboxsync/beboxstats | 62 ++++++++++++++++++ plugins/beboxsync/beboxstats.expect | 25 +++++++ plugins/beboxsync/beboxsync | 50 ++++++++++++++ plugins/other/beboxsync | Bin 1188 -> 0 bytes plugins/other/tr_ratios | Bin 589 -> 0 bytes plugins/other/transmission/tr_ratios | 16 +++++ plugins/other/transmission/tr_ratios_data | 10 +++ plugins/other/transmission/tr_ratios_labels | 8 +++ plugins/zfs/zfs-statistics-for-freebsd | Bin 1561 -> 0 bytes plugins/zope/zodb/README | 36 ++++++++++ .../scripts_python/munin_cache_parameters.py | 27 ++++++++ .../zodb/scripts_python/munin_db_activity.py | 34 ++++++++++ plugins/zope/zodb/zope_cache_parameters | 43 ++++++++++++ plugins/zope/zodb/zope_db_activity | 41 ++++++++++++ plugins/zope/zope_zodb | Bin 2322 -> 0 bytes 15 files changed, 352 insertions(+) create mode 100755 plugins/beboxsync/beboxstats create mode 100755 plugins/beboxsync/beboxstats.expect create mode 100755 plugins/beboxsync/beboxsync delete mode 100755 plugins/other/beboxsync delete mode 100755 plugins/other/tr_ratios create mode 100755 plugins/other/transmission/tr_ratios create mode 100644 plugins/other/transmission/tr_ratios_data create mode 100644 plugins/other/transmission/tr_ratios_labels delete mode 100755 plugins/zfs/zfs-statistics-for-freebsd create mode 100644 plugins/zope/zodb/README create mode 100644 plugins/zope/zodb/scripts_python/munin_cache_parameters.py create mode 100644 plugins/zope/zodb/scripts_python/munin_db_activity.py create mode 100755 plugins/zope/zodb/zope_cache_parameters create mode 100755 plugins/zope/zodb/zope_db_activity delete mode 100755 plugins/zope/zope_zodb diff --git a/plugins/beboxsync/beboxstats b/plugins/beboxsync/beboxstats new file mode 100755 index 00000000..184b8315 --- /dev/null +++ b/plugins/beboxsync/beboxstats @@ -0,0 +1,62 @@ +#!/usr/bin/perl -w + +use strict; + +my ($Args) = @ARGV; + +my $expecter = "/home/alex/bin/beboxstats.expect"; + +if ($Args) { + + # work out line to grab + if ($Args eq 'autoconf') { + # Check the expect script that polls the router exists + unless ( -e $expecter ) { + print "no (Can't find expect script. Check value of \$expecter: $expecter)\n"; + } else { + print "yes\n"; + } + + } elsif ($Args eq 'config') { # print out plugin parameters + printf(" +graph_title bebox line stats +graph_vlabel deciBels +graph_category other +graph_info This graph shows the various line parameters +attenuationdownstream.label Downstream Attenuation +attenuationupstream.label Upstream Attenuation +margindownstream.label Downstream Noise Margin +marginupstream.label Upstream Noise Margin +outputpowerdownstream.label Downstream Output Power +outputpowerupstream.label Upstream Output Power +margindownstream.type GAUGE +outputpowerupstream.type GAUGE +attenuationdownstream.type GAUGE +marginupstream.type GAUGE +outputpowerdownstream.type GAUGE +attenuationupstream.type GAUGE + "); + # .label is the Key on the graph + } else { + printf("Usage: $0 + No arguments: print line stats + autoconf: print 'yes' + config: print config info for Munin\n"); + } + +} else { + # if no arguments, just fetch the data and print it out + +my @insplitted = split(' ', `$expecter | grep dB`); + +print "margindownstream.value $insplitted[3]\n"; +print "marginupstream.value $insplitted[4]\n"; + +print "attenuationdownstream.value $insplitted[8]\n"; +print "attenuationupstream.value $insplitted[9]\n"; + +print "outputpowerdownstream.value $insplitted[13]\n"; +print "outputpowerupstream.value $insplitted[14]\n"; +} + + diff --git a/plugins/beboxsync/beboxstats.expect b/plugins/beboxsync/beboxstats.expect new file mode 100755 index 00000000..aedd3d89 --- /dev/null +++ b/plugins/beboxsync/beboxstats.expect @@ -0,0 +1,25 @@ +#!/usr/bin/expect -f + +# script to log on to a BeBox router [ST Speedtouch 780] and gather line stats + +# set timeout for response from router to 30 seconds +set timeout 30 +set router "host.or.ip.of.router" +set port "23" +set username "Administrator" +set password "routerpassword" + +# telnet to $router on $port +spawn telnet $router $port + +expect "Username :" +send "$username\r" + +expect "Password :" +send "$password\r" + +expect "}=>" +send "adsl info\r" + +expect "}=>" +send "exit\r" diff --git a/plugins/beboxsync/beboxsync b/plugins/beboxsync/beboxsync new file mode 100755 index 00000000..be992845 --- /dev/null +++ b/plugins/beboxsync/beboxsync @@ -0,0 +1,50 @@ +#!/usr/bin/perl -w + +# (C) Alex Dekker +# License is GPL + +use strict; + +my ($Args) = @ARGV; + +my $expecter = "/home/alex/bin/beboxstats.expect"; + +if ($Args) { + + # work out line to grab + if ($Args eq 'autoconf') { + # Check the expect script that polls the router exists + unless ( -e $expecter ) { + print "no (Can't find expect script. Check value of \$expecter: $expecter)\n"; + } else { + print "yes\n"; + } + } elsif ($Args eq 'config') { # print out plugin parameters + printf(" +graph_title bebox sync stats +graph_vlabel ATM kbps +graph_category other +graph_info This graph shows line sync speed +syncdownstream.label Downstream Sync Speed +syncupstream.label Upstream Sync Speed +syncdownstream.type GAUGE +syncupstream.type GAUGE + "); + # .label is the Key on the graph + } else { + printf("Usage: $0 + No arguments: print line stats + autoconf: print 'yes' + config: print config info for Munin\n"); + } + +} else { + # if no arguments, just fetch the data and print it out + +my @insplitted = split(' ', `$expecter | grep stream`); + +print "syncdownstream.value $insplitted[11]\n"; +print "syncupstream.value $insplitted[15]\n"; +} + + diff --git a/plugins/other/beboxsync b/plugins/other/beboxsync deleted file mode 100755 index aa34bfba225c4134a0a8a1491586010a42250698..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1188 zcmV;V1Y7$biwFP?EZ0c@1MOFBZ`(Ey&R6SK+++hzfX4Al9Cz7T#A%0oSknbdvM)`s z(h_BJmPw7I;sjg&`;L@kOO~7z!;-C-4hAfV&)t#t#=8lfh&!c;Ry$8dU8K=)X#RVn zVK@J8XfPZNcY3|v(eS80><VONi4_HFrV>B92Q#st2gXEJ z(qt7>odo3~4+~a;{%{;fsR>IV=OAJYA>$OZfT<*t)%uDH==H~7CPzPZb=wZ5CPn*L?5rU?A>s*)Ta2)KtuG%qx$cus^(u?+lnfh)R>b^ zjX}|Xi6rBUD2%6!LqsH5P~2MCP8J*Nx(@m)n*FMo4k=jAC!VzaPZw`PGNB>()MKZ( zgY>IMG@S~04+6a+(~pb?0Gj7IBK=zYSt%w zKHA_Z#(h-^WkGzc$dqCxcDE+kdjWXXctN>V$7!PE;(QxhR_NW44b@x z&4@rqIFC8wnBqB0U~ZSr)-*+v=eGL-e#2W10;;{4HI7d-0fIFu(Zg)Y+p2!TxQarC zuJN(1+sEBDv|qrdbt(K4jY}i&Pe0*CoV56qf-I?Yt+l)lgO9d66&O~YFT)QLc!sYI z#WLH=f|jZvEAxC?R8<|iWwu`NL{+&|!IYj0J?H$}mp@YJs(u0;kMw`t(O{7Ef4!0I z{|3GOsP6xsgL3^}+OX^gj?-LqP69$PwM7*R3Y^kYyx!CP>BHp}Tt<}oTEtjbMlZV` zZBdyLbDiglqmf5Z7+X-&TbNoVsfq;0x)n&V$RwhUK^LJ|_z zheaI`bds;GMMOekD)tA-8+NjiW1j%-*k3S?{hlORWKg0MHlIGYiGb|gHT%^x;e|14BB|21)r*@H127~azP z9HaaD1wBCnbiBLQxcZKH)TAzUU1t~X{%`YQqp^KLY&07G@G#hDZ0%he8*?8*pL@_V zg`;ZF8(*End=mYQK`*&AtXOlkIOg%8$>`ERFIUiQ1JMSodLk(Zs7H~nXB0_XmLEqp zoLtd{_X@px!SxmB;eV=Wuc@Y*YO1NGnrf=4rkZN1sivB0s;Qr!225i6<3d`?F3CsK2STchly@On))!1_E1&G zfFagG64_3>s^foO!beK!7@7v%rrl49Y$xaQ<<57PM%h@#+CJDLPEN!3XJgL#IGZz8 z_nb!H2F3e);d%$)@6)IynKoPj9H=BQKa<<`{U0S=#NVi%;zlOAH{^!z_KYIHf#+?E zzZ=vS@%I?>Sss6n`FZ@E-J0=Z{`2_1y?EcggnM|`zWCVs+-`M0bf5{e0Uj_Hm;((s z%b$GiITWTqEj>|7s>>3Vpy`5}wPEU&6 z%k7Qo?B30{TGnh)NH?LJzRK-zO0`Q;C1V4$-JCw zQ4G6iPUkhu+z3bia4xu#W#ni7-5 z2&lzSDO_=0DI5W{2)@CX-+qDG2<%KNTZdc;dy>Vu=bkpu* 1 { + split($1,torrentid," ") + if(torrentid[1] != "Sum:") { + split($7,ratio," ") + ratio[1] = ratio[1] * 100 + print "ID" torrentid[1] ".value " ratio[1] + } +} + diff --git a/plugins/other/transmission/tr_ratios_labels b/plugins/other/transmission/tr_ratios_labels new file mode 100644 index 00000000..273ab3d3 --- /dev/null +++ b/plugins/other/transmission/tr_ratios_labels @@ -0,0 +1,8 @@ +BEGIN { FIELDWIDTHS = "7 4 13 10 7 9 7 13 40" } +NR > 1 { + split($1,torrentid," ") + if(torrentid[1] != "Sum:") { + print "ID" torrentid[1] ".label " $9 + } +} + diff --git a/plugins/zfs/zfs-statistics-for-freebsd b/plugins/zfs/zfs-statistics-for-freebsd deleted file mode 100755 index 8bb497591cc081345bdd6db7320f1d373768756b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1561 zcmV+!2Il!6iwFRfBJE571MOOEZ`(Ey_6BT2{AJ&^uQw%`Utrmi{MI;V3paI_0QFYH zF3=@T1zM(UqOzn(R2!$uKiNOn-`NiuDOr9=;y6vzBnJ4vg2b0Q9*;-f9q6;Zrz6+U z4P*?lJ|xuByW>g8Bpyw~07X%%Xg~w)B}8q4WFW}iFt#I0Z}k9Vj6wUDFUAIDHMFqEts}}%wU~n^mE)H z?7y_D?7%Z9^zg@m<(npG&wf=Gi8-(_v|)_Bg}PHhL5XUx>ETNhl4VQFN%|ytfiNP1 zG<%jxJX20)%6-O}ab-WY1mU_a>OZVo(0({*YTzPgs8d3j%8y>PpnkXqd)$y=pP4nc zmaz1inRV(C9dZXAfNX+tx$UEgy4Zy6%Pj_?cwoC@KH%k6V)bok4~YjsnQcD%Q)nk# zwqTRNa3Wh+G6UI?%a^(ie*^mT0a7m-za9JzpW(2@wIabTyb8WLmIUWe*sJgDH(>vu z-GUc?LRflz&}tXpv*Qwro~Ib2PBLIsc;BJ<>^5ui{BF8%+@WxiE#xFAvl~=EC!NoB zGBs9Ji|T6mNe}1|&oR;1VkZC_e@oegLC6O3C#;Ju<+c>oEf|$GOZiZl(i|NZnzxLI z1&VZ@+DIlhCguF9*34?0!%Y?(ZCQkw=)u%rP)Z{^2porJCf21v|kE z?0J~+W;M1?9iOg+@+YdlQqe)(_M}Hp&{-kRTD93Ss8aqTGJVXpm3E#=KD3t-_*%#p z^7_?2zK1B%>Da+{9%DuPr)cG36#uDeS>f?txl$4F-@V|wpMFSun@BW~0e`gMUF64k zU1Ebh8hgg<;pKlhLA&v;eV8?d%URaj?Zd?L@Bf=n{KK9fFLe24R{yhMkMhWIOq_4y zQ`)c$yGN`6Ykb>&B|q6!izQ91?mQ{QJ#ztuuf6v zP`!};sXMijBGNyR{;ga3$E~ADc(A`D_mgGcaj+|!WW*#<*&b)fpv>M6kPmWUM}e^1 z%K2^tz8ho745PHfYVxzywna(ZqM6*_r6r|Z); zohh5?n)OLd31O~x`nWD1A^A){VQT`AJ$?@-S++#SioBEObhvO zt=7uo#!q/munin_db_activity.py +wget --delete-after -q -O - localhost:8080//munin_cache_parameters.py + +Edit zope_db_activity and zope_cache_parameters scripts to reflect + and your instance(s) ports. + +Then move them into your munin plugins lib, and create a symlink under etc according to the +usual munin custom: + +mv zope_* /opt/munin/lib/plugins/ + +ln -s /opt/munin/lib/plugins/zope_* /etc/opt/munin/plugins/ + +Test them with: +/opt/munin/sbin/munin-run zope_db_activity +/opt/munin/sbin/munin-run zope_cache_parameters + +Restart your munin-node and the graphs should appear shortly. + +If you make any improvements (which should be easy), please update +the munin exhange entry, or mail me at gaute(at)pht(dot)no \ No newline at end of file diff --git a/plugins/zope/zodb/scripts_python/munin_cache_parameters.py b/plugins/zope/zodb/scripts_python/munin_cache_parameters.py new file mode 100644 index 00000000..70dff165 --- /dev/null +++ b/plugins/zope/zodb/scripts_python/munin_cache_parameters.py @@ -0,0 +1,27 @@ +## Script (Python) "munin_cache_parameters.py" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +""" +Fetches data about the ZODB for the munin plugin "zope_cache_parameters". +Needs the Manager proxy role to work. +Only answers requests from localhost directly to zopes port. +""" + +req = context.REQUEST + +if req['HTTP_X_FORWARDED_FOR'] or req['REMOTE_ADDR'] != '127.0.0.1': + return "This script can only be called frm localhost" + +maindb = context.restrictedTraverse('/Control_Panel/Database/main') + +print maindb.database_size(), # Total number of objects in the database +print maindb.cache_length(), # Total number of objects in memory from all caches +print len(maindb.cache_detail_length()) * maindb.cache_size() # Target number of objects in memory sum total + +return printed diff --git a/plugins/zope/zodb/scripts_python/munin_db_activity.py b/plugins/zope/zodb/scripts_python/munin_db_activity.py new file mode 100644 index 00000000..824fce48 --- /dev/null +++ b/plugins/zope/zodb/scripts_python/munin_db_activity.py @@ -0,0 +1,34 @@ +## Script (Python) "munin_db_activity.py" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##parameters= +##title= +## +""" +Fetches data about the ZODB for the munin plugin "zope_db_activity". +Needs the Manager proxy role to work. +Only answers requests from localhost directly to zopes port. +""" + +req = context.REQUEST + +if req['HTTP_X_FORWARDED_FOR'] or req['REMOTE_ADDR'] != '127.0.0.1': + return "This script can only be called frm localhost" + +sec = 60*5 # 5 min is munins update frequency + +now = float(DateTime()) +then = now-sec + +request = dict(chart_start=then, + chart_end=now) + +maindb = context.restrictedTraverse('/Control_Panel/Database/main') +cd = maindb.getActivityChartData(200, request) + +print cd['total_load_count'],cd['total_store_count'],cd['total_connections'] + +return printed diff --git a/plugins/zope/zodb/zope_cache_parameters b/plugins/zope/zodb/zope_cache_parameters new file mode 100755 index 00000000..cfdf3813 --- /dev/null +++ b/plugins/zope/zodb/zope_cache_parameters @@ -0,0 +1,43 @@ +#!/usr/bin/python + +from sys import argv +import httplib +conns = [] + +# this should really go in plugins.conf +conns.append(httplib.HTTPConnection("localhost",8080)) +conns.append(httplib.HTTPConnection("localhost",8070)) + + +url = "/munin_cache_parameters.py" + +if len(argv) > 1 and argv[1] == 'config': + + # there is probably a better way to display this cached vs targed graph + # as a percentage of target possibly.. + + print """graph_title Zope cache parameters + graph_category Zope + graph_info A grap of the main data on the "Cache Parameters" tab of the main DB in the zope control panel.""".replace("\n ","\n") + for i in range(0,len(conns)): + print """obs_in_db%(i)s.label Z%(i)s Obs in DB + obs_cached%(i)s.label Z%(i)s obs in all caches + obs_target%(i)s.label Z%(i)s cached obs target""".replace("\n ","\n") % dict(i=i) +else: + for i in range(0,len(conns)): + conns[i].request("GET", url) + + r1 = conns[i].getresponse() + #print r1.status, r1.reason + #200 OK + data = r1.read().strip() + conns[i].close() + (obs_in_db, obs_cached, obs_target) = data.split() + id = dict(i=i) + print 'obs_in_db%(i)s.value' % id, obs_in_db + print 'obs_cached%(i)s.value'% id, obs_cached + print 'obs_target%(i)s.value'% id, obs_target + + + + diff --git a/plugins/zope/zodb/zope_db_activity b/plugins/zope/zodb/zope_db_activity new file mode 100755 index 00000000..64175fb9 --- /dev/null +++ b/plugins/zope/zodb/zope_db_activity @@ -0,0 +1,41 @@ +#!/usr/bin/python + +from sys import argv +import httplib +conns = [] + +# this should really go in plugins.conf +conns.append(httplib.HTTPConnection("localhost",8080)) +conns.append(httplib.HTTPConnection("localhost",8070)) + + +url = "/munin_db_activity.py" + +if len(argv) > 1 and argv[1] == 'config': + + print """graph_title Zope Database Activity + graph_vlabel Count / 5 min. + graph_category Zope + graph_info The number of Reads, Stores, and Connections that happens in the ZODB backend. The data comes from the same source as that in the "Recent Database Activity" tab in the zope control panel.""".replace("\n ","\n") + for i in range(0,len(conns)): + print """load_count%(i)s.label Z%(i)s Loads + store_count%(i)s.label Z%(i)s Stores + connections%(i)s.label Z%(i)s Connections""".replace("\n ","\n") % dict(i=i) +else: + for i in range(0,len(conns)): + conns[i].request("GET", url) + + r1 = conns[i].getresponse() + #print r1.status, r1.reason + #200 OK + data = r1.read().strip() + conns[i].close() + (total_load_count, total_store_count, total_connections) = data.split() + id = dict(i=i) + print 'load_count%(i)s.value' % id, total_load_count + print 'store_count%(i)s.value'% id, total_store_count + print 'connections%(i)s.value'% id, total_connections + + + + diff --git a/plugins/zope/zope_zodb b/plugins/zope/zope_zodb deleted file mode 100755 index f2e1a0d90b7721a3173ee6207360b8aae5483bf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2322 zcmV+t3GMbDiwFRo%40?V1MOLDbKAHP_GkWzJ$Y^Noo=sl+&zH)m+R7&a-~@Ya4=)J<{#mEtovzle;{@nZ{0B$J2hjNvo!O^9c>G6mt~juaLk}{h=RAWj z%OehpT*Ly>B%j4XftE1i8kmNNX$EW}a}6|i6uiGUdmVVFXAN_<zI7)n<6%oQWBF zLag;1jR)Slxy+LYwQ86csX5Ccn9CK%p}~pop=pWz#rcyYJL*H3u8n%VlBEe67=Ef1 z@8cBhNKx~qGKo-MEKraf8o=93PS_+_17|AcO2aQWM@etWl;)&mVcD7RSc-m3vzTd) z0)j2j^MbDms~e;5-~5D*I!)s62Bg@y{{wcCP0(2)f?2#QG@DMoVS>$gR)b6?67m|-*wu5LN{Uj zaGrhNHWO?dO~x$L@iNxyAYK1=y38~grz}G^pr9g!-Z{nEWVwndGiLK~U#2=GGCoas zsJ)6MBWPYt;Bf{vln<%QvOA19H&Iq|U@w~;-4&w#1WvZy&=QvV_T9~bz4 zG#Ctei2uh&FCG3r3mtyb&Q;c?^=T2w^QM_xU_w%~fN*VLaWGqY#q(V26!V9NK#O^7 z2v^shcW7{6v$QayB?v_`g2qk43ka93OhC(4M2$jG@aNI!?I|{3o{gnw)XF4ZYf_f? z{Z9}ZkeKJ?S%N*RJq!*t&x@y!aM7S4`tUt;O|GH0tL`-nhfuc_MIBQuAkk2ZY9rmC zG{bD738z+UO}RRXRhrNvImKATVhHgBwc?Y>VTCTHP#BAu5R(kTEy$_m(g-L@#i%?8 ztX)KSp`li*8S$}>b%Lml3)UKdN){z{%N1fqn_+Eb7%SgnF_rMjycm;|^B4xpRCYyq zP&+kx-+4 zo>7u*bea?d6KLN*F&sOimJ>BLwZgZJ*jGWqCOm=n<^?V$rnWkJU5XL6_4_^S(y~*@ zW_Z+&n05a>VnrND+Vb2pz{()uTbu@=Zp6db_jscC$rFZcK3v7usQ=d-A+b^W@qAQk z0?udOE4i{RPVSNwdz5jNN}+heFL@5F2eWQ~NlxdgNsqWd6)y9Vr`PGg#b3&IGYf_V zW7P0b6bqt?($Z#_$Q^5qGEB`%44M_k`ly)n2e?9FT@j5VYAHRoI|1r@;a{>O=XG>( zTqrkf_X$;JftA_{*|z(ns*_+}%C?nKRl9mLcmHO@T*?1KH``r@%`$u&C z(?9ATIsAVP`orM=?nd+J(El(5pJ7Iu&?e&5X6LiT+NDL2Q<u{zk0XsFoeoyv=@63rRs^97KzVw|* za#y;-^0k!)Tm0WWnEagAK~K2%MgL-*eF6A-uD91&y~R@IKT&a$s_Jh?Qbwz@Ei|XT$QT+QdKTVez~9Oji>s zMf@CYzS#LTv_Iv?d_w2!L!GfD+T`Qn1GaB_LMlxCMGqcgv-bnnw3n}5PL=f!!SME6 z*H)xZyZ5xS7I=Tg`io>y6)1t=HZZhiwwBW6@%P)2a%hqIFEycMZP@ zhcF`0tW>sg@(VhutXek`yLxP_u!NfF`J-y=rJ@Z;<*3Ihq%v$rX~b~~C#7y5UhEpR zJtvFybnas&RlcxA0fpFvz!>Gx|7Zd5NdDj5HGQIu$Mb)A{(n3eApZBdJ-7dV9(p+c z?{Ap@zfyl?bS~>F9%8qSJ1_c}9Y;K`OGg@-dW?vW1S*FM4ig!q?&HcTSW#A$jq6+`>fKf=>%1t`Q Date: Mon, 6 Aug 2012 22:20:20 -0700 Subject: [PATCH 11/11] More housekeeping. --- plugins/{pure => ftp}/pure-ftpd-bw | 0 plugins/{pure => ftp}/pure-ftpd-logs | 0 plugins/{pureftpd => ftp}/pureftpd_traffic | 0 plugins/{ => network}/ssh/openssh-denyhosts | 0 plugins/network/{ => ssh}/sshd_invalid_countries | 0 plugins/network/{ => ssh}/sshd_invalid_countries_ruby | 0 plugins/{ => sensors}/power/acpi_batt_ | 0 plugins/{ => sensors}/power/acpi_sys_batt_ | 0 plugins/{ => sensors}/power/batteries | 0 plugins/{streaming => snmp}/snmp__wmsconnectedplayers | 0 plugins/{streaming => snmp}/snmp__wmsplayerallocatedbandwidth | 0 plugins/{streaming => snmp}/snmp__wmsstreaminghttpplayers | 0 plugins/{streaming => snmp}/snmp__wmsstreamingmmsplayers | 0 plugins/{streaming => snmp}/snmp__wmsstreamingplayers | 0 plugins/{streaming => snmp}/snmp__wmsstreamingrtspplayers | 0 plugins/{stream => streaming}/icecast2 | 0 plugins/{icecast => streaming}/icecast2_ | 0 plugins/{icecast => streaming}/icecast2_all | 0 plugins/{icecast => streaming}/icecast2_simple | 0 plugins/{icecast => streaming}/icecast_ | 0 plugins/{shoutcast => streaming}/shoutcast | 0 plugins/{shoutcast => streaming}/shoutcast2_multi | 0 plugins/{kvm => virtualization}/kvm_cpu | 0 plugins/{kvm => virtualization}/kvm_io | 0 plugins/{kvm => virtualization}/kvm_mem | 0 plugins/{kvm => virtualization}/kvm_net | 0 plugins/{kvm => virtualization}/munin-libvirtpy | 0 plugins/{ => virtualization}/vmware/esx_ | 0 plugins/{ => virtualization}/vmware/esxi | 0 plugins/{ => virtualization}/vmware/vm_cpu_load | 0 plugins/{ => virtualization}/vserver/vserver_jiffies | 0 plugins/{ => virtualization}/vserver/vserver_limit_hits | 0 plugins/{ => virtualization}/vserver/vserver_limits | 0 plugins/{xen => virtualization}/xen | 0 plugins/{xen => virtualization}/xen-cpu | 0 plugins/{xen => virtualization}/xen-multi | 0 plugins/{xen => virtualization}/xen_cpu_v2 | 0 plugins/{xen => virtualization}/xen_memory | 0 plugins/{xen => virtualization}/xen_traffic_ | 0 plugins/{xen => virtualization}/xen_traffic_all | 0 plugins/{xen => virtualization}/xen_vbd | 0 plugins/{filesystem => zfs}/zfs_cache_efficiency | 0 plugins/{filesystem => zfs}/zfsarcstats-counters | 0 43 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{pure => ftp}/pure-ftpd-bw (100%) rename plugins/{pure => ftp}/pure-ftpd-logs (100%) rename plugins/{pureftpd => ftp}/pureftpd_traffic (100%) rename plugins/{ => network}/ssh/openssh-denyhosts (100%) rename plugins/network/{ => ssh}/sshd_invalid_countries (100%) rename plugins/network/{ => ssh}/sshd_invalid_countries_ruby (100%) rename plugins/{ => sensors}/power/acpi_batt_ (100%) rename plugins/{ => sensors}/power/acpi_sys_batt_ (100%) rename plugins/{ => sensors}/power/batteries (100%) rename plugins/{streaming => snmp}/snmp__wmsconnectedplayers (100%) rename plugins/{streaming => snmp}/snmp__wmsplayerallocatedbandwidth (100%) rename plugins/{streaming => snmp}/snmp__wmsstreaminghttpplayers (100%) rename plugins/{streaming => snmp}/snmp__wmsstreamingmmsplayers (100%) rename plugins/{streaming => snmp}/snmp__wmsstreamingplayers (100%) rename plugins/{streaming => snmp}/snmp__wmsstreamingrtspplayers (100%) rename plugins/{stream => streaming}/icecast2 (100%) rename plugins/{icecast => streaming}/icecast2_ (100%) rename plugins/{icecast => streaming}/icecast2_all (100%) rename plugins/{icecast => streaming}/icecast2_simple (100%) rename plugins/{icecast => streaming}/icecast_ (100%) rename plugins/{shoutcast => streaming}/shoutcast (100%) rename plugins/{shoutcast => streaming}/shoutcast2_multi (100%) rename plugins/{kvm => virtualization}/kvm_cpu (100%) rename plugins/{kvm => virtualization}/kvm_io (100%) rename plugins/{kvm => virtualization}/kvm_mem (100%) rename plugins/{kvm => virtualization}/kvm_net (100%) rename plugins/{kvm => virtualization}/munin-libvirtpy (100%) rename plugins/{ => virtualization}/vmware/esx_ (100%) rename plugins/{ => virtualization}/vmware/esxi (100%) rename plugins/{ => virtualization}/vmware/vm_cpu_load (100%) rename plugins/{ => virtualization}/vserver/vserver_jiffies (100%) rename plugins/{ => virtualization}/vserver/vserver_limit_hits (100%) rename plugins/{ => virtualization}/vserver/vserver_limits (100%) rename plugins/{xen => virtualization}/xen (100%) rename plugins/{xen => virtualization}/xen-cpu (100%) rename plugins/{xen => virtualization}/xen-multi (100%) rename plugins/{xen => virtualization}/xen_cpu_v2 (100%) rename plugins/{xen => virtualization}/xen_memory (100%) rename plugins/{xen => virtualization}/xen_traffic_ (100%) rename plugins/{xen => virtualization}/xen_traffic_all (100%) rename plugins/{xen => virtualization}/xen_vbd (100%) rename plugins/{filesystem => zfs}/zfs_cache_efficiency (100%) rename plugins/{filesystem => zfs}/zfsarcstats-counters (100%) diff --git a/plugins/pure/pure-ftpd-bw b/plugins/ftp/pure-ftpd-bw similarity index 100% rename from plugins/pure/pure-ftpd-bw rename to plugins/ftp/pure-ftpd-bw diff --git a/plugins/pure/pure-ftpd-logs b/plugins/ftp/pure-ftpd-logs similarity index 100% rename from plugins/pure/pure-ftpd-logs rename to plugins/ftp/pure-ftpd-logs diff --git a/plugins/pureftpd/pureftpd_traffic b/plugins/ftp/pureftpd_traffic similarity index 100% rename from plugins/pureftpd/pureftpd_traffic rename to plugins/ftp/pureftpd_traffic diff --git a/plugins/ssh/openssh-denyhosts b/plugins/network/ssh/openssh-denyhosts similarity index 100% rename from plugins/ssh/openssh-denyhosts rename to plugins/network/ssh/openssh-denyhosts diff --git a/plugins/network/sshd_invalid_countries b/plugins/network/ssh/sshd_invalid_countries similarity index 100% rename from plugins/network/sshd_invalid_countries rename to plugins/network/ssh/sshd_invalid_countries diff --git a/plugins/network/sshd_invalid_countries_ruby b/plugins/network/ssh/sshd_invalid_countries_ruby similarity index 100% rename from plugins/network/sshd_invalid_countries_ruby rename to plugins/network/ssh/sshd_invalid_countries_ruby diff --git a/plugins/power/acpi_batt_ b/plugins/sensors/power/acpi_batt_ similarity index 100% rename from plugins/power/acpi_batt_ rename to plugins/sensors/power/acpi_batt_ diff --git a/plugins/power/acpi_sys_batt_ b/plugins/sensors/power/acpi_sys_batt_ similarity index 100% rename from plugins/power/acpi_sys_batt_ rename to plugins/sensors/power/acpi_sys_batt_ diff --git a/plugins/power/batteries b/plugins/sensors/power/batteries similarity index 100% rename from plugins/power/batteries rename to plugins/sensors/power/batteries diff --git a/plugins/streaming/snmp__wmsconnectedplayers b/plugins/snmp/snmp__wmsconnectedplayers similarity index 100% rename from plugins/streaming/snmp__wmsconnectedplayers rename to plugins/snmp/snmp__wmsconnectedplayers diff --git a/plugins/streaming/snmp__wmsplayerallocatedbandwidth b/plugins/snmp/snmp__wmsplayerallocatedbandwidth similarity index 100% rename from plugins/streaming/snmp__wmsplayerallocatedbandwidth rename to plugins/snmp/snmp__wmsplayerallocatedbandwidth diff --git a/plugins/streaming/snmp__wmsstreaminghttpplayers b/plugins/snmp/snmp__wmsstreaminghttpplayers similarity index 100% rename from plugins/streaming/snmp__wmsstreaminghttpplayers rename to plugins/snmp/snmp__wmsstreaminghttpplayers diff --git a/plugins/streaming/snmp__wmsstreamingmmsplayers b/plugins/snmp/snmp__wmsstreamingmmsplayers similarity index 100% rename from plugins/streaming/snmp__wmsstreamingmmsplayers rename to plugins/snmp/snmp__wmsstreamingmmsplayers diff --git a/plugins/streaming/snmp__wmsstreamingplayers b/plugins/snmp/snmp__wmsstreamingplayers similarity index 100% rename from plugins/streaming/snmp__wmsstreamingplayers rename to plugins/snmp/snmp__wmsstreamingplayers diff --git a/plugins/streaming/snmp__wmsstreamingrtspplayers b/plugins/snmp/snmp__wmsstreamingrtspplayers similarity index 100% rename from plugins/streaming/snmp__wmsstreamingrtspplayers rename to plugins/snmp/snmp__wmsstreamingrtspplayers diff --git a/plugins/stream/icecast2 b/plugins/streaming/icecast2 similarity index 100% rename from plugins/stream/icecast2 rename to plugins/streaming/icecast2 diff --git a/plugins/icecast/icecast2_ b/plugins/streaming/icecast2_ similarity index 100% rename from plugins/icecast/icecast2_ rename to plugins/streaming/icecast2_ diff --git a/plugins/icecast/icecast2_all b/plugins/streaming/icecast2_all similarity index 100% rename from plugins/icecast/icecast2_all rename to plugins/streaming/icecast2_all diff --git a/plugins/icecast/icecast2_simple b/plugins/streaming/icecast2_simple similarity index 100% rename from plugins/icecast/icecast2_simple rename to plugins/streaming/icecast2_simple diff --git a/plugins/icecast/icecast_ b/plugins/streaming/icecast_ similarity index 100% rename from plugins/icecast/icecast_ rename to plugins/streaming/icecast_ diff --git a/plugins/shoutcast/shoutcast b/plugins/streaming/shoutcast similarity index 100% rename from plugins/shoutcast/shoutcast rename to plugins/streaming/shoutcast diff --git a/plugins/shoutcast/shoutcast2_multi b/plugins/streaming/shoutcast2_multi similarity index 100% rename from plugins/shoutcast/shoutcast2_multi rename to plugins/streaming/shoutcast2_multi diff --git a/plugins/kvm/kvm_cpu b/plugins/virtualization/kvm_cpu similarity index 100% rename from plugins/kvm/kvm_cpu rename to plugins/virtualization/kvm_cpu diff --git a/plugins/kvm/kvm_io b/plugins/virtualization/kvm_io similarity index 100% rename from plugins/kvm/kvm_io rename to plugins/virtualization/kvm_io diff --git a/plugins/kvm/kvm_mem b/plugins/virtualization/kvm_mem similarity index 100% rename from plugins/kvm/kvm_mem rename to plugins/virtualization/kvm_mem diff --git a/plugins/kvm/kvm_net b/plugins/virtualization/kvm_net similarity index 100% rename from plugins/kvm/kvm_net rename to plugins/virtualization/kvm_net diff --git a/plugins/kvm/munin-libvirtpy b/plugins/virtualization/munin-libvirtpy similarity index 100% rename from plugins/kvm/munin-libvirtpy rename to plugins/virtualization/munin-libvirtpy diff --git a/plugins/vmware/esx_ b/plugins/virtualization/vmware/esx_ similarity index 100% rename from plugins/vmware/esx_ rename to plugins/virtualization/vmware/esx_ diff --git a/plugins/vmware/esxi b/plugins/virtualization/vmware/esxi similarity index 100% rename from plugins/vmware/esxi rename to plugins/virtualization/vmware/esxi diff --git a/plugins/vmware/vm_cpu_load b/plugins/virtualization/vmware/vm_cpu_load similarity index 100% rename from plugins/vmware/vm_cpu_load rename to plugins/virtualization/vmware/vm_cpu_load diff --git a/plugins/vserver/vserver_jiffies b/plugins/virtualization/vserver/vserver_jiffies similarity index 100% rename from plugins/vserver/vserver_jiffies rename to plugins/virtualization/vserver/vserver_jiffies diff --git a/plugins/vserver/vserver_limit_hits b/plugins/virtualization/vserver/vserver_limit_hits similarity index 100% rename from plugins/vserver/vserver_limit_hits rename to plugins/virtualization/vserver/vserver_limit_hits diff --git a/plugins/vserver/vserver_limits b/plugins/virtualization/vserver/vserver_limits similarity index 100% rename from plugins/vserver/vserver_limits rename to plugins/virtualization/vserver/vserver_limits diff --git a/plugins/xen/xen b/plugins/virtualization/xen similarity index 100% rename from plugins/xen/xen rename to plugins/virtualization/xen diff --git a/plugins/xen/xen-cpu b/plugins/virtualization/xen-cpu similarity index 100% rename from plugins/xen/xen-cpu rename to plugins/virtualization/xen-cpu diff --git a/plugins/xen/xen-multi b/plugins/virtualization/xen-multi similarity index 100% rename from plugins/xen/xen-multi rename to plugins/virtualization/xen-multi diff --git a/plugins/xen/xen_cpu_v2 b/plugins/virtualization/xen_cpu_v2 similarity index 100% rename from plugins/xen/xen_cpu_v2 rename to plugins/virtualization/xen_cpu_v2 diff --git a/plugins/xen/xen_memory b/plugins/virtualization/xen_memory similarity index 100% rename from plugins/xen/xen_memory rename to plugins/virtualization/xen_memory diff --git a/plugins/xen/xen_traffic_ b/plugins/virtualization/xen_traffic_ similarity index 100% rename from plugins/xen/xen_traffic_ rename to plugins/virtualization/xen_traffic_ diff --git a/plugins/xen/xen_traffic_all b/plugins/virtualization/xen_traffic_all similarity index 100% rename from plugins/xen/xen_traffic_all rename to plugins/virtualization/xen_traffic_all diff --git a/plugins/xen/xen_vbd b/plugins/virtualization/xen_vbd similarity index 100% rename from plugins/xen/xen_vbd rename to plugins/virtualization/xen_vbd diff --git a/plugins/filesystem/zfs_cache_efficiency b/plugins/zfs/zfs_cache_efficiency similarity index 100% rename from plugins/filesystem/zfs_cache_efficiency rename to plugins/zfs/zfs_cache_efficiency diff --git a/plugins/filesystem/zfsarcstats-counters b/plugins/zfs/zfsarcstats-counters similarity index 100% rename from plugins/filesystem/zfsarcstats-counters rename to plugins/zfs/zfsarcstats-counters