hobbit-plugins/0000755000000000000000000000000012231436130010665 5ustar hobbit-plugins/misc.d/0000755000000000000000000000000012124313210012034 5ustar hobbit-plugins/misc.d/zombies0000755000000000000000000000432612124313210013437 0ustar #!/usr/bin/perl -w use strict; use File::Basename qw(dirname); # Function to parse config file; splits at first blanks. sub file_to_hash_of_regexp_keys_and_values($) { my %regexps = (); my $filename = shift; open(my $fh, '<', $filename) or return %regexps; while(<$fh>) { unless (/^#|^\s*$/) { chomp; my ($key, $value) = split(/\s+/, $_, 2); $regexps{$key} = $value; } } return %regexps; } my $ext_apt_config = dirname($0).'/..'; my $ignore_file = $ext_apt_config."/zombies_ignore"; my %ignore = file_to_hash_of_regexp_keys_and_values($ignore_file); chdir ("/proc"); my $zombies = 0; foreach my $pid (glob ("[1-9]*")) { open(F, '<', "$pid/status") or next; my $maybe_zombie = 0; while () { if (/^State:\s+Z/) { my $mtime = (stat ($pid))[9]; # Don't report zombies which are younger than 1 minute last if not defined $mtime or time - $mtime < 60; $maybe_zombie++; last; } } close F; next unless $maybe_zombie; # Check after 1 second if the process in question is still a # zombie. Only report if that's the case. sleep 1; my $ignored = undef; my $userignored = undef; my $name = ''; open(F, '<', "$pid/status") or next; my $zombie = 0; while () { if (/^Name:\s+(.*?)$/) { $name = $1; foreach my $regexp (keys %ignore) { next if $regexp =~ /:\^/; if ($name =~ /^$regexp$/) { $ignored = $ignore{$regexp}; } } } if (/^State:\s+Z/) { my $mtime = (stat ($pid))[9]; last if not defined $mtime or time - $mtime < 60; $zombie = 1; } if (/^Uid:\s+(\d+)\s/) { my $username = getpwuid($1); foreach my $regexp (keys %ignore) { next unless $regexp =~ /:\^/; my ($user_re, $process_re) = split(/:\^/, $regexp, 2); if ($username =~ /^$user_re$/ and $name =~ /^$process_re$/) { $userignored = "$username: $ignore{$regexp}"; } } last; } } close F; if ($zombie) { system "ps u $pid"; if ($ignored) { print "($name zombies ignored: $ignored)\n"; } elsif ($userignored) { print "($name zombies ignored under user $userignored)\n"; } else { $zombies++; } } } if ($zombies) { exit 1; } else { print "No zombie processes\n"; exit 0; } hobbit-plugins/misc.d/mount-ro0000755000000000000000000000021612124313210013541 0ustar #!/bin/sh if egrep ' ro[, ]' /proc/mounts | egrep -v ' (iso9660|nfs4?|udf) ' ; then exit 2 else echo "No filesystems mounted read-only" fi hobbit-plugins/xymonlaunch.d/0000755000000000000000000000000012231434742013463 5ustar hobbit-plugins/xymonlaunch.d/aptdiff.cfg0000644000000000000000000000022412231434742015557 0ustar [aptdiff] DISABLED ENVFILE /etc/xymon/xymonserver.cfg CMD /usr/lib/xymon/server/ext/aptdiff LOGFILE /var/log/xymon/xymonlaunch.log INTERVAL 5m hobbit-plugins/xymonlaunch.d/pgbouncer.cfg0000644000000000000000000000023012231434742016123 0ustar [pgbouncer] DISABLED ENVFILE /etc/xymon/xymonserver.cfg CMD /usr/lib/xymon/server/ext/pgbouncer LOGFILE /var/log/xymon/xymonlaunch.log INTERVAL 5m hobbit-plugins/xymonlaunch.d/tftp.cfg0000644000000000000000000000021612231434742015120 0ustar [tftp] DISABLED ENVFILE /etc/xymon/xymonserver.cfg CMD /usr/lib/xymon/server/ext/tftp LOGFILE /var/log/xymon/xymonlaunch.log INTERVAL 5m hobbit-plugins/xymonlaunch.d/ircbot.cfg0000644000000000000000000000027312231434742015430 0ustar [ircbot] DISABLED ENVFILE /usr/lib/xymon/server/etc/xymonserver.cfg NEEDS xymond LOGFILE /var/log/xymon/ircbot.log CMD xymond_channel --channel=page /usr/lib/xymon/server/ext/ircbot hobbit-plugins/xymonlaunch.d/conn6.cfg0000644000000000000000000000022012231434742015161 0ustar [conn6] DISABLED ENVFILE /etc/xymon/xymonserver.cfg CMD /usr/lib/xymon/server/ext/conn6 LOGFILE /var/log/xymon/xymonlaunch.log INTERVAL 5m hobbit-plugins/debian/0000755000000000000000000000000012231436130012107 5ustar hobbit-plugins/debian/README.Debian0000664000000000000000000001547612231434742014176 0ustar Xymon/Hobbit Plugins -------------------- This set of client and server plugins (scripts, extensions) is moderately tailored for Debian, but should be pretty usable on any *nix platform. Some plugins require additional packages installed. Included client plugins: * apt - check for outstanding updates Optional configuration files: /etc/xymon/apt_no_repo_accept - Packages not from repositories but ok. /etc/xymon/apt_reject - Packages which must not be installed at all. Both configuration files should have one package names matching Perl regular expression per line. The regular expression is implicitly surrounded by "^" and "$" so a line just containing "gnome" doesn't match most gnome packages but only the "gnome" meta package. Use ".*" at the end of the line to match multiple packages with the same prefix. Please note that this also means that you have to escape plus-signs ("+") in package names with backslash ("\"). See the example below. Example file: conkeror dphys-swapfile unburden-home-dir virtualbox-ose-modules-.* xlockmore-gl xscreensaver.* g\+\+ * bkpc - check hosts backed up with BackupPC Needs: backuppc, sudo Based on the nagios backuppc check at http://n-backuppc.cvs.sf.net/viewvc/n-backuppc/check_backuppc/check_backuppc?revision=1.21 In comparison to other included checks this one uses no special configuration files but needs to be configured via commandline options in /etc/xymon/clientlaunch.d/backuppc.cfg Run "/usr/lib/xymon/client/ext/backuppc --help" for available options. * dirtyetc - check for conffiles which are modified compared to Debian's defaults but should not be. Needs: sudo (recommended), debsums Configuration file: /etc/xymon/dirty_etc_ok - Which files are ok to be modified. The file should contain one path match Perl regular expression per line, with ^ and $ implied. Example file: /etc/xymon/clientlaunch.d/dirtyetc.cfg /etc/dphys-config /etc/unburden_home_dir.* * dirtyvcs - check for not checked in modifications or files in VCS repositories Needs: libfile-which-perl Also checks the consistency of (non-bare) git repositories. Configuration files: /etc/xymon/dirty_vcs_dirs - Where to look for repositories. .dirtyvcs_no_fsck (per git repository) .git/dirtyvcs_no_fsck (local per git repository) The file dirty_vcs_dirs should contain one directory path per line, wildcards allowed. In each of the matching directories, it looks for the typical subdirectories of the supported version control systems (for now Git, Mercurial, Bzr and Subversion) and queries the state of the repository. Example file: /etc /etc/* /etc/amavis/conf.d /opt /opt/* /opt/*/bin /opt/*/sbin /usr/local/bin /usr/local/sbin !/opt/test/bin Paths listed with a leading exclamation mark ("!") will be skipped. This allows system administrators to check for their repos, but skip users' repos. No wildcards supported there currently. The existence of a file named .dirtyvcs_no_fsck (per git repository, to be committed into the repository) or .git/dirtyvcs_no_fsck (local per working copy) prevents that dirtyvcs runs "git fsck" on the repository. This may be needed on big repositories where "git fsck" runs quite some time or needs too much RAM or I/O. * ipmi - read IPMI sensors and event log Needs: ipmitool * misc - plugin which can aggregate the output and states of other plugins Needs: libsysadm-install-perl * misc.d/zombies - Warns about processes in zombie state. Configuration file: /etc/xymon/zombies_ignore Text up to the first whitespace is considered a perl regular expression (with implicit ^…$ around) to match the name in the "Name" line of /proc/*/status. If the regular expression contains the string ":^" the text before this string is a regular expression matched against the user name of the owner of the process and the text behind is the actual regular expression matched against the zombie's program name. Use this to ignore e.g. ssh zombies only if they belong to a specific user. All text starting with the first non-whitespace after the first white space is considered the reason for whitelisting these zombie processes. Example file at /usr/share/doc/hobbit-plugins/examples/zombies_ignore * libs - check for running processes with upgraded libraries Needs: lsof, sudo * mailman - check for the existence of Mailman qfiles. Needs: sudo * mdstat - check for failed or resyncing software RAID devices * mq - checks (Postfix's) mail queue Checks at least Postfix's mail queue by parsing the mailq command's output. Patches to support other MTAs are welcome. Recognizes too many mails in the mailq as well as possible RBL issues. * misc - meta plugin for running series of scripts Needs: libsysadm-install-perl * ntpq - check the ntpd daemon synchronization status (needs ntp) * postgres - statistics graphs for postgresql databases Needs: libdbd-pg-perl * sftbnc - check if the local Postfix MTA has soft_bounce enabled. Included server plugins: * aptdiff - monitor list of installed packages in host pools * conn6 - check IPv6 connectivity Needs: fping Enable this test in /etc/xymon/xymonlaunch.d/conn6.cfg and add conn6 to the services of a host in bb-hosts and this script will ping6 the AAAA record of the given host. Alternatively you can add a comma separated list of IPv6 addresses or hostnames that resolve to IPv6 addresses as a parameter to conn6, to ping6 all these addresses. Examples: 10.1.2.3 foo # ftp conn6:2001:db8:1::42 10.1.2.4 bar # smtp conn6 10.1.2.5 baz # conn6:baz.example.com dialup 10.1.2.6 router # conn6:2001:db8:1::1,2001:db8:2::1 * ircbot - relay status changes to IRC Needs: libpoe-component-irc-perl * tftp - check downloading files from TFTP servers Needs: libnet-tftp-perl Enable this test in /etc/xymon/xymonlaunch.d/tftp.cfg and add tftp to the services of a host and this script will try to download the file /pxelinux.0 via TFTP from the given host. Alternatively you can add colon separated a file or path which should be used to test the TFTP server. Currently only one file per server can be tested. Examples: 10.1.2.3 foo # ftp tftp 10.1.2.4 bar # smtp tftp:bootmgr.exe 10.1.2.5 baz # tftp:/sparc.img More plugins: * Xymonton (formerly "The Shire"): http://xymonton.org/ * Many Big Brother plugins also run with Xymon: http://www.deadcat.net/ * The Xymon monitor itself can be found at http://xymon.sourceforge.net/ Feedback welcome, especially suggestions for new plugins - use the Debian BTS, or e-mail us at hobbit-plugins@packages.debian.org. -- Axel Beckert , Wed, 17 Jul 2013 14:14:36 +0200 hobbit-plugins/debian/control0000664000000000000000000000543212231434742013527 0ustar Source: hobbit-plugins Section: net Priority: extra Maintainer: Christoph Berg Uploaders: Axel Beckert Build-Depends: debhelper (>= 8.1.0~) Standards-Version: 3.9.4 Vcs-Git: git://anonscm.debian.org/collab-maint/hobbit-plugins.git Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/hobbit-plugins.git Homepage: http://xymon.sourceforge.net/ Package: hobbit-plugins Architecture: all Pre-Depends: dpkg (>= 1.15.7.2) Depends: xymon-client (>= 4.3.7-1~), ${misc:Depends} Recommends: dctrl-tools, libsysadm-install-perl, lsb-release, lsof, sudo (>= 1.7.2p1-1) Suggests: bzr, debsums, fping, git, ipmitool, libdbd-pg-perl, libfile-which-perl, libnet-tftp-perl, libpoe-component-irc-perl, mercurial, ntp, subversion Enhances: backuppc, dphys-config, mailman, postfix Description: plugins for the Xymon network monitor This package provides plugins for the Xymon network monitor. (Formerly called Hobbit.) . Included client plugins: * apt - check for outstanding updates * backuppc - check for errors reported by BackupPC servers (needs backuppc and sudo) * dirtyetc - check for conffiles which are modified compared to Debian's defaults but should not be (needs sudo and debsums, supports dphys-config) * dirtyvcs - check for dirty VCS working copies (supports Git, Mercurial, Bzr and Subversion, needs appropriate VCS packages and libfile-which-perl installed) * entropy - check kernel entropy pool size * ipmi - read IPMI sensors and event log (needs ipmitool) * libs - check for running processes with upgraded libraries (needs lsof and sudo) * mailman - checks the existence of Mailman shunt files and aged queue files. (needs sudo) * mdstat - check for failed or resyncing RAID devices * mq - check (postfix's) mail queue * misc - meta plugin for running series of scripts (needs libsysadm-install-perl) * ntpq - check the ntpd daemon synchronization status (needs ntp) * postgres - statistics graphs for PostgreSQL databases (needs libdbd-pg-perl) * sftbnc - check if the local Postfix MTA has soft_bounce enabled. * temp - simple temperature monitor . Included server plugins: * aptdiff - monitor list of installed packages in host pools * conn6 - check IPv6 connectivity (needs fping) * ircbot - relay status changes to IRC (needs libpoe-component-irc-perl) * pgbouncer - monitor pool usage and traffic * tftp - checks TFTP servers by downloading a file from them (needs libnet-tftp-perl) . Helper software: * Hobbit.pm: Perl module for writing plugins * xynagios: adaptor for running Nagios plugins with Xymon hobbit-plugins/debian/maintscript0000644000000000000000000000514111773324160014401 0ustar mv_conffile /etc/hobbit/hobbitgraph.d/entropy.cfg /etc/xymon/xymongraph.d/entropy.cfg 20120532 mv_conffile /etc/hobbit/hobbitgraph.d/postgres.cfg /etc/xymon/xymongraph.d/postgres.cfg 20120532 mv_conffile /etc/hobbit/hobbitserver.d/entropy.cfg /etc/xymon/xymonserver.d/entropy.cfg 20120532 mv_conffile /etc/hobbit/hobbitserver.d/postgres.cfg /etc/xymon/xymonserver.d/postgres.cfg 20120532 mv_conffile /etc/hobbit/hobbitserver.d/ircbot.cfg /etc/xymon/xymonserver.d/ircbot.cfg 20120532 mv_conffile /etc/hobbit/hobbitserver.d/conn6.cfg /etc/xymon/xymonserver.d/conn6.cfg 20120532 mv_conffile /etc/hobbit/dirty_etc_ok /etc/xymon/dirty_etc_ok 20120532 mv_conffile /etc/hobbit/misc.d/mount-ro /etc/xymon/misc.d/mount-ro 20120532 mv_conffile /etc/hobbit/misc.d/zombies /etc/xymon/misc.d/zombies 20120532 mv_conffile /etc/hobbit/hobbitlaunch.d/ircbot.cfg /etc/xymon/xymonlaunch.d/ircbot.cfg 20120532 mv_conffile /etc/hobbit/hobbitlaunch.d/conn6.cfg /etc/xymon/xymonlaunch.d/conn6.cfg 20120532 mv_conffile /etc/hobbit/hobbitlaunch.d/tftp.cfg /etc/xymon/xymonlaunch.d/tftp.cfg 20120532 mv_conffile /etc/hobbit/hobbitlaunch.d/aptdiff.cfg /etc/xymon/xymonlaunch.d/aptdiff.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/entropy.cfg /etc/xymon/clientlaunch.d/entropy.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/postgres.cfg /etc/xymon/clientlaunch.d/postgres.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/backuppc.cfg /etc/xymon/clientlaunch.d/backuppc.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/mq.cfg /etc/xymon/clientlaunch.d/mq.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/dirtyetc.cfg /etc/xymon/clientlaunch.d/dirtyetc.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/apt.cfg /etc/xymon/clientlaunch.d/apt.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/ntpq.cfg /etc/xymon/clientlaunch.d/ntpq.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/ipmi.cfg /etc/xymon/clientlaunch.d/ipmi.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/dirtyvcs.cfg /etc/xymon/clientlaunch.d/dirtyvcs.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/misc.cfg /etc/xymon/clientlaunch.d/misc.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/mdstat.cfg /etc/xymon/clientlaunch.d/mdstat.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/mailman.cfg /etc/xymon/clientlaunch.d/mailman.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/libs.cfg /etc/xymon/clientlaunch.d/libs.cfg 20120532 mv_conffile /etc/hobbit/clientlaunch.d/sftbnc.cfg /etc/xymon/clientlaunch.d/sftbnc.cfg 20120532 mv_conffile /etc/hobbit/dirty_vcs_dirs /etc/xymon/dirty_vcs_dirs 20120532 mv_conffile /etc/sudoers.d/hobbit /etc/sudoers.d/xymon 20120532 hobbit-plugins/debian/NEWS0000644000000000000000000000311212231436120012602 0ustar hobbit-plugins (20131022) unstable; urgency=low The dirtyvcs plugin now also runs "git fsck" by default on (non-bare) git repositories. This may cause quite some I/O or memory usage on big repositories (i.e. with several hundered MB in .git) and hence unwanted additional load on the system. You can disable the running of "git fsck" per repository by either creating an (possibly empty) file named ".dirtyvcs_no_fsck" in the repository (check it in or list it in .gitignore) or a file named ".dirtyvcs_no_fsck" inside the .git subdirectory (i.e. a file local to the working copy which is not checked in). -- Axel Beckert Wed, 12 Dec 2012 18:48:34 +0100 hobbit-plugins (20120531) unstable; urgency=low The included IRC bot has been migrated to use POE::Component::IRC instead of the unfortunately deprecated Net::IRC. You may need to install the appropriate dependencies (which are in the Suggests part of the package's dependencies). See http://bugs.debian.org/640209 for the discussion. As of this writing AutoJoin is activated, but does not seem to work. -- Axel Beckert Tue, 22 May 2012 11:38:05 +0200 hobbit-plugins (20110311) unstable; urgency=low To work properly the dirtyvcs check needs at least read access, in case of (at least) git also write access (for locking the repository) to the working copy. The libs check uses sudo now to gain root permissions. Newer kernel versions do not allow lsof anymore to access other users' file lists. -- Christoph Berg Fri, 11 Mar 2011 11:23:49 +0100 hobbit-plugins/debian/changelog0000664000000000000000000003651012231436122013771 0ustar hobbit-plugins (20131022) unstable; urgency=low [ Axel Beckert ] * Add script to automatically generate pre-4.3.7-1-compatible package if not built for the experimental distribution. * apt: + Properly handle cases where a package is installed in an extra architecture but not in the primary architecture. + Properly recognize security updates on Debian and Ubuntu + Checks for broken or unconfigured packages + Print distribution and release + Use less resource-hungry grep-dctrl instead of aptitude to check aptitude's hold states. Recommend dctrl-tools. + Support aptitude's "Forbid Version" feature. + Don't show "apt-get install" line for hold packages. + Ship /etc/apt/apt.conf.d/15hobbit-plugins-update-stamp and let APT touch /var/lib/apt/periodic/update-success-stamp after a successful update of the package lists. APT hook taken copied from update-notifier-common which uses the same stamp file, because we don't want to pull the full update-notifier-common just for that one-line configuration file. + Fix "dpkg-query -l" output filtering, add assertion warning. + Also warn if last update was in the "future". * Hobbit.pm: Add Hobbit::trends wrapper method. * Refactoring Perl code: + Always use three-argument open() and parentheses. + Prefer $ENV{XYMON} over other variants. + Consistently use "$ENV{XYMON}" instead of "xymon". * Update error messages to mention what couldn't be done with a file. * ircbot: + Reading from STDIN fixed. Was broken since the switch to POE. (Closes: #696156) + Now based on POE::Component::IRC::State instead of just POE::Component::IRC to make POE::Component::IRC::Plugin::AutoJoin properly. (Related to #696160) + Handle irc_disconnected event. (Finally closes: #696160) + Make default/example configuration conforming to RFC2606 * ntpq: + Catch case where /var/run/ntpd.pid does not exist. * misc.d/mount-ro: + Don't alarm for read-only NFS/NFSv4 or UDF mounts. + Make filesystem blacklist less false negative prone. * misc.d/zombies: + Only alarm if a zombie is a zombie 1 sec later. too. + Add script to generate a zombie to test misc.d/zombies. + Add optional zombies blacklist file. Install example zombie blacklist to /usr/share/doc/…/examples/. * mq: + Report and alarm about different Postfix queues separately. + Do not report RBL issues for fakemx.net and friends. + Exit silently if /usr/bin/mailq is not available. + Do not report "too busy" messages as RBL issues. + Create graphs of the different numbers. * tftp: + Make it work with Squeeze's version of Net::TFTP * dirtyvcs: + Now also runs git fsck on git repositories by default + Allow to skip single repositories by listing them with an exclamation mark prepended in dirty_vcs_dirs. + Now needs libfile-which-perl. * backuppc: + Show expected but not configured hosts clear instead of yellow. * mailman: + Report red on files in /var/lib/mailman/qfiles/shunt/, yellow for files in other subdirectories of /var/lib/mailman/qfiles/. + Only report queue files older than 5 minutes. * debian/control Vcs-* headers: Move from git.debian.org to anonscm.debian.org (Fixes lintian warnings vcs-field-not-canonical) * More hobbit → xymon renaming fixups: + conn6, tftp: bbhostgrep → xymongrep * Fix wrong method name in Hobbit.pm documentation. * Some reindenting and untabifying of Perl code. * Update copyright years. * Apply wrap-and-sort. [ Christoph Berg ] * Hobbit.pm: Accept both XYMON/XYMONSRV and BB/BBDISP environment variables. * Hobbit.pm: Add grep function wrapping xymongrep. * Hobbit.pm: Add graph method for showing more than one graph per test. * Hobbit.pm: Add sprintf method. * Hobbit.pm: Fix Hobbit::trends constructor. (Closes: #690768) * aptdiff: Modify aptdiff_ignore file to use "hostname pkg" patterns. * ipmi: Show more than the first line from "sel list". (Closes: #695785) * pgbouncer: New server-side script. * temp: New test graphing /sys/class/thermal/*/temp. * xynagios: Early strip test prefixes, otherwise errors get submitted with the long name. -- Christoph Berg Tue, 22 Oct 2013 10:50:15 +0200 hobbit-plugins (20120626) experimental; urgency=low * Follow Xymon's path changes from /etc/hobbit/ to /etc/xymon/ et al. + Remove alternative dependency on hobbit-plugins + Require xymon-client >= 4.3.7-1~ + Rename source directories hobbit*.d accordingly + Update postinst + Bump debhelper build-dependency to >= 8.1.0~ for the use of dpkg-maintscript-helper. * Drop alternative dependency on old transitional package git-core. -- Axel Beckert Tue, 26 Jun 2012 21:52:49 +0200 hobbit-plugins (20120531) unstable; urgency=low [ Axel Beckert ] * New client-side plugin "mq" to check (at least postfix) mail queues. (Disabled by default) * New client-side plugin "dirtyetc" to check for unexpected changes in conffiles. (Disabled by default) * Ported ircbot plugin from deprecated Net::IRC to POE::Component::IRC (Closes: #640209). AutoJoin is enabled, Flood protection disabled. * Updated debian/control and debian/README.Debian accordingly. * Hobbit.pm API change: - file_to_hash() renamed to file_to_list_of_regexps() and now returns an array instead of an hash - dirtyvcs' file_to_array() renamed to file_to_list_of_globs() and now exportable from Hobbit.pm - both functions now shift instead of pop from @_ * client/ext/mq: Don't report RBL issues just on "too many connections". * Bump Standards-Version to 3.9.3 (no changes) [ Christoph Berg ] * aptdiff: Read list of packages to ignore from /etc/hobbit/aptdiff_ignore. * apt: Handle :arch in the output of dpkg --get-selections. -- Christoph Berg Thu, 31 May 2012 00:58:27 +0200 hobbit-plugins (20111012) unstable; urgency=low * Hobbit.pm: New key dont_moan to disable moan and croak if a test needs a badly written third party library. * Hobbit.pm: More sanity checks for max_color(); * Hobbit.pm: Add Documentation as POD - Generate Hobbit.3pm man page out of Hobbit.pm * Move file_to_hash from client-ext/apt to Hobbit.pm * New client-side plugin backuppc based on the code of the backuppc nagios check from http://n-backuppc.sf.net/. Disabled by default. * New client-side plugin mailman which checks the existence of Mailman qfiles. Disabled by default. * New server-side plugin tftp based on the code of the conn6 plugin. Disabled by default. - Suggest libnet-tftp-perl which is needed by this test. * Fix bug in client-ext/apt which prohibited packages installed from local "deb file:///…" repository to be recognized as such. * Update some links in README.Debian. * Add /var/yp and /var/yp/ypfiles to /etc/hobbit/dirty_vcs_dirs. * Mention the plugins mdstat, misc and ntpq in README.Debian. * Bump Standards-Version to 3.9.2 (no changes) -- Axel Beckert Wed, 12 Oct 2011 00:17:57 +0200 hobbit-plugins (20110325) unstable; urgency=low [ Christoph Berg ] * sftbnc: Disable by default. * Hobbit.pm: Allow h/d/w suffix on status ttl. [ Axel Beckert ] * apt: - Now also understands "deb file:///…" apt repositories. - Remove some debug output which caused harm when the plugin was running standalone. * dirtyvcs: - Neither list subdirectories of Subversion repositories nor Git submodules. - Make VCS directories to check configurable. * libs: - Sync with http://cvs.noreply.org/cgi-bin/viewvc.cgi/trunk/nagios-check-libs?revision=474 - Gracefully handle not installed or non-working sudo and lsof. - Clarify severity of some messages by adding some more icons to the output. * debian/control: - Update package description to list dependencies of each plugin and the sftbnc plugin. - Recommend sudo >= 1.7.2p1-1 (where support for /etc/sudoers.d has been added) since the libs plugin (enabled by default) no more works without root rights. * README.Debian: Add more documentation. [ Roland Rosenfeld ] * conn6: Replace the shell script with a more featureful implementation in Perl. See the script source for documentation. (Closes: #614564) -- Axel Beckert Thu, 24 Mar 2011 22:46:37 +0100 hobbit-plugins (20110311) unstable; urgency=low [ Axel Beckert ] * Depend on xymon-client and only alternatively on the transitional package hobbit-client. * Move from Hg to Git (Vcs-* header in debian/control updated) * Update homepage to current Xymon homepage * Add new checks: + Check for dirty VCS working copies. Suggest the supported VCS packages (git, mercurial, bzr, subversion). + Check for Postfix soft_bounce being enabled (Closes: #570442) * Let Hobbit.pm support status+ syntax, add new optional attribute ttl. * Add a simple perl syntax checker as "make test" * Fix lintian warning maintainer-script-without-set-e. * Sort long package lists alphabetically. [ Christoph Berg ] * libs: Needs sudo for lsof now, put a config snippet in sudoers.d. -- Christoph Berg Fri, 11 Mar 2011 11:05:35 +0100 hobbit-plugins (20101207) experimental; urgency=low * ircbot: Fixed help command if prefixed with nick name * apt: Also check aptitude's hold states, not only dpkg's * apt: Use perl regexps in /etc/hobbit/apt_* * apt: Name configuration files and (internal) variables consistently. (/etc/hobbit/apt_no_repo_accept and /etc/hobbit/apt_reject) -- Axel Beckert Mon, 06 Dec 2010 21:32:37 +0100 hobbit-plugins (20101203) experimental; urgency=low * Add myself to Uploaders. * apt: Overhaul "last apt update" determining + Split up the list of update stamp files into two groups to reduce the amount of "Last apt update" false positives: - Files where each file indicates a successful update, just not necessarily the newest one. Check all of them and use the newest of them. (Closes: #605687) - Files which are less exact indicators. Check them in order and just use the first one found as before. + Check mtime of /var/cache/apt/pkgcache.bin, /var/lib/apt/lists/partial and /var/lib/apt/lists before checking the mtime of /var/lib/apt/lists/lock. (Closes: #526894) + Add patch by Emil Larsson for not-in-repo package whitelist (/etc/hobbit/apt_alien_accepts) as well as a rejected packages blacklist (/etc/hobbit/apt_rejects). (Closes: #487331) * ircbot: Forward-port nick-highlighting patch by Christian Herzog from ISG D-PHYS, ETH Zurich (Closes: #524016) * ircbot: Optionally use privmsg instead of notice for green and clear messages (set IRC_GREEN_PRIVMSG to 1) * Bump Standards-Version to 3.9.1 (no changes) * Switch to source format "3.0 (native)" -- Axel Beckert Fri, 03 Dec 2010 15:58:44 +0100 hobbit-plugins (20100527) unstable; urgency=low * ircbot: implement drop and ack commands. * apt: If /var/lib/apt/update_output exists, assume it contains errors from apt-get update -qq and print it. -- Christoph Berg Thu, 27 May 2010 13:01:14 +0200 hobbit-plugins (20100320) unstable; urgency=low * ircbot: improve messages a bit, and implement disable/enable commands. -- Christoph Berg Sat, 20 Mar 2010 20:35:03 +0100 hobbit-plugins (20091007) unstable; urgency=low * xynagios: Add --hostname, --strip, and --trends options. -- Christoph Berg Wed, 07 Oct 2009 16:09:58 +0200 hobbit-plugins (20090817) unstable; urgency=low * xynagios: adaptor for running Nagios plugins with Xymon. * misc: meta plugin for running series of scripts. + mount-ro: check for read-only filesystems. + zombies: check for zombie processes. * Hobbit.pm: Allow setting the report title line via $bb->{title}. * Recommends libsysadm-install-perl. * Remove Martin from Uploaders. * Bump Standards-Version and DH compat level. -- Christoph Berg Mon, 17 Aug 2009 09:34:33 +0200 hobbit-plugins (20090420) unstable; urgency=low * apt: Show number of outstanding upgrades; don't complain about held packages not coming from a repository. * mdstat: Monitor /proc/mdstat. * ircbot: Display acknowledgements. -- Christoph Berg Mon, 20 Apr 2009 18:03:02 +0200 hobbit-plugins (20080705) unstable; urgency=low [ Peter Eisentraut ] * ntpq: Give ntpq some time to initialize, so the test is not red just after boot. [ Christoph Berg ] * apt: Also look for /var/lib/apt/update_success. * entropy: Monitor and graph available kernel entropy. * ircbot: Show disable time and message when tests are set blue. * Remove `bb-check-' prefix from apt und libs plugin binaries. -- Christoph Berg Sat, 05 Jul 2008 16:03:53 +0200 hobbit-plugins (20080407) unstable; urgency=low [ Christoph Berg ] * bb-check-apt: Warn when installed packages have no corresponding apt repository. * postgres: Use PgCommon.pm to find active clusters for the latest PostgreSQL version installed and monitor all. Clusters not named "main" will be reported as clustername.domainname. [ Peter Eisentraut ] * bb-check-apt: Also check /var/lib/apt/periodic/update-stamp for last update timestamp, because some file systems don't update /var/lib/apt/lists/lock reliably. * Corrected spelling of PostgreSQL in package description and postgres.cfg. * Hobbit.pm: Added status synopsis to the title line after the date. * ntpq: New module for checking the ntpd daemon synchronization status. -- Christoph Berg Mon, 07 Apr 2008 13:17:10 +0200 hobbit-plugins (20080308) unstable; urgency=low * Hobbit.pm: Perl module for easier scripting. * aptdiff: Monitor differences in installed packages in host pools. * ipmi: Monitor IPMI sensors and event log. * ircbot: Do not announce unchanged status messages. * Add README.Debian. -- Christoph Berg Sat, 08 Mar 2008 01:27:48 +0100 hobbit-plugins (20080229) unstable; urgency=low * Add IRC bot plugin. -- Christoph Berg Sat, 01 Mar 2008 01:42:17 +0100 hobbit-plugins (20071222) unstable; urgency=low * Add postgres plugin (needs splitncv patch, included in hobbit >= 4.2.0.dfsg-9). -- Christoph Berg Sat, 22 Dec 2007 19:59:17 +0100 hobbit-plugins (20071101) unstable; urgency=low * Use hobbit init script to recreate include files. * Add conn6 server script. -- Christoph Berg Thu, 01 Nov 2007 21:38:00 +0100 hobbit-plugins (20070908) unstable; urgency=low * bb-check-libs: Format output over multiple lines, send clear instead of purple when lsof is missing. * bb-check-apt: print "apt-get install" for cut-and-paste, also print packages on hold. * Add Homepage: and Vcs-Hg:. -- Christoph Berg Sat, 08 Sep 2007 00:40:32 +0200 hobbit-plugins (20070823) unstable; urgency=low * bb-check-libs: Code restructured, handle lsof not found more nicely. * Fix postinst. * Section: net. -- Christoph Berg Thu, 23 Aug 2007 16:50:30 +0200 hobbit-plugins (20070819) unstable; urgency=low * Initial release. -- Christoph Berg Sun, 19 Aug 2007 14:32:59 +0200 hobbit-plugins/debian/copyright0000644000000000000000000000654312037520514014056 0ustar This package was debianized by Christoph Berg on Sun, 19 Aug 2007 14:51:46 +0200. Upstream authors and copyrights: bb-check-libs: # Copyright (C) 2005 Peter Palfrader # Porting to hobbit Copyright (C) 2007 Christoph Berg # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. bb-check-apt: # Copyright (C) 2007 Christoph Berg [Same license terms as bb-check-libs] conn6: # Copyright (C) 2011 Roland Rosenfeld # # 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 2 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. tftp: # Copyright (C) 2011 Roland Rosenfeld # Copyright (C) 2011-2012 Axel Beckert # # 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 2 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. backuppc: # Copyright (C) 2006, 2007 Seneca Cunningham # Copyright (C) 2011 Axel Beckert # # 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 2 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. On Debian systems the full text of the GPLv2 can be found under /usr/share/common-licenses/GPL-2. hobbit-plugins/debian/compat0000644000000000000000000000000211536366547013332 0ustar 7 hobbit-plugins/debian/postinst0000644000000000000000000000062012231434742013722 0ustar #!/bin/sh set -e case $1 in configure) if test -x /usr/lib/xymon/server/bin/xymond ; then if [ -x /usr/sbin/invoke-rc.d ] ; then invoke-rc.d xymon reload || : else /etc/init.d/xymon reload || : fi else if [ -x /usr/sbin/invoke-rc.d ] ; then invoke-rc.d xymon-client reload || : else /etc/init.d/xymon-client reload || : fi fi ;; esac #DEBHELPER# exit 0 hobbit-plugins/debian/TODO0000644000000000000000000000036112037520514012603 0ustar Currently missing: * ntpq plugin documentation in README.Debian * entropy plugin documentation in README.Debian * mdstat plugin documentation in README.Debian Move the following common config files if they exist: apt_no_repo_accept hobbit-plugins/debian/backport.sh0000755000000000000000000000543012064066147014270 0ustar #!/bin/sh set -e ALLFILES="*-ext/* *launch.d/*.cfg debian/README.Debian Makefile etc/dirty_etc_ok" if [ "$1" = "undo" ]; then prename -v 's/hobbit/xymon/g' *.d sudoers.d/* sed -e 's/^#Pre-Depends:/Pre-Depends:/g' -i debian/control sed -e 's/(<< 4.3.7-1~)/(>= 4.3.7-1~)/g' -i debian/control sed -e 's/hobbit/xymon/g' -i sudoers.d/* debian/postinst *-bin/* *launch.d/*.cfg sed -e 's/hobbitd/xymond/g' -i server-ext/ircbot *launch.d/ircbot.cfg client-bin/xynagios sed -e 's:hobbit\([a-z]*\).d:xymon\1.d:g' -i Makefile sed -e 's:/var/log/hobbit/:/var/log/xymon/:g' -i $ALLFILES sed -e 's:/var/lib/hobbit/:/var/lib/xymon/:g' -i $ALLFILES sed -e 's:/usr/lib/hobbit/:/usr/lib/xymon/:g' -i $ALLFILES sed -e 's:/etc/hobbit:/etc/xymon:g' -i $ALLFILES sed -e 's:sudoers.d/hobbit:sudoers.d/xymon:g' -i $ALLFILES sed -e 's:HOBBITCLIENTHOME:XYMONCLIENTHOME:g' -i $ALLFILES sed -e 's:BBHOME:XYMONHOME:g' -i server-ext/* sed -e 's:BBDISP:XYMSRV:g' -i server-ext/* sed -e 's:$ENV{BB}:$ENV{XYMON}:g' -i server-ext/* sed -e 's:BBSERVERHOSTNAME:XYMONSERVERHOSTNAME:g' -i server-ext/* sed -e 's:bbhostgrep:xymongrep:g' -i server-ext/* [ -e debian/maintscript.disabled ] && mv -v debian/maintscript.disabled debian/maintscript else [ -e debian/maintscript ] && mv -v debian/maintscript debian/maintscript.disabled sed -e 's:xymongrep:bbhostgrep:g' -i server-ext/* sed -e 's:XYMONSERVERHOSTNAME:BBSERVERHOSTNAME:g' -i server-ext/* sed -e 's:XYMONHOME:BBHOME:g' -i server-ext/* sed -e 's:XYMSRV:BBDISP:g' -i server-ext/* sed -e 's:$ENV{XYMON}:$ENV{BB}:g' -i server-ext/* sed -e 's:XYMONCLIENTHOME:HOBBITCLIENTHOME:g' -i $ALLFILES sed -e 's:sudoers.d/xymon:sudoers.d/hobbit:g' -i $ALLFILES sed -e 's:/etc/xymon:/etc/hobbit:g' -i $ALLFILES sed -e 's:/usr/lib/xymon/:/usr/lib/hobbit/:g' -i $ALLFILES sed -e 's:/var/lib/xymon/:/var/lib/hobbit/:g' -i $ALLFILES sed -e 's:/var/log/xymon/:/var/log/hobbit/:g' -i $ALLFILES sed -e 's:xymon\([a-z]*\).d:hobbit\1.d:g' -i Makefile sed -e 's/xymond/hobbitd/g' -i server-ext/ircbot *launch.d/ircbot.cfg client-bin/xynagios sed -e 's/xymon/hobbit/g' -i sudoers.d/* debian/postinst *-bin/* *launch.d/*.cfg sed -e 's/(>= 4.3.7-1~)/(<< 4.3.7-1~)/g' -i debian/control sed -e 's/^Pre-Depends:/#Pre-Depends:/g' -i debian/control prename -v 's/xymon/hobbit/g' *.d sudoers.d/* fi exit 0 hobbit-plugins/debian/source/0000755000000000000000000000000011536366547013434 5ustar hobbit-plugins/debian/source/format0000644000000000000000000000001511536366547014643 0ustar 3.0 (native) hobbit-plugins/debian/examples0000644000000000000000000000001212124313210013633 0ustar examples/*hobbit-plugins/debian/rules0000755000000000000000000000121312231435027013170 0ustar #!/usr/bin/make -f build-arch: build build-indep: #awk -F'[ ;]+' 'NR==1 {print $3}' debian/changelog | grep -iq experimental || debian/backport.sh $(MAKE) install: dh_testdir dh_testroot dh_prep $(MAKE) install DESTDIR=debian/hobbit-plugins binary-arch: binary binary-indep: install dh_installdocs dh_installexamples dh_installchangelogs dh_fixperms dh_compress dh_md5sums dh_installdeb dh_gencontrol dh_builddeb clean: dh_clean $(MAKE) clean #awk -F'[ ;]+' 'NR==1 {print $3}' debian/changelog | grep -iq experimental || debian/backport.sh undo .PHONY: build build-indep build-arch install binary binary-indep binary-arch clean hobbit-plugins/client-bin/0000755000000000000000000000000012231434742012720 5ustar hobbit-plugins/client-bin/xynagios0000775000000000000000000001271512231434742014517 0ustar #!/usr/bin/perl -w use strict; use Getopt::Long; use Hobbit; use Sysadm::Install qw(tap); sub usage () { print < usage: --hostname= Override hostname from environment. --strip= Remove this prefix from test names; "check_" is always removed. --trends Send performance data as a "data .trends" report --help --version Print this text EOT } my $params; Getopt::Long::config('bundling'); if (!GetOptions ( '--hostname=s' => \$params->{'hostname'}, '--strip=s' => \$params->{'strip'}, '--trends' => \$params->{'trends'}, '--help' => \$params->{'help'}, '--version' => \$params->{'help'},)) { usage (); exit (1); }; if ($params->{help}) { usage (); exit (0); } my $test = $ARGV[0]; $test =~ s!.*/!!; $test =~ s!\..*!!; $test =~ s/^check_//; $test =~ s/^$params->{strip}// if ($params->{strip}); my $bb = new Hobbit ({ test => $test, hostname => $params->{hostname} }); my ($stdout, $stderr, $exit_code) = tap (@ARGV); my ($exit, $signal) = ($exit_code >> 8, $exit_code & 0xff); if ($signal) { $bb->color_line ('red', "$test was killed by signal $signal, exit $exit\n"); } if ($exit > 2) { $bb->color_line ('red', "$test returned exit $exit\n"); } if ($stderr) { $bb->color_line ('red', "Stderr output:\n$stderr"); } if ($exit == 2) { $bb->add_color ('red'); } elsif ($exit == 1) { $bb->add_color ('yellow'); } else { $bb->add_color ('green'); } if ($stdout =~ s/^(\S+) +(OK|WARNING|CRITICAL|ERROR|UNKNOWN): *//s) { $bb->{title} = "$1 $2"; $bb->{test} = lc ($1); } $bb->{test} =~ s/^check_//; $bb->{test} =~ s/^$params->{strip}// if ($params->{strip}); my $trends; if ($params->{trends}) { $trends = new Hobbit ({ type => 'data', test => 'trends', hostname => $params->{hostname} }); } # | time=0.02 postgres=4583020 template0=4349956 template1=4349956 my ($performance, $time); if ($stdout =~ s/\s+\|\s+(.*)//) { my @values = split (/\s+/, $1); foreach my $value (@values) { unless ($value =~ /(.*)=(.*)/) { #warn "Missing = in performance value $value\n"; next; } my ($label, @figures) = ($1, split (/;/, $2)); $label =~ s/^'|'$//g; if ($label eq 'time') { # do not treat 'time' as performance data $time = shift (@figures); next; } my $value = shift (@figures); $performance .= "$label : $value"; my $warn = shift @figures; $performance .= " warn $warn" if $warn; my $crit = shift @figures; $performance .= " crit $crit" if $crit; my $min = shift @figures; $performance .= " min $min" if $min; my $max = shift @figures; $performance .= " max $max" if $max; $performance .= "\n"; if ($params->{trends}) { $trends->print ("[$bb->{test},$label.rrd]\n"); $trends->print ("DS:lambda:GAUGE:600:U:U $value\n"); } } } $bb->print ($stdout); $bb->print ("\nPerformance data:\n$performance") if $performance; $bb->print ("\ntime $time") if $time; $bb->send; if ($params->{trends}) { $trends->send; } =pod =head1 NAME B - adaptor for using Nagios checks with Xymon =head1 SYNOPSIS B [I --] I [I] =head1 DESCRIPTION B runs a Nagios check, and reports its output in a way compatible with the Xymon (Hobbit, BB) monitoring system. The Xymon test name is taken from the plugin output if it starts with I IB<:>. Otherwise, the basename of the plugin filename is used. A B prefix is removed for brevity. =head1 OPTIONS =over =item B<--hostname=>I Report tests as this host. =item B<--strip=>I Remove I (regexp) from test names. The prefix "check_" is always removed before stripping other prefixes. Useful for trimming down overly verbose Nagios test names, e.g. "check_postgres_database_size" to "database_size". =item B<--trends> In addition to printing performance data in the status report (suitable for the NCV/SPLITNCV xymond_rrd modules), send in a data report for IB<.trends>. This rrd module is more robust. =item B<--help> =item B<--version> Print help text and version, and exit. =back =head1 SEE ALSO xymon(7), xymon(1), xymoncmd(1), nagios3(8). =head1 AUTHOR Christoph Berg =head1 LICENSE AND COPYRIGHT Copyright (c) Christoph Berg Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =cut hobbit-plugins/xymonserver.d/0000755000000000000000000000000012074001355013512 5ustar hobbit-plugins/xymonserver.d/postgres.cfg0000644000000000000000000000052511773324160016052 0ustar TEST2RRD="$TEST2RRD,postgres=ncv,pgblk=ncv,pglck=ncv,pgscn=ncv,pgtbl=ncv,pgtpl=ncv,pgxlg=ncv" SPLITNCV_postgres="*:GAUGE" SPLITNCV_pgblk="*:DERIVE" SPLITNCV_pglck="*:GAUGE" SPLITNCV_pgscn="*:DERIVE" SPLITNCV_pgtbl="*:DERIVE" SPLITNCV_pgtpl="*:DERIVE" SPLITNCV_pgxlg="*:DERIVE" GRAPHS="$GRAPHS,postgres,pgblk,pglck,pgscn,pgtbl,pgtpl,pgxlg" hobbit-plugins/xymonserver.d/pgbouncer.cfg0000644000000000000000000000007312057115411016157 0ustar TEST2RRD="$TEST2RRD,pgbouncer" GRAPHS="$GRAPHS,pgbouncer" hobbit-plugins/xymonserver.d/entropy.cfg0000644000000000000000000000012011773324160015673 0ustar TEST2RRD="$TEST2RRD,entropy=ncv" NCV_entropy="*:GAUGE" GRAPHS="$GRAPHS,entropy" hobbit-plugins/xymonserver.d/temp.cfg0000644000000000000000000000006012074001355015134 0ustar TEST2RRD="$TEST2RRD,temp" GRAPHS="$GRAPHS,temp" hobbit-plugins/xymonserver.d/ircbot.cfg0000644000000000000000000000216612037520514015464 0ustar # Configuration for the Xymon IRC bot # Where to connect to (port 6667, no SSL by default) IRC_SERVER="irc.example.net" #IRC_PORT="6667" #IRC_SSL=0 # Which channel to join IRC_CHANNEL="#somechannel" # Our nick - $MACHINE might or might not be a good default IRC_NICK="$MACHINE" # The IRC user name (the thing in front of @ in userhost, defaults to xymon) #IRC_USER="xymon" # The Ircname (also known as realname) # Note: please be so polite to fill in your nick here so people can contact you # in case the bot gets crazy IRC_IRCNAME="Xymon monitor bot run by Someowner" # The bot will ignore all requests not coming from nick!user@host pattern that # do not match this (^anchored$) Perl regexp (if unset, .* is assumed) IRC_ACCESS="Somenick!.*@.*" # IRC nicks that should be alerted when certain machines have a problem #ALERT_NICKS="adminnick1, adminnick2" #ALERT_HOSTS="server1 server2 someotherimportanthost" # Don't alert for these tests #ALERT_IGNORE="apt ntp ntpq someotherservice" # Uncomment to make "green" and "clear" messages go to the channel # like all other messages instead of being sent as notice. #IRC_GREEN_PRIVMSG=1 hobbit-plugins/xymonserver.d/conn6.cfg0000644000000000000000000000003711773324160015225 0ustar TEST2RRD="$TEST2RRD,conn6=tcp" hobbit-plugins/client-ext/0000755000000000000000000000000012231434742012750 5ustar hobbit-plugins/client-ext/backuppc0000755000000000000000000001725612231434742014501 0ustar #!/usr/bin/perl -w # a Hobbit/Xymon plugin to check the status of BackupPC # # Based on http://n-backuppc.cvs.sf.net/viewvc/n-backuppc/check_backuppc/check_backuppc?revision=1.21 # # Tested against BackupPC 2.1.2 and 3.1.0 # # # Copyright (C) 2006, 2007 Seneca Cunningham # Copyright (C) 2011 Axel Beckert # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # my $config = "/etc/backuppc/TODO"; use strict; use lib '/usr/share/backuppc/lib/'; use BackupPC::Lib; use Hobbit; $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $bb = new Hobbit({ test => 'bkpc', dont_moan => 1}); #no utf8; my %ERRORS = ( OK => 0, UNKNOWN => 1, WARNING => 1, CRITICAL => 2 ); use POSIX qw(strftime difftime); use Getopt::Long; Getopt::Long::Configure('bundling'); # BackupPC my $version = '1.1.0'; my $warnLevel = 0; my $daysOld = 7; my $verbose = 1; my $opt_V = 0; my $opt_h = 0; my $goodOpt = 0; my $reduce = 0; my $backupOnly = 0; my $archiveOnly = 0; my $statusOnly = 0; my @hostsDesired; my @hostsExcluded; # Process options $goodOpt = GetOptions( 'v+' => \$verbose, 'verbose+' => \$verbose, 'c=f' => \$daysOld, 'critical=f' => \$daysOld, 'w=f' => \$warnLevel, 'warning=f' => \$warnLevel, 'V' => \$opt_V, 'version' => \$opt_V, 'h' => \$opt_h, 'help' => \$opt_h, 'r=i' => \$reduce, 'reduce' => \$reduce, 'b' => \$backupOnly, 'backup-only' => \$backupOnly, 'a' => \$archiveOnly, 'archive-only' => \$archiveOnly, 's' => \$statusOnly, 'status-only' => \$statusOnly, 'H=s' => \@hostsDesired, 'hostname=s' => \@hostsDesired, 'x=s' => \@hostsExcluded, 'exclude=s' => \@hostsExcluded); @hostsDesired = () if $#hostsDesired < 0; @hostsExcluded = () if $#hostsExcluded < 0; if ($opt_V) { print "check_backuppc - " . $version . "\n"; exit $ERRORS{'OK'}; } if ($backupOnly and $archiveOnly) { $goodOpt = 0; print "Cannot apply both --backup-only and --archive-only, contradictory\n\n"; } if ($opt_h or not $goodOpt) { print "check_backuppc - " . $version . "\n"; print "A Hobbit plugin to check on BackupPC backup status.\n\n"; print "Options:\n"; print " --hostname,-H only check the specified host\n"; print " --exclude,-x do not check the specified host\n"; print " --archive-only,-a only check the archive hosts\n"; print " --backup-only,-b only check the backup hosts\n"; print " --status-only,-s only check backup status, omit connection failures that are\n"; print " less than \$Conf{FullPeriod} old\n"; print " --warning,-w days old an errored host must be to cause a warning\n"; print " --critical,-c number of days old an errored backup must be to be critical\n"; print " --reduce,-r maximum number of failed hosts for severity reduction\n"; print " --verbose,-v increase verbosity\n"; print " --version,-V display plugin version\n"; print " --help,-h display this message\n\n"; exit $ERRORS{'OK'} if $goodOpt; exit $ERRORS{'UNKNOWN'}; } if ($warnLevel > $daysOld) { $bb->color_line('red', "CONFIGURATION ERROR - Warning threshold must be <= critical\n"); } # Connect to BackupPC my $server; if (!($server = BackupPC::Lib->new)) { $bb->color_line('red', "Couldn't connect to BackupPC\n"); $bb->send; exit $ERRORS{'CRITICAL'}; } my %Conf = $server->Conf(); $server->ChildInit(); my $err = $server->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}); if ($err) { $bb->color_line('red', "Can't connect to server ($err)\n"); $bb->send; exit $ERRORS{'UNKNOWN'}; } # hashes that BackupPC uses for varios status info my %Status; my %Jobs; my %Info; # query the BackupPC server for host, job, and server info my $info_raw = $server->ServerMesg('status info'); my $jobs_raw = $server->ServerMesg('status jobs'); my $status_raw = $server->ServerMesg('status hosts'); # undump the output... BackupPC uses Data::Dumper eval $info_raw; eval $jobs_raw; eval $status_raw; # check the dumped output my $hostCount = 0; my @goodHost; my @badHost; my @tooOld; my @notTooOld; # host status checks foreach my $host (sort(keys(%Status))) { next if $host =~ /^ /; next if (@hostsDesired and not grep {/$host/} @hostsDesired); next if (@hostsExcluded and grep {/$host/} @hostsExcluded); next if ($backupOnly and $Status{$host}{'type'} eq 'archive'); next if ($archiveOnly and $Status{$host}{'type'} ne 'archive'); $hostCount++; # Debug if ($verbose == 3) { $bb->print("Host $host state " . $Status{$host}{'state'}); $bb->print(" with error: " . $Status{$host}{'error'} . "\n"); } if ($Status{$host}{'error'}) { # Check connectivity errors with greater care if ($statusOnly && ( $Status{$host}{'error'} eq 'ping too slow' || $Status{$host}{'error'} eq 'no ping response' || $Status{$host}{'error'} eq 'host not found')) { if ($Status{$host}{'lastGoodBackupTime'} - $Status{$host}{'startTime'} <= $Conf{FullPeriod} * 3600 * 24) { push @goodHost, $host; next; } } push @badHost, $host; # Check bad host ages $Status{$host}{'lastGoodBackupTime'} = $Status{$host}{'startTime'} if (not $Status{$host}{'lastGoodBackupTime'}); if (difftime(time(), $Status{$host}{'lastGoodBackupTime'}) > ($daysOld * 3600 * 24)) { push @tooOld, $host; } elsif (difftime(time(), $Status{$host}{'lastGoodBackupTime'}) > ($warnLevel * 3600 * 24)) { push @notTooOld, $host; } else { push @goodHost, $host; pop @badHost; } # Debug if ($verbose == 2) { $bb->print("Host $host state " . $Status{$host}{'state'}); $bb->print(" with error: " . $Status{$host}{'error'} . "\n"); } } else { push @goodHost, $host; } } if ($hostCount == @goodHost or $#badHost < $reduce and not @tooOld) { $bb->color_line('green', "BackupPC OK - (" . @badHost . "/" . $hostCount . ") failures\n"); &list_unknown_hosts; $bb->send; exit $ERRORS{'OK'}; } &list_unknown_hosts; # Only failures reach this far # WARNING if ($#tooOld < 0 or $#badHost < $reduce) { #print "BACKUPPC WARNING - ("; if ($verbose) { foreach my $host (@badHost) { $bb->color_line('yellow', $host . " (" . $Status{$host}{'error'} . ")\n"); } #print ")\n"; } else { $bb->color_line('yellow', $#badHost + 1 . "/" . $hostCount . ") failures\n"); } $bb->send; exit $ERRORS{'WARNING'}; } # CRITICAL #print "BACKUPPC CRITICAL - ("; if ($#notTooOld >= 0 and $verbose) { foreach my $host (@notTooOld) { $bb->color_line('red', $host . " (" . $Status{$host}{'error'} . ")\n"); } #print "), ("; } if ($verbose) { foreach my $host (@tooOld) { $bb->color_line('red', $host . " (" . $Status{$host}{'error'} . ")\n"); } #print ") critical\n"; } else { $bb->print($#badHost + 1 . "/" . $hostCount . ") failures, "); $bb->print(print $#tooOld + 1 . " critical\n"); } $bb->send; exit $ERRORS{'CRITICAL'}; sub list_unknown_hosts { foreach my $host (@hostsDesired, @hostsExcluded) { if (not grep {/$host/} keys(%Status)) { $bb->color_line('clear', "Host expected but not configured ($host)\n"); #exit $ERRORS{'UNKNOWN'}; } } } hobbit-plugins/client-ext/dirtyetc0000755000000000000000000001056112231434742014530 0ustar #!/usr/bin/perl -w # Copyright (C) 2010-2012 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. my $ext_etc_config = "/etc/xymon"; use strict; use Hobbit qw(file_to_list_of_regexps); my $dirty_etc_ok_file = $ext_etc_config."/dirty_etc_ok"; my $dphys_config_list = "/etc/dphys-config.list"; my @dirty_etc_ok = file_to_list_of_regexps($dirty_etc_ok_file); my @dphys_config_ok = (); my $DEBSUMS = '/usr/bin/debsums'; my $SUDO = '/usr/bin/sudo'; $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $bb = new Hobbit('dirtyetc'); ### ### Checks for sudo and debsums ### if (!-x $SUDO) { $bb->color_line ('yellow', "$SUDO not found or not executable. This dirtyetc check should run debsums with root rights. See the file /etc/sudoers.d/xymon for how debsums would be run with root rights via sudo. "); $SUDO = ''; } if (!-x $DEBSUMS) { $bb->color_line ('rot', "$DEBSUMS not found or not executable. This dirtyetc plugin has been enabled, but debsums seems not installed. This plugin depends on debsums. "); $bb->send(); exit 0; } ### ### Parse dphys-config.list ### if (-e $dphys_config_list) { if (!-r $dphys_config_list) { $bb->color_line('yellow', "$dphys_config_list exists, but is not readable\n"); } else { open(my $dpc_fh, '<', $dphys_config_list) or croak("Assertion: $dphys_config_list readable but I still can't open it? WTF!"); while (my $dpc_line = <$dpc_fh>) { chomp($dpc_line); # Ignore blank lines, comment lines and files which are to # be deleted by dphys-config next if $dpc_line =~ /^#|^\s*$|^-:/; my ($filename, $destination, $trigger) = split(/:/, $dpc_line); if (-d $destination) { if ($destination =~ m(/$)) { push(@dphys_config_ok, qr(^$destination$filename$)); } else { push(@dphys_config_ok, qr(^$destination/$filename$)); } } elsif (-f $destination) { push(@dphys_config_ok, qr(^$destination$)); } else { # We can ignore non-existent files, can we? } } } } ### ### Call debsums ### my $command = "$DEBSUMS -ec 2>&1"; open(my $debsums_fh, '-|', "$SUDO $command") or die "Can't execute $SUDO $command"; my @changed_conffiles = <$debsums_fh>; close($debsums_fh); chomp(@changed_conffiles); my (@ok, @ok_dpc, @bad, @bad_config); foreach my $changed_conffile (@changed_conffiles) { # Check if that's ok if ($changed_conffile =~ /Permission denied/) { push(@bad_config, $changed_conffile); } elsif (grep { $changed_conffile =~ $_ } @dirty_etc_ok) { push(@ok, $changed_conffile); } elsif (grep { $changed_conffile =~ $_ } @dphys_config_ok) { push(@ok_dpc, $changed_conffile); } else { push(@bad, $changed_conffile); } } show_file_list('yellow', 'dirtyetc plugin configuration issues', @bad_config); show_file_list('yellow', 'Configuration files which are modified but should not be', @bad); show_file_list('green', 'Configuration files which are ok to be modified', @ok); show_file_list('green', 'Configuration files which are modified, but distributed via dphys-config', @ok_dpc); ### ### Finally send the result ### $bb->send; ### ### Subroutines ### sub show_file_list { my ($color, $info, @list) = @_; return unless @list; $bb->color_line($color, "$info:\n\n"); foreach my $filename (@list) { $bb->print(" $filename\n"); } $bb->print("\n"); } hobbit-plugins/client-ext/sftbnc0000755000000000000000000000347612231434742014167 0ustar #!/usr/bin/perl -w # Copyright (C) 2007, 2008 Christoph Berg # Copyright (C) 2010 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use strict; use Hobbit; $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; exit 0 unless -x '/usr/sbin/postfix'; my $bb = new Hobbit('sftbnc'); my $maincf = '/etc/postfix/main.cf'; if (open(MAIN, '<', $maincf)) { my $softbounce = 0; while ($_ =
) { next if /^\#/; $softbounce = 1 if /^\s*soft_bounce\s*=\s*yes\b/i; } close(MAIN); $bb->color_line($softbounce ? 'yellow' : 'green', "Postfix soft_bounce is ".($softbounce ? 'on' : 'off')); } else { $bb->color_line('yellow', "Postfix seems to be installed but I can't open $maincf: $!"); } $bb->send; hobbit-plugins/client-ext/temp0000755000000000000000000000103712231434742013644 0ustar #!/usr/bin/perl use strict; use warnings; use Hobbit; my $bb = new Hobbit('temp'); my $trends = Hobbit::trends; my @zones = glob "/sys/class/thermal/*/temp"; exit 0 unless (@zones); $bb->add_color ('green'); foreach my $zone (@zones) { open F, $zone; my $temp = ; close F; chomp $temp; $zone =~ m!.*/(.+)/!; my $name = $1; $bb->sprintf ("%s: %.1f degrees C\n", $name, $temp / 1000.0); $trends->print ("[$bb->{test},$name.rrd]\n"); $trends->sprintf ("DS:temp:GAUGE:600:U:U %f\n", $temp / 1000.0); } $bb->send; $trends->send; hobbit-plugins/client-ext/libs0000755000000000000000000001146112231434742013632 0ustar #!/usr/bin/perl -w # Copyright (C) 2005, 2006, 2007, 2008 Peter Palfrader # Porting to hobbit Copyright (C) 2007 Christoph Berg # Copyright (C) 2011 Axel Beckert # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. use strict; use English; use Hobbit; $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $LSOF = '/usr/bin/lsof'; my $SUDO = '/usr/bin/sudo'; my $bb = new Hobbit ('libs'); ################### Kernel my $current = `uname -r`; chomp $current; my $installed = readlink "/vmlinuz"; $installed =~ s!.*vmlinuz-!! if $installed; if ($installed and ($current ne $installed)) { $bb->color_line ('yellow', "Machine should be rebooted, newer kernel is installed: $current $installed\n\n"); } my $curconfig = "/proc/config.gz"; my $instconfig = "/boot/config-$current"; if (-e $curconfig and -e $instconfig) { system "zdiff -q $curconfig $instconfig > /dev/null"; if ($? >> 8 != 0) { $bb->color_line ('yellow', "Machine should be rebooted, kernel configs $curconfig and $instconfig differ\n\n"); } } else { $bb->color_line ('clear', "One of $curconfig and $instconfig was not found, cannot check kernel uptodateness\n\n"); } ################### my %processes; sub getPIDs($$) { my ($user, $process) = @_; return join(' ', sort keys %{ $processes{$user}->{$process} }); }; sub getProcs($) { my ($user) = @_; return join("\n", map { " $_ (".getPIDs($user, $_).')' } (sort {$a cmp $b} keys %{ $processes{$user} })); }; sub getUsers() { return join("\n", (map { "$_:\n".getProcs($_) } (sort {$a cmp $b} keys %processes))); }; sub inVserver() { my ($f, $key); if (-e "/proc/self/vinfo" ) { $f = "/proc/self/vinfo"; $key = "XID"; } else { $f = "/proc/self/status"; $key = "s_context"; }; open(F, '<', $f) or return 0; while () { my ($k, $v) = split(/: */, $_, 2); if ($k eq $key) { close F; return ($v > 0); }; }; close F; return 0; } my $INVSERVER = inVserver(); if (!-x $SUDO or !-x $LSOF) { $bb->color_line ('clear', "$SUDO and/or $LSOF not found or not executable. This library check needs lsof to be run with root rights. See the file /etc/sudoers.d/xymon for how lsof would be run with root rights via sudo. "); $bb->send; exit 0 } if (!-e '/etc/sudoers.d/README') { $bb->color_line ('yellow', "sudo seems to be installed, but an older version without support for files in /etc/sudoers.d/. Please add the contents of /etc/sudoers.d/xymon to /etc/sudoers and create /etc/sudoers.d/README to disable this warning: cat /etc/sudoers.d/xymon >> /etc/sudoers echo See /usr/lib/xymon/client/ext/libs >> /etc/sudoers.d/README "); } unless (open(LSOF, '-|', "$SUDO $LSOF -n 2> /dev/null")) { $bb->color_line ('red', "Cannot run $LSOF -n: $!\n"); $bb->send; exit; } my @lsof=; close LSOF; if ($CHILD_ERROR) { # program failed $bb->color_line ('red', "$LSOF -n returned with non-zero exit code: ".($CHILD_ERROR / 256)."\n"); $bb->send; exit; }; for my $line (@lsof) { my ($process, $pid, $user, $fd, undef, undef, undef, $path, $rest) = split /\s+/, $line; if ($line =~ m/\.dpkg-/ || $line =~ m/path inode=/ || $fd eq 'DEL') { next if $path =~ m#^/proc/#; next if $path =~ m#^/var/tmp/#; next if $path =~ m#^/SYS#; next if $path =~ m#^/drm$#; # xserver stuff next if $path =~ m#^/dev/zero#; next if ($INVSERVER && ($process eq 'init') && ($pid == 1) && ($user eq 'root')); #$processes{$user}->{$process} = [] unless defined $processes{$user}->{$process}; $processes{$user}->{$process}->{$pid} = 1; }; }; my $libmsg; if (keys %processes) { $bb->color_line ('yellow', "The following processes have libs linked that were upgraded:\n\n". getUsers() . "\n"); } else { $bb->color_line ('green', "No upgraded libs linked in running processes\n"); }; $bb->add_color ('green'); $bb->send; hobbit-plugins/client-ext/mq0000775000000000000000000001123512231434742013317 0ustar #!/usr/bin/perl -w # Copyright (C) 2010-2013 Axel Beckert # # Based on the generic hobbit plugin template by Christoph Berg. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use strict; use Hobbit; # Configuration my %threshold_yellow = ( active => 100, deferred => 50 ); my %threshold_red = ( active => 500, deferred => 250 ); my $recipients_factor = 10; # Initialisation $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $mailq = '/usr/bin/mailq'; exit 0 unless -x $mailq; my $bb = new Hobbit('mq'); my $data = Hobbit::trends(); my %qflag = ( ' ' => 'deferred', '*' => 'active', '!' => 'hold', ); my @mailq = `$mailq`; my %queue = (); my %queue_size = map { $_ => 0 } values %qflag; my %queue_mails = map { $_ => 0 } values %qflag; my %queue_recipients = map { $_ => {} } values %qflag; my $current_qid = undef; my $current_queue = undef; # Parsing mailq output and counting foreach my $mqline (@mailq) { if ($mqline =~ /^([0-9A-F]+)([ !*]?)\s+(\d+)\s+(\S+\s+\S+\s+\d+\s+\d+:\d+:\d+)\s+(.+)$/) { my ($qid, $qfl, $size, $date, $from) = ($1, $2, $3, $4, $5); $current_qid = $qid; $current_queue = $qflag{$qfl}; $queue{$qid} = { 'queue' => $current_queue, 'size' => $size, 'reason' => '', }; # accounting $queue_size{$current_queue} += $size; $queue_mails{$current_queue}++; next; } # reason if ($mqline =~ /^\s*\((.+)\)$/) { my $reason = $1; $queue{$current_qid}{'reason'} = $reason; next; } # recipients if ($mqline =~ /^\s+(.+)$/) { $queue_recipients{$current_queue}{$1} = 1; next; } } # Threshold checks and colors $bb->print("\n"); # Handle active and deferred queues according to given thresholds foreach my $q (qw(active deferred)) { $bb->color_line($queue_mails{$q} > $threshold_yellow{$q} ? $queue_mails{$q} > $threshold_red{$q} ? 'red' : 'yellow' : 'green', sprintf("%5i mails in $q queue\n", $queue_mails{$q})); my $qr = keys %{$queue_recipients{$q}}; $bb->color_line($qr > $threshold_yellow{$q} * $recipients_factor ? $qr> $threshold_red{$q} * $recipients_factor ? 'red' : 'yellow' : 'green', sprintf("%5i recipients in $q queue\n", $qr)); } my $qr = keys %{$queue_recipients{hold}}; # If there's any mail hold, then there's something to do => yellow my $hold_color = $queue_mails{hold} ? 'yellow' : 'green'; $bb->color_line($hold_color, sprintf("%5i mails in hold queue\n", $queue_mails{hold})); $bb->color_line($hold_color, sprintf("%5i recipients in hold queue\n", $qr)); my $mailqfooter = $mailq[-1]; $mailqfooter =~ s/^-- (\d+ \w+ in )(\d+)( Requests?\.)$/$1$2$3/i; my $mails_overall = $2 || 0; $bb->sprintf("\nAll Postfix mail queues together: %i recipients and $mailqfooter\n", keys(%{$queue_recipients{active}}) + keys(%{$queue_recipients{deferred}}) + $qr); # Checking for RBL issues foreach my $qid (sort keys %queue) { next if $queue{$qid}{queue} eq 'hold'; my $reason = $queue{$qid}{reason}; if ($reason =~ /refused to talk to me/ and $reason !~ /too many connections/i and $reason !~ /too busy/i and $reason !~ /fakemx/i) { $bb->color_line('yellow', "Possible RBL issues: $reason\n"); } } # Data for graphs foreach my $type (qw(mails recipients)) { $data->print("[mq,$type.rrd]\n"); foreach my $q (qw(active deferred hold)) { $data->print("DS:$q$type:GAUGE:600:U:U $queue_mails{$q}\n"); $data->print("DS:$q$type:GAUGE:600:U:U ".keys(%{$queue_recipients{$q}})."\n"); } } $bb->graph('mq_mails'); $bb->graph('mq_recipients'); $bb->send; $data->send; hobbit-plugins/client-ext/postgres0000755000000000000000000001366512231434742014557 0ustar #!/usr/bin/perl -w # Plugin for monitor postgres connections. # # Licenced under GPL v2. # # You must also activate Postgresql statistics. See # http://www.postgresql.org/docs/8.1/interactive/monitoring-locks.html # for how to enable this. Specifically, the following lines must # exist in your postgresql.conf: # # stats_start_collector = true # stats_block_level = true use strict; use DBI; use DBD::Pg; use Hobbit; use lib '/usr/share/postgresql-common'; use PgCommon; my $version = PgCommon::get_newest_version () or die "no postgres version found"; my @clusters = PgCommon::get_version_clusters ($version) or die "no postgres/$version clusters found"; foreach my $cluster (@clusters) { my $clustername = `hostname -f`; chomp $clustername; $clustername =~ s/[^.]*\./$cluster./ if ($cluster ne "main"); my $bb = new Hobbit ({ hostname => $clustername, test => 'postgres', text => "Connections to cluster $version/$cluster:\n" }); my $socketdir = PgCommon::get_cluster_socketdir ($version, $cluster); my $port = PgCommon::get_cluster_port ($version, $cluster); my %dbh; $dbh{'postgres'} = DBI->connect ("DBI:Pg:dbname=postgres;host=$socketdir;port=$port", "", "", {RaiseError => 1}) || die; my $sql = "SELECT datname, count (pg_stat_activity.datname) FROM pg_database LEFT JOIN pg_stat_activity USING (datname) WHERE datallowconn AND datname <> 'template1' GROUP BY datname ORDER BY datname"; my $sth = $dbh{'postgres'}->prepare($sql); $sth->execute(); my @db = (); while ( my ($dbname, $curr_conn) = $sth->fetchrow_array ) { $bb->color_print ('green', "$dbname : $curr_conn\n"); # GAUGE push @db, $dbname; } $bb->send; foreach my $dbname (@db) { next if $dbname eq 'postgres'; my $bb = new Hobbit ("bbpostgres"); # dummy to catch connection errors $dbh{$dbname} = DBI->connect ("DBI:Pg:dbname=$dbname;host=$socketdir;port=$port", "", "", {RaiseError => 1}) || die ""; } ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pgtbl', text => "Table activity on cluster $version/$cluster:\n" }); # DERIVE foreach my $dbname (@db) { $bb->print ("\n"); my $sql = "SELECT SUM(n_tup_ins), SUM(n_tup_upd), SUM(n_tup_del) FROM pg_stat_user_tables"; my $sth = $dbh{$dbname}->prepare($sql); $sth->execute(); my ($n_tup_ins, $n_tup_upd, $n_tup_del) = $sth->fetchrow(); $bb->color_print ('green', "${dbname}_delete : $n_tup_del\n") if ($n_tup_del); $bb->color_print ('green', "${dbname}_insert : $n_tup_ins\n") if ($n_tup_ins); $bb->color_print ('green', "${dbname}_update : $n_tup_upd\n") if ($n_tup_upd); } $bb->send; ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pgtpl', text => "Tuple reads on cluster $version/$cluster:\n" }); # DERIVE foreach my $dbname (@db) { $bb->print ("\n"); my $sql = "SELECT SUM(seq_tup_read), SUM(idx_tup_fetch) FROM pg_stat_user_tables"; my $sth = $dbh{$dbname}->prepare($sql); $sth->execute(); my ($seq_tup_read,$idx_tup_fetch) = $sth->fetchrow(); $bb->color_print ('green', "${dbname}_idx_fetch : $idx_tup_fetch\n") if ($idx_tup_fetch); $bb->color_print ('green', "${dbname}_seq_read : $seq_tup_read\n") if ($seq_tup_read); } $bb->send; ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pgscn', text => "Scans initiated on cluster $version/$cluster:\n" }); # DERIVE foreach my $dbname (@db) { $bb->print ("\n"); my $sql = "SELECT SUM(seq_scan), SUM(idx_scan) FROM pg_stat_user_tables"; my $sth = $dbh{$dbname}->prepare($sql); $sth->execute(); my ($seq_scan,$idx_scan) = $sth->fetchrow(); $bb->color_print ('green', "${dbname}_idx_scan : $idx_scan\n") if ($idx_scan); $bb->color_print ('green', "${dbname}_seq_scan : $seq_scan\n") if ($seq_scan); } $bb->send; ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pgblk', text => "Cache blocks on cluster $version/$cluster:\n" }); # DERIVE foreach my $dbname (@db) { $bb->print ("\n"); my $sql = "SELECT blks_read, blks_hit FROM pg_stat_database WHERE datname='$dbname'"; my $sth = $dbh{$dbname}->prepare($sql); $sth->execute(); my ($blks_read,$blks_hit) = $sth->fetchrow(); $bb->color_print ('green', "${dbname}_blks_hit : $blks_hit\n") if ($blks_hit); $bb->color_print ('green', "${dbname}_blks_read : $blks_read\n") if ($blks_read); #my $read_hitratio = $blks_read+$blks_hit != 0 ? sprintf "%.2f", ($blks_hit/($blks_read+$blks_hit))*100 : 100; #$out .= "${dbname}_read_hitratio : $read_hitratio\n"; # GAUGE } $bb->send; ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pgxlg', text => "Xlog activity on cluster $version/$cluster:\n" }); #DERIVE foreach my $dbname (@db) { $bb->print ("\n"); my $sql = "SELECT xact_commit, xact_rollback FROM pg_stat_database WHERE datname='$dbname'"; my $sth = $dbh{$dbname}->prepare($sql); $sth->execute(); my ($curr_xact_commit,$curr_xact_rollback) = $sth->fetchrow(); $bb->color_print ('green', "${dbname}_commit : $curr_xact_commit\n") if ($curr_xact_commit); $bb->color_print ('green', "${dbname}_rollback : $curr_xact_rollback\n") if ($curr_xact_rollback); } $bb->send; ############## $bb = new Hobbit ({ hostname => $clustername, test => 'pglck', text => "Locks on cluster $version/$cluster:\n" }); #GAUGE foreach my $dbname (@db) { $bb->print ("\n"); my $sql="SELECT mode, COUNT(mode) FROM pg_locks GROUP BY mode ORDER BY mode"; my $sth = $dbh{$dbname}->prepare ($sql); $sth->execute (); my $locks = 0; my $exlocks = 0; while (my ($mode, $count) = $sth->fetchrow ()) { if ($mode =~ /exclusive/i) { $exlocks = $exlocks + $count; } $locks = $locks+$count; } $bb->color_print ('green', "${dbname}_exlocks : $exlocks\n") if ($exlocks); $bb->color_print ('green', "${dbname}_locks : $locks\n") if ($exlocks); } $bb->send; ############## foreach my $dbname (@db) { $dbh{$dbname}->disconnect; } } hobbit-plugins/client-ext/entropy0000755000000000000000000000357712231434742014412 0ustar #!/usr/bin/perl # A Hobbit client-side module to check the available kernel entropy. # Copyright (C) 2008 Christoph Berg # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use warnings; use strict; use Hobbit; my $loop = 10; # sample this many counts my $delay = 2; # sleep 2s before each sample my $bb = new Hobbit('entropy'); my $entropy = 0; for (1 .. $loop) { sleep $delay; open(F, '<', '/proc/sys/kernel/random/entropy_avail') or exit; $entropy += ; chomp $entropy; close F; } $entropy = sprintf "%d", $entropy / $loop; $bb->print ("Kernel entropy pool\n\n"); if ($entropy >= 200) { $bb->color_line ('green', "$entropy bits available - ok\n\n"); } elsif ($entropy >= 100) { $bb->color_line ('yellow', "$entropy bits available - low\n\n"); } else { $bb->color_line ('red', "$entropy bits available - very low\n\n"); } $bb->print ("entropy : $entropy\n"); $bb->send; hobbit-plugins/client-ext/ipmi0000755000000000000000000000173712231434742013644 0ustar #!/usr/bin/perl # A simple IPMI sensor and event log monitor # Either a) chmod +r /dev/ipmi0 b) chmod u+s ipmitool c) allow xymon to use sudo: # hobbit ALL=(root) SETENV:NOPASSWD: /usr/bin/ipmitool sdr # hobbit ALL=(root) SETENV:NOPASSWD: /usr/bin/ipmitool sel list last 50 #my $IPMI='sudo /usr/local/lib/bb-sudo/ipmitool'; my $IPMI='ipmitool'; use warnings; use strict; use Hobbit; my $bb = new Hobbit ('ipmi'); $bb->print ("Sensor Data Repository:\n"); foreach my $line (`$IPMI sdr 2>&1`) { if($line =~ /ok$/) { $bb->color_line ('green', $line); } elsif($line =~ /ns$/) { $bb->color_line ('clear', $line); } elsif($line =~ /Could not open device|Get Device ID command failed|Error obtaining SDR|Unable to open/) { $bb->color_line ('yellow', $line); # probably we just couldn't read /dev/ipmi0 } else { $bb->color_line ('red', $line); } } $bb->print ("\nIPMI event log (newest 50):\n"); my $sel = `$IPMI sel list last 50 2>&1`; $bb->print ($sel); $bb->send; hobbit-plugins/client-ext/mailman0000775000000000000000000000517612231434742014327 0ustar #!/usr/bin/perl -w # # Xymon/Hobbit/BigBrother test which checks the existence of Mailman # "shunt" qfiles which e.g. let mailman package upgrades on Debian # fail and can cause quite some issues if you handle such a failed # package upgrade wrongly. # # Copyright (C) 2011-2013 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use strict; use Hobbit; my $qfilesdir = '/var/lib/mailman/qfiles'; my $limit = 300; # Seconds # Setup environment $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; # Do nothing if mailman doesn't seem to be installed. exit 0 unless -d $qfilesdir; # Setup Hobbit test my $bb = new Hobbit('mailman'); my $now = time(); # Check if we can access all potential files if (opendir(QFILES, $qfilesdir)) { while (my $dir = readdir(QFILES)) { next if $dir =~ /^\./; -r "$qfilesdir/$dir" or $bb->color_line('yellow', "Can't read $qfilesdir/$dir!\n"); my @qfiles = grep { !/^\./ } glob("$qfilesdir/$dir/*"); if (@qfiles) { $bb->print("Found Mailman queue files in $qfilesdir/$dir:\n
");

	    foreach my $file (@qfiles) {
		if ($dir eq 'shunt') {
		    $bb->color_line('red', "$file: ".localtime((stat($file))[9]));
		} else {
		    my $stat = (stat($file))[9];
		    my $color = $now-$stat > $limit ? 'yellow' : 'green';
		    $bb->color_line($color, "$file: ".localtime($stat));
		}
	    }
	    $bb->print("
\n"); } else { $bb->color_line('green', "No Mailman queue files found in $qfilesdir/$dir/.\n"); } } closedir(QFILES); } else { $bb->color_line('yellow', "Can't read $qfilesdir: $!\n"); } $bb->send; hobbit-plugins/client-ext/apt0000775000000000000000000002502312231434742013466 0ustar #!/usr/bin/perl -w # Copyright (C) 2007-2012 Christoph Berg # Copyright (C) 2009-2010 Emil Larsson # Copyright (C) 2010-2012 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. my $ext_apt_config = "/etc/xymon"; use strict; use IPC::Open3; use Hobbit qw(file_to_list_of_regexps); my $security_regexp = qr(/updates(?:/|$)|-security(?:/|$)); my $no_repo_accept_file = $ext_apt_config."/apt_no_repo_accept"; my $reject_file = $ext_apt_config."/apt_reject"; my @no_repo_accept = file_to_list_of_regexps($no_repo_accept_file); my @reject = file_to_list_of_regexps($reject_file); my $arch = `dpkg --print-architecture`; chomp($arch); $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $bb = new Hobbit('apt'); if (-x '/usr/bin/lsb_release' and open(P, '-|', '/usr/bin/lsb_release -d -s')) { $bb->print (

); close P; } elsif (open(F, '<', "/etc/debian_version")) { my $version = ; chomp $version; $bb->print ("Debian version $version\n"); close F; } my %packages; my %forbidden_version; open(P, '-|', "dpkg --get-selections") or die "Couldn't execute dpkg --get-selections: $!"; while (

) { if (/^(\S+)\s+(\S+)/) { # pkg[:arch] install/hold/... next unless $2 eq "install" or $2 eq "hold"; $packages{$1} = $2; } } close P; if (-x '/usr/bin/aptitude' and -r '/var/lib/aptitude/pkgstates') { if (-x '/usr/bin/grep-dctrl') { # Find aptitude's holds my $command = 'grep-dctrl -s Package -n -F State 2 /var/lib/aptitude/pkgstates'; open(P, '-|', $command) or die "Couldn't execute $command: $!"; while (

) { chomp; $packages{$_} = 'hold'; } close P; # Find aptitude's forbidden versions $command = 'grep-dctrl -s Package,ForbidVer -F ForbidVer -e . /var/lib/aptitude/pkgstates'; open(P, '-|', $command) or die "Couldn't execute $command: $!"; my $current_pkg = undef; while (

) { chomp; next unless $_; my ($key, $value) = split(/: /); if ($key eq 'Package') { $current_pkg = $value; } elsif ($key eq 'ForbidVer') { $forbidden_version{$current_pkg} = $value; } else { die "Don't know how to parse '$_'!"; } } close P; } else { my $command = 'grep -c "^State: 2" /var/lib/aptitude/pkgstates'; open(P, '-|', $command) or die "Couldn't execute $command: $!"; my $holds_found =

; close P; my $warning_text = 'Warning: Package dctrl-tools seems not installed. Therefore no checking for packages set on hold via aptitude is done'; if ($holds_found > 0) { $bb->color_line('yellow', "$warning_text, but hold packages are present."); } else { $bb->print("$warning_text.\n"); } } } my %package_state = (); open(P, '-|', "dpkg-query -l") or die "Couldn't execute dpkg-query -l: $!"; while (

) { next if /^Desired=|^\||^\+/; my ($state, $pkg, $version, $desc) = split(); warn "Couldn't find package name in line: $_" unless $pkg; # dpkg's hold states are fine, too. See # http://bugs.debian.org/137771 for the aptitude' vs dpkg's hold # states issue. unless (/^ii|^rc|^hi/) { $package_state{$pkg} = "$_"; } } close P; my $pid = open3(\*IN, \*P, \*ERR, qw/xargs -r apt-cache policy/); die "open3: $!" unless $pid; if (!fork()) { close P; foreach my $p (sort keys %packages) { print IN "$p\n"; } close IN; exit 0; } close IN; close ERR; my ($pkg, $inst, $cand, $pin, $pinprio, $in_dist, $dist, $has_repo); my (@up, @upgrades, @sec, @security, @holdupgrades, @holdsecurity, @no_repo, @no_repo_pinned, @no_repo_accepted, @rejected, @broken); sub try_pkg () { unless (exists $packages{$pkg}) { if (exists $packages{"$pkg:$arch"}) { $pkg .= ":$arch"; } } if ($inst ne "(none)" and grep { $pkg =~ $_ } @reject) { push @rejected, "$pkg ($inst)"; return } if (exists $package_state{$pkg}) { my ($state, $pkg, $version, $desc) = split(/\s+/, $package_state{$pkg}); push @broken, "$state $pkg ($version)"; } if ($inst ne "(none)" and not $has_repo) { if (defined $pin and $pinprio > 0) { push @no_repo_pinned, "$pkg ($inst) $pinprio"; } elsif ($packages{$pkg} and $packages{$pkg} eq "hold") { push @no_repo_pinned, "$pkg ($inst) hold"; } else { if (grep { $pkg =~ $_ } @no_repo_accept) { push @no_repo_accepted, "$pkg ($inst)"; } else { push @no_repo, "$pkg ($inst)"; } } } return if $inst eq $cand; # Check for hold packages if ($packages{$pkg} eq "hold") { if ($dist and $dist =~ $security_regexp) { push @holdsecurity, "$pkg ($inst $cand)"; } else { push @holdupgrades, "$pkg ($inst $cand)"; } return; } # Check for forbidden versions if (exists($forbidden_version{$pkg}) and $forbidden_version{$pkg} eq $cand) { if ($dist and $dist =~ $security_regexp) { push @holdsecurity, "$pkg ($inst $cand) candidate version forbidden"; } else { push @holdupgrades, "$pkg ($inst $cand) candidate version forbidden"; } return; } # Updates available and wanted if ($dist and $dist =~ $security_regexp) { push @sec, $pkg; push @security, "$pkg ($inst $cand)"; } else { push @up, $pkg; push @upgrades, "$pkg ($inst $cand)"; } } while (

) { if (/^(\S+):/) { my $next_pkg = $1; try_pkg () if $pkg; $pkg = $next_pkg; undef $dist; undef $has_repo; undef $pin; undef $pinprio; } $inst = $1 if / +Installed: (.+)/; $cand = $1 if / +Candidate: (.+)/; $pin = $1 if / +Package pin: (.+)/ and $1 eq $inst; if (/^[ *]+(\S+) (\d+)$/) { $in_dist = ($1 eq $cand); $pinprio = $2; } if ($in_dist and /^ +\d+ \S+ (\S+)/) { # 700 http://localhost lenny/main Packages $dist .= "$1 "; $has_repo = 1 if m( (https?|ftp)://| file:); } } try_pkg (); close P; waitpid $pid, 0; sub pkgreport($$\@;\@) { my ($title, $color, $longlist, $shortlist) = @_; if (@{$longlist}) { $bb->print("\n"); my $number = scalar @{$longlist}; $bb->color_line($color, "$title ($number):"); $bb->print(' apt-get install ' . join (' ', @{$shortlist})) if $shortlist; $bb->print("\n"); foreach (sort @{$longlist}) { $bb->print(" $_\n"); } } } pkgreport('Rejected packages', 'red', @rejected); pkgreport('Security updates', 'red', @security, @sec); pkgreport('Broken or unconfigured packages', 'yellow', @broken); pkgreport('Other updates', 'yellow', @upgrades, @up); pkgreport('Security updates on hold', 'green', @holdsecurity); pkgreport('Other updates on hold', 'green', @holdupgrades); pkgreport('Packages not installed from apt repositories', 'yellow', @no_repo); pkgreport('Pinned/held packages not installed from apt repositories', 'green', @no_repo_pinned); pkgreport('Accepted packages not installed from apt repositories', 'green', @no_repo_accepted); $bb->print("\n"); # apt-get update will also exit with status 0 on some errors, and # /var/lib/apt/lists/lock will be updated in any case. We suggest to use # something like the following in /etc/cron.d/: # 44 */4 * * * root apt-get update -qq > /var/lib/apt/update_output 2>&1 && [ ! -s /var/lib/apt/update_output ] && date -u > /var/lib/apt/update_success # stamp files which should be all checked, take the newest one as # time-stamp for the last update. my @stamp_files_check_all = qw( /var/lib/apt/update_success /var/lib/apt/periodic/update-success-stamp /var/lib/apt/periodic/update-stamp ); # stamp files in order of decreasing usefulness, just check the first # one found and only if none of the files mentioned above were found. my @stamp_files_check_first = qw( /var/lib/apt/lists /var/lib/apt/lists/partial /var/cache/apt/pkgcache.bin /var/lib/apt/lists/lock ); my $last_update = 'never'; foreach my $stamp_file (@stamp_files_check_all) { my $last_update_tmp = -M $stamp_file; if ($last_update_tmp and ($last_update eq 'never' or $last_update_tmp < $last_update)) { $last_update = $last_update_tmp; } } if ($last_update eq 'never') { foreach my $stamp_file (@stamp_files_check_first) { if (-e $stamp_file) { $last_update = -M _; last } } } my $updatecolor; if ($last_update eq 'never' or $last_update >= 7) { $updatecolor = 'red'; } elsif ($last_update >= 1.5 or $last_update < 0) { $updatecolor = 'yellow'; } else { $updatecolor = 'green'; } $bb->color_line($updatecolor, "Last apt update: ". ($last_update eq 'never' ? 'never' : sprintf("%.1f day(s) ago\n", $last_update))); # If /var/lib/apt/update_output is present, print its content my $outputfile = '/var/lib/apt/update_output'; if (-s $outputfile) { $bb->print("\n"); my $mtime = scalar localtime((stat $outputfile)[9]); $bb->color_line('red', "Errors from $mtime:\n"); open(F, '<', $outputfile) or die "Can't read from $outputfile: $!"; while () { $bb->print(" $_"); } close F; } $bb->send; hobbit-plugins/client-ext/dirtyvcs0000775000000000000000000001044712231434742014555 0ustar #!/usr/bin/perl -w # Copyright (C) 2010-2013 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. my $ext_vcs_config = "/etc/xymon"; use strict; use Hobbit qw(file_to_list_of_globs); use File::Which; my $dirty_vcs_dirs_file = $ext_vcs_config."/dirty_vcs_dirs"; my $dirty_vcs_fsck_skip = 'dirtyvcs_no_fsck'; my @possible_repos = file_to_list_of_globs($dirty_vcs_dirs_file); $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin'; $ENV{'LC_ALL'} = 'C'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $bb = new Hobbit('dirtyvcs'); my $empty_re = qr/^\s*$/s; my %vcs_to_dir = ( 'git' => { dir => '.git', clean => qr/nothing to commit \(working directory clean\)/ }, 'bzr' => { dir => '.bzr', clean => $empty_re }, 'hg' => { dir => '.hg', clean => $empty_re }, 'svn' => { dir => '.svn', clean => $empty_re }, ); my @blacklist = map { s/^!//; $_ } grep { /^!/ } @possible_repos; my $repos_found = 0; foreach my $vcs (sort keys %vcs_to_dir) { my $vcs_avail = which($vcs); foreach my $path (sort @possible_repos) { foreach my $repo (sort grep { -d "$_/$vcs_to_dir{$vcs}{dir}" and !-d "$_/../$vcs_to_dir{$vcs}{dir}" } glob("$path")) { next if grep { $_ eq $repo } @blacklist; $repos_found++; if ($vcs_avail) { chdir($repo); my $status = `$vcs status 2>&1`; if ($status =~ $vcs_to_dir{$vcs}{clean} and $status =~ /warning|permission denied|fatal|abort|unable/i) { $bb->color_line('yellow', "$repo ($vcs) is clean, but has warnings or errors:\n". "

$status
"); } elsif ($status =~ $vcs_to_dir{$vcs}{clean}) { $bb->color_line('green', "$repo ($vcs) is clean". ($vcs_to_dir{$vcs}{clean} eq $empty_re ? ".\n" : ":\n
$status
")); } else { $bb->color_line('yellow', "$repo ($vcs) is dirty:\n". "
$status
"); } if ($vcs eq 'git' and !-e "$repo/.$dirty_vcs_fsck_skip" and !-e "$repo/.git/$dirty_vcs_fsck_skip") { # Options --no-dangling and --no-progress unknown in Squeeze my $status = `git fsck 2>&1 | egrep -v 'Checking|dangling' 2>&1`; if ($status =~ /missing|broken/) { $bb->color_line('red', "fsck for $repo ($vcs) failed:\n". "
$status
"); } elsif ($status) { $bb->color_line('yellow', "fsck for $repo ($vcs) found issues:\n". "
$status
"); } } } else { $bb->color_line('yellow', "$repo ($vcs) exists, but $vcs seems not installed.\n"); } } } } if ($repos_found) { $bb->print("\n$repos_found VCS repositories found."); } else { $bb->color_line('green', "No VCS repositories found."); } $bb->send; hobbit-plugins/client-ext/ntpq0000755000000000000000000000472212231434742013665 0ustar #!/usr/bin/perl # A Hobbit client-side module to check the local ntpd daemon # synchronization status. Not to be confused with the built-in "ntp" # test, which checks the ntpd server remotely. # Copyright (C) 2008 Peter Eisentraut # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use warnings; use strict; use Hobbit; if (! -x '/usr/bin/ntpq' and system('ntpq -? >/dev/null 2>&1') != 0) { exit 0; } my $bb = new Hobbit('ntpq'); my $ntpd_pid_file = '/var/run/ntpd.pid'; $bb->print("NTP peers:\n\n"); my $found_syspeer = 0; my $recently_started = 0; my $initializing = 0; if (-f $ntpd_pid_file) { $recently_started = (time - (stat($ntpd_pid_file))[9]) < 300; } else { $bb->color_line('yellow', "ntpd pid file $ntpd_pid_file not found. Is ntpd running?\n\n"); } my @output = `ntpq -np 2>&1` or die; foreach my $line (@output) { if ($line =~ /^ / or $line =~ /^==/) { $bb->print(' ' . $line); } elsif ($line =~ /^\*/) { $bb->color_line('green', $line); $found_syspeer = 1; } elsif ($line =~ /^( |x|\.|\-|\+|\#|o)/) { $bb->color_line('clear', $line); $initializing = 1 if $line =~ /\.INIT\.|\.STEP\./; } else { $bb->color_line('yellow', $line); } } if (!$found_syspeer) { $bb->print("\n"); if ($recently_started and $initializing) { $bb->color_line('yellow', "No system peer entry (\"*\") found; ntpd was recently started and is initializing.\n"); } else { $bb->color_line('red', "No system peer entry (\"*\") found\n"); } } $bb->send; hobbit-plugins/client-ext/misc0000755000000000000000000000133412231434742013632 0ustar #!/usr/bin/perl -w use strict; use Sysadm::Install qw/tap/; use Hobbit; my $bb = new Hobbit ('misc'); my @tests = sort grep { /\/[a-zA-Z0-9_-]+$/ } glob "/etc/xymon/misc.d/*"; foreach my $test (@tests) { next unless -x $test; my ($stdout, $stderr, $rc) = tap($test); $rc >>= 8; $test =~ /\/([a-zA-Z0-9_-]+)$/; my $name = $1; my $color = ($rc == 0 and not $stderr) ? 'green' : (($rc == 1 and not $stderr) ? 'yellow' : 'red'); $bb->color_line($color, $name . ($rc ? " returned $rc" : '') . (($stdout or $stderr) ? ':' : '') ."\n"); if ($stdout) { $stdout =~ s/^/ /mg; $bb->print ($stdout); } if ($stderr) { $stderr =~ s/^/ /mg; $bb->print ($stderr); } } $bb->send unless ($bb->{color} eq 'clear'); hobbit-plugins/client-ext/mdstat0000755000000000000000000000146512231434742014200 0ustar #!/usr/bin/perl -w # Monitor devices in /proc/mdstat # Test will go red when a disk has failed (F) or is not usable [_] #Personalities : [raid1] #md7 : active raid1 dm-51[0] dm-32[1] # 1953118336 blocks [2/2] [UU] # #md4 : active raid1 dm-22[0] dm-44[1] # 1953118336 blocks [2/2] [UU] # [=======>.............] resync = 37.6% (735336064/1953118336) finish=527.5min speed=38470K/sec #md2 : active raid1 dm-36[0] dm-28[1] # 42328960 blocks [2/2] [UU] # #unused devices: use strict; use Hobbit; my $bb = new Hobbit ('mdstat'); open(MDSTAT, '<', "/proc/mdstat") or die "Can't read from /proc/mdstat: $!"; while () { my $color = 'clear'; $color = 'green' if /\[U+\]/; $color = 'red' if /\(F\)/ or /\[U*_U*\]/; $bb->color_line ($color, $_); } close MDSTAT; $bb->send; hobbit-plugins/clientlaunch.d/0000755000000000000000000000000012231434742013567 5ustar hobbit-plugins/clientlaunch.d/postgres.cfg0000644000000000000000000000022112231434742016111 0ustar [postgres] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/postgres LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/ntpq.cfg0000644000000000000000000000021212231434742015225 0ustar [ntpq] #DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/ntpq LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/backuppc.cfg0000644000000000000000000000025612231434742016043 0ustar [bkpc] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD /usr/bin/sudo -E -u backuppc $XYMONCLIENTHOME/ext/backuppc -v LOGFILE /var/log/xymon/xymonclient.log INTERVAL 15m hobbit-plugins/clientlaunch.d/apt.cfg0000644000000000000000000000021012231434742015025 0ustar [apt] #DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/apt LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/misc.cfg0000644000000000000000000000021112231434742015175 0ustar [misc] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/misc LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/mq.cfg0000644000000000000000000000020512231434742014662 0ustar [mq] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/mq LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/entropy.cfg0000644000000000000000000000021712231434742015750 0ustar [entropy] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/entropy LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/ipmi.cfg0000644000000000000000000000021112231434742015200 0ustar [ipmi] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/ipmi LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/temp.cfg0000644000000000000000000000021112231434742015207 0ustar [temp] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/temp LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/dirtyetc.cfg0000644000000000000000000000022112231434742016072 0ustar [dirtyetc] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/dirtyetc LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/libs.cfg0000644000000000000000000000021212231434742015174 0ustar [libs] #DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/libs LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/dirtyvcs.cfg0000644000000000000000000000022112231434742016112 0ustar [dirtyvcs] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/dirtyvcs LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/sftbnc.cfg0000644000000000000000000000021512231434742015525 0ustar [sftbnc] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/sftbnc LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/mdstat.cfg0000644000000000000000000000021512231434742015542 0ustar [mdstat] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD $XYMONCLIENTHOME/ext/mdstat LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/clientlaunch.d/mailman.cfg0000644000000000000000000000025012231434742015663 0ustar [mailman] DISABLED ENVFILE /etc/xymon/xymonclient.cfg CMD /usr/bin/sudo -E -u list $XYMONCLIENTHOME/ext/mailman LOGFILE /var/log/xymon/xymonclient.log INTERVAL 5m hobbit-plugins/Makefile0000644000000000000000000000317512231434742012342 0ustar ETCFILES = dirty_vcs_dirs dirty_etc_ok APTCONFFILES = 15hobbit-plugins-update-stamp ETCDIRS = clientlaunch.d misc.d xymongraph.d xymonlaunch.d xymonserver.d EXTDIRS = client-ext server-ext MANS = xynagios.1 Hobbit.3pm all: $(MANS) xynagios.1: client-bin/xynagios pod2man $< > $@ Hobbit.3pm: perl/Hobbit.pm pod2man --section=3pm $< > $@ install: $(MANS) for dir in $(ETCDIRS) ; do \ dest=$(DESTDIR)/etc/xymon/$$dir && \ install -d $$dest && \ install -m644 $$dir/* $$dest || exit 1 ; \ done for file in $(ETCFILES) ; do \ dest=$(DESTDIR)/etc/xymon && \ install -d $$dest && \ install -m644 etc/$$file $$dest || exit 1 ; \ done for file in $(APTCONFFILES) ; do \ dest=$(DESTDIR)/etc/apt/apt.conf.d && \ install -d $$dest && \ install -m644 etc/apt.conf.d/$$file $$dest || exit 1 ; \ done chmod 755 $(DESTDIR)/etc/xymon/misc.d/* for dir in $(EXTDIRS) ; do \ dest=$(DESTDIR)/usr/lib/xymon/`basename $$dir -ext`/ext && \ install -d $$dest && \ install $$dir/* $$dest || exit 1; \ done dest=$(DESTDIR)/usr/lib/xymon/client/bin && \ install -d $$dest && \ install client-bin/* $$dest dest=$(DESTDIR)/etc/sudoers.d && \ install -d $$dest && \ install sudoers.d/* $$dest install -d $(DESTDIR)/usr/share/perl5 install -m644 perl/* $(DESTDIR)/usr/share/perl5 install -d $(DESTDIR)/usr/share/man/man1 install -d $(DESTDIR)/usr/share/man/man3 install -m644 xynagios.1 $(DESTDIR)/usr/share/man/man1 install -m644 Hobbit.3pm $(DESTDIR)/usr/share/man/man3 clean: rm -f $(MANS) test: for i in `egrep -l '^#! ?/usr/bin/perl' *-ext/* | egrep -v 'misc|postgres|~$$'` perl/*.pm; do perl -Iperl -c $$i; done hobbit-plugins/etc/0000755000000000000000000000000012231434742011447 5ustar hobbit-plugins/etc/dirty_etc_ok0000644000000000000000000000007112231434742014047 0ustar /etc/xymon/clientlaunch.d/dirtyetc.cfg /etc/dphys-config hobbit-plugins/etc/apt.conf.d/0000755000000000000000000000000012055133132013372 5ustar hobbit-plugins/etc/apt.conf.d/15hobbit-plugins-update-stamp0000644000000000000000000000014412055133132021012 0ustar APT::Update::Post-Invoke {"touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";}; hobbit-plugins/etc/dirty_vcs_dirs0000644000000000000000000000027511773324160014427 0ustar # dirtyvcs xymon-/hobbit-plugin: Where to look for VCS repositories /etc /etc/* /etc/amavis/conf.d /opt /opt/* /opt/*/bin /opt/*/sbin /usr/local/bin /usr/local/sbin /var/yp /var/yp/ypfiles hobbit-plugins/xymongraph.d/0000755000000000000000000000000012074001355013305 5ustar hobbit-plugins/xymongraph.d/postgres.cfg0000644000000000000000000000427611773324160015654 0ustar [postgres] FNPATTERN postgres,(.*).rrd TITLE PostgreSQL connections YAXIS Connections DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgtbl] FNPATTERN pgtbl,(.*).rrd TITLE PostgreSQL table activity YAXIS Rows DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgtpl] FNPATTERN pgtpl,(.*).rrd TITLE PostgreSQL tuples activity YAXIS Tuples DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgscn] FNPATTERN pgscn,(.*).rrd TITLE PostgreSQL scan activity YAXIS Scans DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgblk] FNPATTERN pgblk,(.*).rrd TITLE PostgreSQL cache block activity YAXIS Blocks DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgxlg] FNPATTERN pgxlg,(.*).rrd TITLE PostgreSQL xlog activity YAXIS Transactions DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pglck] FNPATTERN pglck,(.*).rrd TITLE PostgreSQL locks YAXIS Locks DEF:p@RRDIDX@=@RRDFN@:lambda:AVERAGE LINE2:p@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:p@RRDIDX@:LAST: \: %5.1lf (cur) GPRINT:p@RRDIDX@:MAX: \: %5.1lf (max) GPRINT:p@RRDIDX@:MIN: \: %5.1lf (min) GPRINT:p@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n hobbit-plugins/xymongraph.d/pgbouncer.cfg0000644000000000000000000000416012057115640015757 0ustar [pgbouncer] FNPATTERN pgbouncer,conns,(.*).rrd TITLE pgbouncer connections YAXIS Connections DEF:cl@RRDIDX@=@RRDFN@:cl_active:AVERAGE DEF:clw@RRDIDX@=@RRDFN@:cl_waiting:AVERAGE DEF:sv@RRDIDX@=@RRDFN@:sv_used:AVERAGE LINE2:cl@RRDIDX@#@COLOR@:@RRDPARAM@ client active GPRINT:cl@RRDIDX@:LAST: \: %4.0lf (cur) GPRINT:cl@RRDIDX@:MAX: \: %4.0lf (max) GPRINT:cl@RRDIDX@:MIN: \: %4.0lf (min) GPRINT:cl@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n LINE2:clw@RRDIDX@#@COLOR@:@RRDPARAM@ client waiting GPRINT:clw@RRDIDX@:LAST: \: %4.0lf (cur) GPRINT:clw@RRDIDX@:MAX: \: %4.0lf (max) GPRINT:clw@RRDIDX@:MIN: \: %4.0lf (min) GPRINT:clw@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n LINE2:sv@RRDIDX@#@COLOR@:@RRDPARAM@ server GPRINT:sv@RRDIDX@:LAST: \: %4.0lf (cur) GPRINT:sv@RRDIDX@:MAX: \: %4.0lf (max) GPRINT:sv@RRDIDX@:MIN: \: %4.0lf (min) GPRINT:sv@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgbouncer_requests] FNPATTERN pgbouncer,stats,(.*).rrd TITLE pgbouncer requests YAXIS requests/s DEF:req@RRDIDX@=@RRDFN@:requests:AVERAGE LINE2:req@RRDIDX@#@COLOR@:@RRDPARAM@ req GPRINT:req@RRDIDX@:LAST: \: %4.0lf (cur) GPRINT:req@RRDIDX@:MAX: \: %4.0lf (max) GPRINT:req@RRDIDX@:MIN: \: %4.0lf (min) GPRINT:req@RRDIDX@:AVERAGE: \: %5.1lf (avg)\n [pgbouncer_traffic] FNPATTERN pgbouncer,stats,(.*).rrd TITLE pgbouncer traffic YAXIS Bytes/s DEF:recv@RRDIDX@=@RRDFN@:received:AVERAGE DEF:sent@RRDIDX@=@RRDFN@:sent:AVERAGE LINE2:recv@RRDIDX@#@COLOR@:@RRDPARAM@ rx GPRINT:recv@RRDIDX@:LAST: \: %7.0lf (cur) GPRINT:recv@RRDIDX@:MAX: \: %7.0lf (max) GPRINT:recv@RRDIDX@:MIN: \: %7.0lf (min) GPRINT:recv@RRDIDX@:AVERAGE: \: %7.0lf (avg)\n LINE2:sent@RRDIDX@#@COLOR@:@RRDPARAM@ tx GPRINT:sent@RRDIDX@:LAST: \: %7.0lf (cur) GPRINT:sent@RRDIDX@:MAX: \: %7.0lf (max) GPRINT:sent@RRDIDX@:MIN: \: %7.0lf (min) GPRINT:sent@RRDIDX@:AVERAGE: \: %7.0lf (avg)\n hobbit-plugins/xymongraph.d/entropy.cfg0000644000000000000000000000037411773324160015501 0ustar [entropy] TITLE Kernel entropy pool YAXIS Bits DEF:en=entropy.rrd:entropy:AVERAGE LINE2:en#00ff33:Available bits GPRINT:en:LAST: \: %5.0lf (cur) GPRINT:en:MAX: \: %5.0lf (max) GPRINT:en:MIN: \: %5.0lf (min) GPRINT:en:AVERAGE: \: %5.0lf (avg)\n hobbit-plugins/xymongraph.d/temp.cfg0000644000000000000000000000060212074001355014731 0ustar [temp] FNPATTERN temp,(.*).rrd TITLE thermal zones YAXIS degrees C DEF:temp@RRDIDX@=@RRDFN@:temp:AVERAGE LINE2:temp@RRDIDX@#@COLOR@:@RRDPARAM@ GPRINT:temp@RRDIDX@:LAST: \: %4.1lf (cur) GPRINT:temp@RRDIDX@:MAX: \: %4.1lf (max) GPRINT:temp@RRDIDX@:MIN: \: %4.1lf (min) GPRINT:temp@RRDIDX@:AVERAGE: \: %4.1lf (avg)\n hobbit-plugins/sudoers.d/0000755000000000000000000000000012231434742012602 5ustar hobbit-plugins/sudoers.d/xymon0000644000000000000000000000054212231434742013700 0ustar # newer kernel versions do not allow lsof to read other users' open files # /usr/lib/xymon/client/ext/libs uses sudo now xymon ALL=(root) NOPASSWD: /usr/bin/lsof -n xymon ALL=(root) NOPASSWD: /usr/bin/debsums -ec xymon ALL=(backuppc) SETENV:NOPASSWD: /usr/lib/xymon/client/ext/backuppc xymon ALL=(list) SETENV:NOPASSWD: /usr/lib/xymon/client/ext/mailman hobbit-plugins/perl/0000755000000000000000000000000012231433772011640 5ustar hobbit-plugins/perl/Hobbit.pm0000664000000000000000000003020412231433020013370 0ustar # Perl module to send reports to the Xymon system monitor # (formerly known as Hobbit) # # Copyright (C) 2008-2012 Christoph Berg # Copyright (C) 2011-2012 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. package Hobbit; use Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(file_to_list_of_regexps file_to_list_of_globs); use strict; use warnings; =head1 NAME Hobbit.pm -- Perl module to easily write Hobbit/Xymon tests =head1 SYNOPSIS use Hobbit; my $bb = new Hobbit('testname'); if (somethings_is_not_so_good) { $bb->color_line('yellow', 'Something is not so good'); } if (somethings_is_really_bad) { $bb->color_line('red', 'Something is really bad'); } $bb->send(); =head1 DESCRIPTION Hobbit.pm is part of the Debian package hobbit-plugins and was written to gather common tasks needed when writing tests for the Xymon monitoring system (formerly known as Hobbit). =cut # Declare the severity order of the known Hobbit colors my %color = ( clear => 0, green => 1, purple => 2, yellow => 3, red => 4, ); # Initialize the Hobbit object my $gself = { hostname => 'hobbit.pm', test => 'uninitialized', }; bless $gself; =head1 EXPORTABLE HELPER FUNCTIONS =head2 @regexps = file_to_list_of_regexps($file) =cut sub file_to_list_of_regexps($) { my @regexps = (); my $filename = shift; open(my $fh, '<', $filename) or return @regexps; while(<$fh>) { unless (/^#/) { chomp; s/\s+$//; push(@regexps, qr/^$_$/); } } return @regexps; } =head2 @globs = file_to_list_of_globs($file) =cut sub file_to_list_of_globs($) { my @globlist = (); my $filename = shift; open(my $fh, '<', $filename) or return @globlist; while(<$fh>) { unless (/^#/) { chomp; s/\s+$//; push(@globlist, $_); } } return @globlist; } =head1 INTERNAL FUNCTIONS =head2 $max_color = max_color($color1, $color) Out of two colors, returns the color with the highest severity. =cut sub max_color ($$) { my ($a, $b) = @_; die "Hobbit::max_color(): No colors given as argument" unless defined($a); die "Hobbit::max_color(): Only one color given as argument" unless defined($b); die "color $a unknown" unless exists $color{$a}; die "color $b unknown" unless exists $color{$b}; return $color{$b} > $color{$a} ? $b : $a; } =head1 METHODS =head2 Constructor: new Hobbit('testname'); =head2 Constructor: new Hobbit({ test => 'testname', ttl => 60, ...}); Creates a new Hobbit object. =head3 Common use cases my $bb = new Hobbit('sometest'); my $bb = new Hobbit({ test => 'testname', color => 'green', hostname => 'host.example.com', text => 'Test successful', title => 'Some Test', ttl => 60, type => 'status', dont_moan => 1 }); =head3 Available parameters =over 3 =item color The initial color of the test. (Default: "clear") =item dont_moan Disable moan() and croak() (see below). Needed if e.g. another used Perl module throws a lot of warnings but works fine otherwise, etc. =item hostname The hostname for which the test should report. (Default: $ENV{CLIENTHOSTNAME} || $ENV{MACHINEDOTS} || $ENV{MACHINE} || 'unknown') =item test The name of the test, i.e. the name of the column on the hobbit status web pages. (Mandatory) =item text Text which is prepended to generated report. (Default: the empty string) =item title The summary of the test. (Default: "$test OK" respectively "$test NOT ok") =item ttl How long the test result is valid before the test state is changed to purple by the xymon daemon if no newer test results have been received. The default value is set on the xymon server and is 300 seconds by default. Values without unit are interpreted as minutes. Valid units are h for hours, d for days, and w for weeks. No space between value and unit allowed. =item type Allows one to send messages of other types than "status", e.g. data, notify, disable, enable, etc. May not yet work with all of these types properly. Please report bugs via the Debian Bug Tracking system. =back =cut sub new ($) { my $class = shift; my $arg = shift; unless (ref $arg) { $arg = { test => $arg, }; } unless ($arg->{test}) { print STDERR "$0: test name undefined\n"; exit 1; } my $self = { type => ($arg->{type} || 'status'), color => 'clear', text => $arg->{text} || '', hostname => ($arg->{hostname} || $ENV{CLIENTHOSTNAME} || $ENV{MACHINEDOTS} || $ENV{MACHINE} || "unknown"), test => $arg->{test}, title => $arg->{title}, ttl => $arg->{ttl}, dont_moan => $arg->{dont_moan}, }; if ($self->{dont_moan}) { $SIG{__WARN__} = \&warn; $SIG{__DIE__} = \¨ } $gself = $self; bless $self; } =head2 Constructor: Hobbit::trends; =head2 Constructor: Hobbit::trends ('hostname'); Creates a new Hobbit trends object. This is a shorthand for new Hobbit({ type = 'data', test = 'trends', hostname = $hostname, dont_moan => 1 }); =head3 Common use case my $trends = Hobbit::trends; $trends->print ("[$bb->{test},extralabel.rrd]\n"); $trends->print ("DS:lambda:GAUGE:600:U:U $value\n"); $trends->send; =cut sub trends { return new Hobbit ({ hostname => shift, test => 'trends', type => 'data', dont_moan => 1, }); } =head2 add_color('somecolor') Minutes that a sub test caused the given color state. Adjusts the overall resulting color accordingly. =cut sub add_color ($) { my ($self, $color) = @_; $self->{color} = max_color ($self->{color}, $color); } =head2 print('some text') Adds the given text to the end of the current report without changing the current color. =cut sub print ($) { my ($self, $text) = @_; $self->{text} .= $text; } =head2 sprintf('format', args ...) Like the print() method, but using sprintf() with format string and arguments. =cut sub sprintf () { my ($self, $format, @args) = @_; $self->{text} .= sprintf ($format, @args); } =head2 color_print('somecolor', 'some text') Adds the given text to the end of the current report and minutes that a sub test caused the given color state. Adjusts the overall resulting color accordingly. =cut sub color_print ($$) { my ($self, $color, $text) = @_; $self->add_color ($color); $self->print ($text); } =head2 color_line('somecolor', 'some text') Adds the given text to the end of the current report and minutes that a sub test caused the given color state. Prepends that text with an accordingly colored Xymon icon and adjusts the overall resulting color accordingly. =cut sub color_line ($$) { my ($self, $color, $text) = @_; $self->color_print ($color, "&$color $text"); } =head2 graph('graphname') Adds HTML for showing a graph. Xymon itself can only show a single graph per test (others can be added to the "trends" column). This method works around that limitation by manually linking to the graph CGI. =cut sub graph ($) { my ($self, $graph) = @_; my $host = $self->{hostname} || ''; my $end = time; my $start = $end - 172800; # 2 days my ($graph_sh, $title, $skin); if ($ENV{XYMON} or not $ENV{BB}) { # xymon mode $graph_sh = 'showgraph.sh'; $title = 'xymongraph'; $skin = $ENV{XYMONSKIN} || '/xymon/gifs/static'; #my $cgi = $ENV{BBSERVERCGIURL} || $ENV{CGIBINURL} || "/hobbit-cgi"; } else { # hobbit mode $graph_sh = 'hobbitgraph.sh'; $title = 'hobbitgraph'; $skin = $ENV{BBSKIN} || '/hobbit/gifs/static'; } $self->print ("

"); $self->print (""); $self->print ("\"$title"); $self->print (" "); $self->print (" "); $self->print (""); $self->print ("\"Zoom"); $self->print ("

\n"); } =head2 send() Sends the report to the xymon server. =cut sub send () { my $self = shift; if ($self->{ttl} and $self->{ttl} =~ /^\d+/ and # there might be an h/d/w suffix $self->{type} eq 'status') { $self->{type} = "$self->{type}+$self->{ttl}"; } my $report = "$self->{type} $self->{hostname}.$self->{test}"; if ($self->{type} =~ m/^status/) { my $date = scalar localtime; my $title = ''; if ($self->{color} eq 'green') { $title = "$self->{test} OK"; } elsif ($self->{color} eq 'yellow' or $self->{color} eq 'red') { $title = "$self->{test} NOT ok"; } $title = ' - ' . ($self->{title} ? $self->{title} : $title) if ($self->{title} or $title); $report .= " $self->{color} $date$title"; } $report .= "\n$self->{text}"; $report .= "\n" unless ($report =~ /\n\n$/); if ($ENV{XYMON} and $ENV{XYMSRV}) { open F, '|-', "$ENV{XYMON} $ENV{XYMSRV} @"; print F $report; close F; } elsif ($ENV{BB} and $ENV{BBDISP}) { open F, '|-', "$ENV{BB} $ENV{BBDISP} @"; print F $report; close F; } else { print $report; } } =head1 FUNCTIONS =head2 grep(I) Run a xymongrep (bbhostgrep) query and return an array reference of hashes with keys B (string), B (string), and B (array reference). my $list = Hobbit::grep('foobar'); foreach my $host (@$list) { print "$host->{ip} $host->{hostname}\n"; } =cut sub grep ($) { my ($tag) = @_; my @greps = qw(/usr/lib/xymon/client/bin/xymongrep /usr/lib/hobbit/client/bin/bbhostgrep); my $grep = (grep { -x $_ } @greps)[0]; my $list; open GREP, '-|', "$grep $tag"; while () { if (/^(\S+) (\S+) # (.*)/) { my ($ip, $hostname, $tags) = ($1, $2, $3); my @tags = split / /, $tags; push @$list, { ip => $1, hostname => $2, tags => \@tags }; } } close GREP; return $list; } =head1 INTERNAL METHODS =head2 moan() If the check issues a Perl warning, this warning is added to the report with color state "yellow". Set dont_moan to 1 to disable this feature. =cut sub moan ($) { my $msg = shift; my $date = scalar localtime; print STDERR "$date $0 $gself->{hostname}.$gself->{test}: $msg"; $gself->color_line ('yellow', "Warning: $msg"); } =head2 croak() If the check issues a Perl error, this error is added to the report with color state "red". Set dont_moan to 1 to disable this feature. =cut sub croak ($) { my $msg = shift; my $date = scalar localtime; print STDERR "$date $0 $gself->{hostname}.$gself->{test}: $msg"; $gself->color_line ('red', "Error: $msg"); $gself->send(); exit 1; } $SIG{__WARN__} = \&moan; $SIG{__DIE__} = \&croak; 1; =head1 AUTHORS AND COPYRIGHT Copyright (C) 2008-2011 Christoph Berg Copyright (C) 2011 Axel Beckert =head1 SEE ALSO L L, L hobbit-plugins/perl/Hobbit.pm.txt0000777000000000000000000000000012211104460015750 2Hobbit.pmustar hobbit-plugins/server-ext/0000755000000000000000000000000012231434742013000 5ustar hobbit-plugins/server-ext/aptdiff0000755000000000000000000000734312231434742014352 0ustar #!/usr/bin/perl -w # Copyright (C) 2008, 2012 Christoph Berg # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # Server script to monitor list of installed packages in a group of hosts # # The test result will appear in the "aptdiff" column for one of the hosts. # In bb-hosts, use aptdiff=POOL[,POOL...] where POOL is a hostname or a # sprintf-pattern PATTERN:START:END. The script will ask the xymon server # for the dpkg sections of the clientlogs. Running kernels are also checked # via the uname section. # # Examples: # aptdiff=foo.bla.org,bar.bla.org # aptdiff=web%02d.bla.org:1:8 use strict; use Hobbit qw(file_to_list_of_regexps); # File with list of "$hostname $pkg" regexps of host/pkg patterns to ignore my @diff_ignore = file_to_list_of_regexps ("/etc/xymon/aptdiff_ignore"); my @lines = `$ENV{XYMONHOME}/bin/xymongrep "aptdiff=*"`; foreach my $line (@lines) { $line =~ /^(\S+)\s+(\S+)\s+#.*\baptdiff=(\S+)/ or next; my ($ip, $hostname, $data) = ($1, $2, $3); my ($template, $start, $end) = split (/:/, $data); my @templates = split (/,/, $template); my @hosts; if ($start and $end) { foreach my $t (@templates) { foreach my $n ($start .. $end) { push @hosts, sprintf ($t, $n); } } } else { @hosts = @templates; } my $out; my %dpkg; foreach my $host (@hosts) { next if exists $dpkg{$host}; my $found = 0; open(F, '-|', "$ENV{XYMON} $ENV{XYMONSERVERHOSTNAME} 'clientlog $host section=uname,dpkg'") or die "$host: $!"; while () { if (/\[dpkg\]/) { next; } elsif (/\[uname\]/) { my $uname = ; chomp $uname; $uname =~ s/^(\S+)\s+\S+/$1/; # strip hostname $dpkg{$host}->{'KERNEL'} = $uname; $dpkg{_all}->{'KERNEL'} = 1; next; } next unless /^([ih])i (\S+) (\S+)/; $dpkg{$host}->{$2} = $3 . ($1 eq 'h' ? "/hold" : ""); $dpkg{_all}->{$2} = 1; $found = 1; } close F; $host = '' unless $found; } @hosts = grep /./, @hosts; my $first = shift @hosts || next; my $diff = 0; my $bb = new Hobbit ({ test => 'aptdiff', hostname => $hostname }); foreach my $pkg (sort keys %{$dpkg{_all}}) { my $ver = $dpkg{$first}->{$pkg} || "(none)"; foreach my $other (@hosts) { my $otherver = $dpkg{$other}->{$pkg} || "(none)"; if ($ver ne $otherver) { my $color = 'yellow'; if (grep { "$hostname $pkg" =~ $_ } @diff_ignore) { $color = 'clear'; } else { $diff = 1; } $bb->color_line ($color, "$pkg: $first $ver $other $otherver\n"); } } } if ($diff) { $bb->print ("\n"); } elsif (@hosts) { $bb->color_line ('green', "no package differences in pool $hostname\n\n"); } else { $bb->color_line ('clear', "not enough hosts in pool $hostname\n\n"); } $bb->print ("Hosts:\n" . join ("\n", $first, @hosts) . "\n"); $bb->send; } hobbit-plugins/server-ext/ircbot0000755000000000000000000003547112231434742014222 0ustar #!/usr/bin/perl # Copyright (C) 2008, 2009, 2010 Christoph Berg # Copyright (C) 2010, 2012 Axel Beckert # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. # Xymon-to-IRC bot. Should be running from xymond_channel --channel=page. use warnings; use strict; use POE qw(Component::IRC::State Component::IRC::Plugin::AutoJoin Wheel::ReadWrite); use Data::Dumper; my $hosttestre = '[a-z0-9.^*()\[\]|_+-]+'; # chars for host/test patterns my $nick = $ENV{IRC_NICK} || die ("IRC_NICK is not set"); my $channel = $ENV{IRC_CHANNEL} || die ("IRC_CHANNEL is not set"); my $server = $ENV{IRC_SERVER} || die ("IRC_SERVER is not set"); my $access = $ENV{IRC_ACCESS} || ".*"; my $sleep = $ENV{IRC_SLEEP} || "0"; my $green_privmsg = $ENV{IRC_GREEN_PRIVMSG} || "0"; my $alertNicks = $ENV{ALERT_NICKS} || ''; my @alertHosts = split /[, ]+/, $ENV{ALERT_HOSTS} || ''; my @alertIgnore = split /[, ]+/, $ENV{ALERT_IGNORE} || ''; my %lastchange; # %lastchange{$host}->{$test} = $timestamp print scalar(localtime) . " Connecting to $server\n"; my $irc = POE::Component::IRC::State->spawn() or die "Oh noooo! $!"; POE::Session->create( inline_states => { _start => \&on_start, irc_disconnected => \&do_connect, irc_001 => \&on_connect, irc_public => \&on_msg, irc_msg => \&on_msg, got_input => \&on_stdin, }, ); sub bb { my $msg = shift; system ($ENV{XYMON}, $ENV{XYMSRV}, $msg); } sub color { my %color = ( green => 3, yellow => 7, red => 4, purple => 6, blue => 2, ); my $color = shift; my $text = shift; return "$color{$color}$text" if (exists ($color{$color})); return $text; } sub age { my $age = time - shift; $age = -$age if ($age < 0); if ($age <= 60) { return sprintf ('%ds', $age); } elsif ($age <= 3600) { return sprintf ('%dm%ds', $age/60.0, $age % 60); } elsif ($age <= 86400) { return sprintf ('%dh%dm', $age/3600.0, ($age % 3600)/60.0); } elsif ($age <= 90 * 86400) { return sprintf ('%dd%dh', $age/86400.0, ($age % 86400)/3600.0); } else { return sprintf ('%.1fmon', $age / (30 * 86400.0)); } } sub dismsg ($$) { my ($host, $test) = @_; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host test=$test fields=disabletime,dismsg'"); my $ret = ; chomp $ret; close F; my ($disabletime, $dismsg) = split /\|/, $ret; my $until = $disabletime == -1 ? "OK" : scalar (localtime ($disabletime)); my %quote = ( '\\' => '\\', n => ' ', p => '|', r => ' ', t => ' ' ); $dismsg =~ s/\\([\\nprt])/$quote{$1}/g; $dismsg =~ s/^ +//; return "until $until $dismsg"; } sub get_cookie ($$) { my ($host, $test) = @_; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host test=$test fields=cookie'"); my $cookie = ; close F; return undef if (not $cookie or $cookie == -1); chomp $cookie; return $cookie; } sub on_start { $_[HEAP]{client} = POE::Wheel::ReadWrite->new( InputHandle => \*STDIN, OutputHandle => \*STDOUT, InputEvent => "got_input" ); $irc->plugin_add('AutoJoin', POE::Component::IRC::Plugin::AutoJoin->new( Channels => { $channel => '' } )); $irc->yield(register => "all"); do_connect(@_); } sub do_connect { $irc->yield( connect => { Nick => $nick, Ircname => $ENV{IRC_IRCNAME} || 'Xymon monitor bot', Username => $ENV{IRC_USER} || 'xymon', Server => $server, Port => $ENV{IRC_PORT} || 6667, UseSSL => $ENV{IRC_SSL} ? 1 : 0, Flood => 1, # for now } ); } sub on_connect { my $self = shift; # read current status open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard fields=hostname,testname,lastchange'"); my $count = 0; while (my $line = ) { chomp $line; my ($hostname, $testname, $lastchange) = split /\|/, $line; next unless ($lastchange); $lastchange{$hostname}->{$testname} = $lastchange; $count++; } close F; print scalar (localtime) . " Joining $channel, got $count status reports from xymond\n"; $irc->yield(join => $channel); } sub on_msg { # get input my ($kernel, $from, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2]; chomp $msg; $msg =~ s/[^[:print:]]/ /g; return unless ($msg =~ /^($nick: )?(help|disable|enable|drop|ack|hosts?|status|query|clear|green|yellow|red|purple|blue)\b/); # check access my $date = scalar localtime; my $peer = (split /!/, $from)[0]; my $channel = $where->[0]; # Source: https://www.alien.net.au/irc/chantypes.html $channel = undef unless $channel =~ /^[#&!+.~]/; my $reply = $channel ? $channel : $peer; if ($from !~ /^($access)$/io) { print "$date Denied access for $from ($msg)\n"; return; } # parse stuff if ($msg =~ /^($nick: )?help\b/i) { $irc->yield(notice => $reply, "List of commands: " . "help disable enable drop ack hosts status query "); } elsif ($msg =~ /^$nick: disable ($hosttestre)[ .]($hosttestre) (\S+) (.+)/io) { my ($host, $test, $time, $reason) = ($1, $2, $3, $4); $time =~ s/ok/-1/i; bb ("disable $host.$test $time Disabled by $peer: $reason"); } elsif ($msg =~ /^$nick: enable ($hosttestre)[ .]($hosttestre)/io) { my ($host, $test) = ($1, $2); bb ("enable $host.$test"); } elsif ($msg =~ /^$nick: drop ($hosttestre)[ .]($hosttestre)/io) { my ($host, $test) = ($1, $2); if ($test eq '*') { bb ("drop $host"); } else { bb ("drop $host $test"); } } elsif ($msg =~ /^$nick: ack(?:nowledge)? ($hosttestre)[ .]($hosttestre) (.+)/io) { my ($host, $test, $time_reason) = ($1, $2, $3); if (my $cookie = get_cookie ($host, $test)) { $time_reason = "1h $time_reason" unless ($time_reason =~ /^\d/); bb ("xymondack $cookie $time_reason Acked by $peer"); } else { $irc->yield(notice => $reply, "No alert cookie for $host $test"); } } elsif ($msg =~ /^(?:$nick: )?hosts?(?:\s+($hosttestre)(?:\s+($hosttestre))?)?/io) { my $host = $1 || '*'; my $test = $2 || 'info'; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host test=$test fields=hostname,color'"); my %hosts; while () { chomp; my ($hostname, $color) = split /\|/; $hosts{$hostname} = $test eq 'info' ? 'clear' : $color; } close F; my @hosts = sort keys %hosts; my $nhosts = scalar @hosts; @hosts = @hosts[0 .. 19] if $nhosts > 20; my $txt = join (' ', map { color ($hosts{$_}, $_) } @hosts); $txt = "no hosts found" if $nhosts == 0; $txt .= " ... " . ($nhosts - 20) . " more" if ($nhosts > 20); $irc->yield(notice => $reply, $txt); } elsif ($msg =~ /^(?:$nick: )?status\s+($hosttestre)\s+($hosttestre)/io) { my ($host, $test) = ($1, $2); open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host test=$test fields=hostname,testname,color,lastchange,logtime,disabletime,dismsg'"); my $ntests; while () { next if (++$ntests > 5); chomp; my ($hostname, $testname, $color, $lastchange, $logtime, $disabletime, $dismsg) = split /\|/; $irc->yield(notice => $reply, "10$hostname $testname: " . color ($color, $color) . " for " . age ($lastchange) . ", reported " . age ($logtime) . " ago"); sleep $sleep if $sleep; if ($disabletime != 0) { my $until = $disabletime == -1 ? "OK" : scalar (localtime ($disabletime)); my %quote = ( '\\' => '\\', n => ' ', p => '|', r => ' ', t => ' ' ); $dismsg =~ s/\\([\\nprt])/$quote{$1}/g; $irc->yield(notice => $reply, "Test disabled until $until: $dismsg"); sleep $sleep if $sleep; } } close F; if ($ntests > 5) { $irc->yield(notice => $reply, "... " . ($ntests - 5) . " more"); } } elsif ($msg =~ /^(?:$nick: )?status\s+($hosttestre)/io) { my $host = $1; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host fields=hostname,testname,color'"); my %test; while () { chomp; my ($hostname, $test, $color) = split /\|/; next if $test =~ /^(info|trends)$/; $test{$hostname}{$test} = $color; } close F; my $nhosts; for $host (sort keys %test) { next if (++$nhosts > 5); my $status = join (' ', map { color ($test{$host}{$_}, $_) } sort keys %{$test{$host}}); $status = "unknown" if (not scalar keys %{$test{$host}}); $irc->yield(notice => $reply, "10$host: $status"); sleep $sleep if $sleep; } if ($nhosts > 5) { $irc->yield(notice => $reply, "... " . ($nhosts - 5) . " more"); } } elsif ($msg =~ /^(?:$nick: )?status\b/io) { open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard fields=hostname,testname,color'"); my (%host, $services, %color); while () { chomp; my ($host, $test, $color) = split /\|/; next if $test =~ /^(info|trends)$/; $host{$host} = 1; $services++; $color{$color}++; } close F; my $hosts = scalar keys %host; my $status = join ('', map { color ($_, " $color{$_} $_") } sort keys %color ); $irc->yield(notice => $reply, "status: $hosts hosts, $services services,$status"); } elsif ($msg =~ /^(?:$nick: )?(clear|green|yellow|red|purple|blue)\b/) { my $color = $1; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard fields=hostname,testname,lastchange,logtime color=$color'"); my $services = 0; while () { chomp; my ($host, $test, $last, $logtime) = split /\|/; next if $test =~ /^(info|trends)$/; $services++; if ($services <= 5) { $irc->yield(notice => $reply, "10$host $test: " . color ($color, $color) . " for " . age ($last) . ", reported " . age ($logtime) . " ago"); sleep $sleep if $sleep; } } close F; if ($services == 0) { $irc->yield(notice => $reply, "no " . color ($color, $color) . " services"); } if ($services > 5) { $irc->yield(notice => $reply, "... " . ($services - 5) . " more"); } # not mentioned in 'help' as it is pretty boring } elsif ($msg =~ /^(?:$nick: )?query\s+($hosttestre)/i) { my $query = $1; my $ret = substr (`$ENV{XYMON} $ENV{XYMSRV} 'query $query'`, 0, 100); chomp $ret; $ret =~ s/[^[:print:]]/ /g; $irc->yield(notice => $reply, "$query: " . ($ret || "no result")); } else { return; } print "$date <$from> $msg\n"; sleep $sleep if $sleep; } sub on_stdin { my $line = $_[ARG0]; chomp $line; return unless $line =~ /^@@./; #print "$line\n"; my @list = split /\|/, $line; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 # @@page#2|1204300490.218654|xymond|tesla|xymond|127.0.0.1|1204302290|green|yellow|1204300490|page|-1|linux|linux| # @@page#1|1204302889.833747|127.0.0.1|hubble|bat|10.81.1.7|1204304689|red|clear|1204302889||404645||| if ($list[0] =~ /^\@\@page/) { my ($host, $test, $color, $oldcolor, $logtime) = @list[3, 4, 7, 8, 9]; return if ($color eq $oldcolor); # no change my $alertMsg = ''; if ($alertNicks && grep(/$host/, @alertHosts) && !grep(/$test/, @alertIgnore) && ($color eq 'red')) { $alertMsg = $alertNicks.": "; } my $msg = "$alertMsg10$host " . color ($color, "$test $color") . " (was " . color ($oldcolor, $oldcolor) . ($lastchange{$host}->{$test} ? " for " . age ($lastchange{$host}->{$test}) : "") . ")"; if ($color eq 'blue') { $msg .= " " . dismsg ($host, $test); } if ($color =~ /clear|green/) { if ($green_privmsg) { $irc->yield(privmsg => $channel => $msg); } else { $irc->yield(notice => $channel => $msg); } } else { $irc->yield(privmsg => $channel => $msg); } $lastchange{$host}->{$test} = $logtime; sleep $sleep if $sleep; # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 # @@stachg#11280/sam|1268916763.289293|195.49.152.111||sam|xymontest|1268918563|yellow|green|1268696171|0||0|1268916705 # @@stachg#11290/adweb|1268917833.154419|195.49.152.3||adweb|apt|2147483647|blue|yellow|1268910336|-1|Disabled by: cbe @ 10.1.1.1\nReason: Upgrade\n|0|1268917558 } elsif ($list[0] =~ /^\@\@stachg/) { # untested my ($host, $test, $color, $oldcolor, $lastchange) = @list[4, 5, 7, 8, 9]; return if ($color eq $oldcolor); # no change my $alertMsg = ''; if ($alertNicks && grep(/$host/, @alertHosts) && !grep(/$test/, @alertIgnore) && ($color eq 'red')) { $alertMsg = $alertNicks.": "; } my $msg = "$alertMsg10$host " . color ($color, "$test $color") . " (was " . color ($oldcolor, $oldcolor) . ($lastchange ? " since " . scalar localtime ($lastchange) : "") . ")"; if ($color eq 'blue') { $msg .= " " . dismsg ($host, $test); } if ($color =~ /clear|green/) { if ($green_privmsg) { $irc->yield(privmsg => $channel => $msg); } else { $irc->yield(notice => $channel => $msg); } } else { $irc->yield(privmsg => $channel => $msg); } sleep $sleep if $sleep; # 0 1 2 3 4 5 6 # @@ack#12|1231428868.733473|127.0.0.1|benz|apt|10.81.0.10|1231429168 } elsif ($list[0] =~ /^\@\@ack/) { # unfortunately there are no acks on "stachg" channel my ($host, $test, $acktime) = @list[3, 4, 6]; open(F, '-|', "$ENV{XYMON} $ENV{XYMSRV} 'xymondboard host=$host test=$test fields=ackmsg'"); my $ackmsg = ; chomp $ackmsg; close F; my %quote = ( '\\' => '\\', n => ' ', p => '|', r => ' ', t => ' ' ); $ackmsg =~ s/\\([\\nprt])/$quote{$1}/g; my $msg = "10$host $test acknowledged for " . age ($acktime) . ": $ackmsg"; $irc->yield(privmsg => $channel => $msg); # 0 1 2 3 4 # @@droptest#11924/*|1272016619.152373|1.4.1.1|dbsrv|postgres } elsif ($list[0] =~ /^\@\@droptest/) { my ($host, $test) = @list[3, 4]; my $msg = "10$host $test dropped"; $irc->yield(privmsg => $channel => $msg); delete $lastchange{$host}->{$test}; # @@logrotate#224/*|1271219105.493869|xymond| } elsif ($list[0] =~ /^\@\@logrotate/) { # do nothing # @@shutdown#666/*|1355525247.611339|xymond| } elsif ($list[0] =~ /^\@\@shutdown/) { print scalar(localtime) . "Xymon shutdown. Exiting.\n"; exit; } else { print scalar (localtime) . " Could not parse $line\n"; } } $poe_kernel->run(); hobbit-plugins/server-ext/conn60000755000000000000000000000713612231434742013760 0ustar #!/usr/bin/perl # # Do IPv6 ping tests as "conn6". # This server script is based on a shell script from Debian hobbit-plugins # 20101207 package, but rewritten in Perl. # # Just add conn6 to the services of a host and this script will ping6 the # AAAA record of the given host. # Alternatively you can add a comma separated list of IPv6 addresses or # hostnames that resolve to IPv6 addresses as a parameter to conn6, to ping6 # all these addresses. # Examples: # 10.1.2.3 foo # ftp conn6:2001:db8:1::42 # 10.1.2.4 bar # smtp conn6 # 10.1.2.5 baz # conn6:baz.example.com dialup # 10.1.2.6 router # conn6:2001:db8:1::1,2001:db8:2::1 # # Copyright (c) 2011 Roland Rosenfeld # # 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 2 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, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # $Id: conn6.pl,v 1.2 2011/02/22 09:22:55 roland Exp roland $ use strict; use warnings; #use Data::Dumper; my $fping = 'fping6'; open(HOSTGREP, '-|', "$ENV{XYMONHOME}/bin/xymongrep conn6 conn6:\* dialup") || die "cannot run $ENV{XYMONHOME}/bin/xymongrep"; while () { if (/^(\d+\.\d+\.\d+\.\d+)\s+(\S+)\s+#\s+(.*)$/) { my ($ipv4, $host, $services) = ($1, $2, $3); # parse services: my $dialup = 0; my @destinations; foreach my $service (split /\s+/, $services) { if ($service eq 'dialup') { $dialup = 1; } elsif ($service eq 'conn6') { push @destinations, $host; } elsif ($service =~ /^conn6:(.*)$/) { my $dests = $1; foreach my $destination (split /,/, $dests) { push @destinations, $destination; } } } next if $#destinations == -1; # no conn6 found, only dialup my $output = ''; my $color = 'green'; foreach my $destination (@destinations) { my $localcolor = 'green'; my $pingresult = `$fping -e $destination 2>&1`; my $time = 0; if ($pingresult =~ /is\s*alive/) { if ($pingresult =~ /\(([\d.]+)\s*us/) { $time = sprintf('%f', $1/1000000); } elsif ($pingresult =~ /\(([\d.]+)\s*ms/) { $time = sprintf('%f', $1/1000); } elsif ($pingresult =~ /\(([\d.]+)/) { $time = $1; } } else { $color = 'red'; $localcolor = 'red'; if ($dialup == 1) { $color = 'clear'; $localcolor = 'clear'; } } $output .= "\&$localcolor $pingresult"; if ($destination !~ /:.*:/) { # resolve hostnames: $output .= `host -t AAAA $host 2>&1`; } $output .= "Seconds: $time\n\n\n"; } #open (BB, '|-', "cat") || die "cannot run bb"; open(BB, '|-', "$ENV{XYMON} $ENV{XYMSRV} \@") || die "cannot run $ENV{XYMON}"; print BB "status $host.conn6 $color ".`date`."\n"; print BB $output; #print BB "------------------------------------------\n"; close BB; } } hobbit-plugins/server-ext/tftp0000755000000000000000000000606112231434742013706 0ustar #!/usr/bin/perl # # Xymon test to check tftp servwrs # # This server script is based on Roland Rosenfeld's conn6 test which # itself is based on a shell script from the Debian hobbit-plugins # package, but rewritten in Perl. # # Just add tftp to the services of a host and this script will try to # download the file /pxelinux.0 via TFTP from the given host. # # Alternatively you can add colon separated a file or path which # should be used to test the TFTP server. # # Currently only one file per server can be tested. # # Examples: # 10.1.2.3 foo # ftp tftp # 10.1.2.4 bar # smtp tftp:bootmgr.exe # 10.1.2.5 baz # tftp:/sparc.img # # Copyright (c) 2011 Roland Rosenfeld # Copyright (c) 2011-2012 Axel Beckert # # 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 2 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, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; use warnings; #use Data::Dumper; use Hobbit; use Net::TFTP; my $default_path = '/pxelinux.0'; my %remote_path = (); open(HOSTGREP, '-|', "$ENV{XYMONHOME}/bin/xymongrep tftp tftp:\* dialup") || croak("cannot run $ENV{XYMONHOME}/bin/xymongrep"); while () { if (/^(\d+\.\d+\.\d+\.\d+)\s+(\S+)\s+#\s+(.*)$/) { my ($ipv4, $host, $services) = ($1, $2, $3); # parse services: my $dialup = 0; my @destinations; foreach my $service (split /\s+/, $services) { if ($service eq 'dialup') { $dialup = 1; } elsif ($service eq 'tftp') { push @destinations, $host; $remote_path{$host} = $default_path; } elsif ($service =~ /^tftp:(.*)$/) { push @destinations, $host; $remote_path{$host} = $1; } } next if $#destinations == -1; # no tftp found, only dialup my $output = ''; my $color = 'green'; foreach my $destination (@destinations) { my $tftp = Net::TFTP->new($destination); my $bb = new Hobbit({ test => 'tftp', hostname => $destination }); $tftp->get($remote_path{$destination}); my $error = $tftp->error; if ($error) { if ($dialup == 1) { $bb->add_color('clear'); $bb->print("&red Couldn't download $remote_path{$destination} from $destination via TFTP"); } else { $bb->color_line('red', "Couldn't download $remote_path{$destination} from $destination via TFTP"); } } else { $bb->color_line('green', "Successfully downloaded $remote_path{$destination} from $destination via TFTP"); } $bb->send(); } } } hobbit-plugins/server-ext/pgbouncer0000755000000000000000000000710312231434742014713 0ustar #!/usr/bin/perl # Copyright (C) 2012 Christoph Berg # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. use strict; use warnings; use DBD::Pg; use Hobbit; my $hosts = Hobbit::grep ('pgbouncer'); foreach my $host (@$hosts) { my $bb = new Hobbit({ hostname => $host->{hostname}, test => 'pgbouncer' }); $bb->add_color ('green'); my $trends = Hobbit::trends($host->{hostname}); my $hostname = $host->{hostname}; my $dbh = DBI->connect("dbi:Pg:dbname=pgbouncer host=$hostname port=6432", 'hobbit', '', {AutoCommit => 1, RaiseError => 1, PrintError => 1}); $bb->print ("Connections:\n"); my $q = $dbh->prepare ("SHOW POOLS"); $q->execute; while (my $row = $q->fetchrow_hashref) { next if ($row->{database} eq 'pgbouncer'); $bb->print ("$row->{user}\@$row->{database}:\n"); $bb->print (" clients: active $row->{cl_active}\n"); $bb->print (" waiting $row->{cl_waiting}\n"); $bb->print (" server connections: active $row->{sv_active}\n"); $bb->print (" idle $row->{sv_idle}\n"); $bb->print (" used $row->{sv_used}\n"); $bb->print (" tested $row->{sv_tested}\n"); $bb->print (" login $row->{sv_login}\n"); $trends->print ("[pgbouncer,conns,$row->{database},$row->{user}.rrd]\n"); $trends->print ("DS:cl_active:GAUGE:600:U:U $row->{cl_active}\n"); $trends->print ("DS:cl_waiting:GAUGE:600:U:U $row->{cl_waiting}\n"); $trends->print ("DS:sv_active:GAUGE:600:U:U $row->{sv_active}\n"); $trends->print ("DS:sv_idle:GAUGE:600:U:U $row->{sv_idle}\n"); $trends->print ("DS:sv_used:GAUGE:600:U:U $row->{sv_used}\n"); $trends->print ("DS:sv_tested:GAUGE:600:U:U $row->{sv_tested}\n"); $trends->print ("DS:sv_login:GAUGE:600:U:U $row->{sv_login}\n"); $trends->print ("DS:maxwait:GAUGE:600:U:U $row->{maxwait}\n"); } $bb->print ("\nStatistics:\n"); $q = $dbh->prepare ("SHOW STATS"); $q->execute; while (my $row = $q->fetchrow_hashref) { next if ($row->{database} eq 'pgbouncer'); $bb->print ("$row->{database}:\n"); $bb->print (" total requests: $row->{total_requests}\n"); $bb->print (" total received: $row->{total_received}\n"); $bb->print (" total sent: $row->{total_sent}\n"); $trends->print ("[pgbouncer,stats,$row->{database}.rrd]\n"); $trends->print ("DS:requests:DERIVE:600:U:U $row->{total_requests}\n"); $trends->print ("DS:received:DERIVE:600:U:U $row->{total_received}\n"); $trends->print ("DS:sent:DERIVE:600:U:U $row->{total_sent}\n"); } $bb->graph ('pgbouncer_traffic'); $bb->graph ('pgbouncer_requests'); $bb->send; $trends->send; } hobbit-plugins/examples/0000755000000000000000000000000012207652651012516 5ustar hobbit-plugins/examples/zombies_ignore0000644000000000000000000000150112124313210015430 0ustar # Known bug in LightDM lightdm See http://bugs.debian.org/675351 and https://bugs.launchpad.net/bugs/990661 # Known bug in libvte packages, affecting tons of terminal emulators mssh|/usr/bin/(x-term|termin)|(mate-|xfce4-|lx)terminal See https://bugs.launchpad.net/bugs/996484, https://bugs.launchpad.net/bugs/864609, http://bugs.debian.org/645104 # BackupPC may reap zombies not immediately by design BackupPC_dump BackupPC may reap zombies not immediately by design, see http://sourceforge.net/mailarchive/message.php?msg_id=23214059 # Match ssh zombies only if from user "backuppc" backuppc:^ssh BackupPC may reap zombies not immediately by design, see http://sourceforge.net/mailarchive/message.php?msg_id=23214059 # Example for ignoring zombies generated by the demo zombie script in # test/zombie.pl zombie\.pl Demo Zombie hobbit-plugins/examples/verify/0000775000000000000000000000000012207652651014024 5ustar hobbit-plugins/examples/verify/zombie.pl0000775000000000000000000000071212207652651015651 0ustar #!/usr/bin/perl -w # Script to generate a zombie process to test misc.d/zombies. # Author: Axel Beckert use 5.010; my $pid = fork; if ($pid) { say "PARENT: Parent = $$. Child = $pid"; # Parent stops itself kill(19, $$); say "PARENT: continued..."; exit 0; } elsif (defined $pid and $pid == 0) { say "CHILD: Child = $$"; sleep 1; say "CHILD: Back from sleep, exiting" } else { say "FORK failed: $!"; }