diff --git a/.gitignore b/.gitignore index a5c75d7..50d8957 100644 --- a/.gitignore +++ b/.gitignore @@ -1,39 +1,5 @@ -munin-1.4.5.tar.gz -/munin-node.service -/munin-1.4.5.tar.gz -/munin-1.4.5-rundir-conf.patch -/munin.conf -/munin-1.4.5-no-such-object.patch -/munin-1.4.6.tar.gz -/munin-1.4.7.tar.gz -/munin-2.0.2.tar.gz -/munin-2.0.4.tar.gz -/munin-2.0.5.tar.gz -/munin-2.0.6.tar.gz -/munin-2.0.7.tar.gz -/munin-2.0.8.tar.gz -/munin-2.0.9.tar.gz -/munin-2.0.10.tar.gz -/munin-2.0.11.tar.gz -/munin-2.0.11.1.tar.gz -/munin-2.0.12.tar.gz -/munin-2.0.13.tar.gz -/munin-2.0.14.tar.gz -/munin-2.0.15.tar.gz -/munin-2.0.16.tar.gz -/munin-2.0.17.tar.gz -/munin-2.0.18.tar.gz -/munin-2.0.19.tar.gz -/munin-2.0.20.tar.gz -/munin-2.0.21.tar.gz -/munin-2.0.22.tar.gz -/munin-2.0.23.tar.gz -/munin-2.0.24.tar.gz -/munin-2.0.25.tar.gz -/munin-2.0.26.tar.gz -/munin-2.0.27.tar.gz -/munin-2.0.28.tar.gz -/munin-2.0.29.tar.gz -/munin-2.0.30.tar.gz -/munin-2.0.32.tar.gz -/munin-2.0.33.tar.gz +munin-*.tar.gz* +*.src.rpm +.build-*.log +munin-2*/ +noarch/ diff --git a/00-default b/00-default new file mode 100644 index 0000000..ccc9d52 --- /dev/null +++ b/00-default @@ -0,0 +1,84 @@ +# This file is used to configure how the plugins are invoked. +# Place in /etc/munin/plugin-conf.d/ or corresponding directory. +# +# PLEASE NOTE: Changes in the plugin-conf.d directory are only +# read at munin-node startup, so restart at any changes. +# +# user # Set the user to run the plugin as +# group # Set the group to run the plugin as +# command # Run instead of the plugin. %c +# expands to what would normally be run. +# env. # Sets in the plugin's environment, see the +# individual plugins to find out which variables they +# care about. + +[bind9_rndc] +user root +env.rndc /usr/sbin/rndc +env.querystats /var/named/data/named_stats.txt + +[cps*] +user root + +[df*] +user root +env.exclude none unknown binfmt_misc cgroup_root debugfs devpts devtmpfs fuse.gvfs-fuse-daemon iso9660 ramfs romfs rootfs rpc_pipefs squashfs udf +env.exclude_re ^/run/user/ ^/sys/ ^/var/lib/docker ^/var/lib/containers/storage/overlay ^/var/lib/mock/ ^/media/ ^/mnt$ + +[exim*] +group mail + +[fw_*] +user root + +[hddtemp_smartctl] +user root + +[if_*] +user root + +[ipmi_*] +user root +timeout 20 + +[load] +env.load_warning 100 + +[mailman] +user mailman + +[munin_stats] +env.fields update limits + +[mysql*] +#env.mysqlopts -u someuser + +[mysql_replication] +env.slave_io_running_warning 0.5 +env.slave_sql_running_warning 0.5 +env.seconds_behind_master_warning 3600 +env.seconds_behind_master_critical 86400 + +[mysql_wsrep_flow_paused_ns] +env.wsrep_flow_control_paused_ns_warning 200000000 +env.wsrep_flow_control_paused_ns_critical 10000000000 + +[postfix*] +user root +env.logfile maillog +env.logdir /var/log + +[postgres_*] +user postgres +env.PGUSER postgres +env.PGPORT 5432 + +[sendmail*] +user root +env.mspqueue /var/spool/clientmqueue + +[smart_*] +user root + +[vlan*] +user root diff --git a/21b3d860c17d7997d64267963f91ed75ca8a3e03.patch b/21b3d860c17d7997d64267963f91ed75ca8a3e03.patch new file mode 100644 index 0000000..d3cba49 --- /dev/null +++ b/21b3d860c17d7997d64267963f91ed75ca8a3e03.patch @@ -0,0 +1,36 @@ +From 21b3d860c17d7997d64267963f91ed75ca8a3e03 Mon Sep 17 00:00:00 2001 +From: Lars Kruse +Date: Thu, 29 Mar 2018 03:15:42 +0200 +Subject: [PATCH] plugins nginx_*: change category from 'nginx' to 'webserver' + +--- + plugins/node.d/nginx_request | 2 +- + plugins/node.d/nginx_status | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/node.d/nginx_request.in b/plugins/node.d/nginx_request.in +index 38f1cbe6c..9cd41d7cf 100755 +--- a/plugins/node.d/nginx_request.in ++++ b/plugins/node.d/nginx_request.in +@@ -94,7 +94,7 @@ if ( exists $ARGV[0] and $ARGV[0] eq "config" ) + { + print "graph_title Nginx requests\n"; + print "graph_args --base 1000\n"; +- print "graph_category nginx\n"; ++ print "graph_category webserver\n"; + print "graph_vlabel Requests per \${graph_period}\n"; + print "request.type DERIVE\n"; + print "request.min 0\n"; +diff --git a/plugins/node.d/nginx_status.in b/plugins/node.d/nginx_status.in +index f69b6ab8d..1834dada4 100755 +--- a/plugins/node.d/nginx_status.in ++++ b/plugins/node.d/nginx_status.in +@@ -93,7 +93,7 @@ if ( exists $ARGV[0] and $ARGV[0] eq "autoconf" ) { + if ( exists $ARGV[0] and $ARGV[0] eq "config" ) { + print "graph_title Nginx status\n"; + print "graph_args --base 1000\n"; +- print "graph_category nginx\n"; ++ print "graph_category webserver\n"; + print "graph_vlabel Connections\n"; + + print "total.label Active connections\n"; diff --git a/274.patch b/274.patch deleted file mode 100644 index 6638a9e..0000000 --- a/274.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 4a39b56c7aefdd9794add4468c7dbe87ff683ce8 Mon Sep 17 00:00:00 2001 -From: Daniel Black -Date: Sun, 26 Oct 2014 17:36:29 +1100 -Subject: [PATCH] Run munin-asyncd fetching on wall clock type - -Patch by Picnic Pete: https://github.com/picnicpete ---- - node/_bin/munin-asyncd.in | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/node/_bin/munin-asyncd.in b/node/_bin/munin-asyncd.in -index 8efe50f..4811b2d 100644 ---- a/node/_bin/munin-asyncd.in -+++ b/node/_bin/munin-asyncd.in -@@ -160,9 +160,14 @@ MAIN: while($keepgoing) { - next; - } - -- # Should update it -- $last_updated{$plugin} = $when; -- $when_next = min($when_next, $when + max($plugin_rate, $minrate)); -+ # Should update it - based on wall clock time -+ my $should_have_been = $when - ($when % $plugin_rate); -+ my $should_be_next = $should_have_been + $plugin_rate; -+ -+ $last_updated{$plugin} = $should_have_been; -+ if ($should_be_next < $when_next) { -+ $when_next = $should_be_next; -+ } - - if ($do_fork && fork()) { - # parent, return directly diff --git a/Makefile.config-dist b/Makefile.config-dist deleted file mode 100644 index baa0663..0000000 --- a/Makefile.config-dist +++ /dev/null @@ -1,25 +0,0 @@ -include Makefile.config - -CGIDIR = $(DESTDIR)/var/www/cgi-bin -CGITMPDIR = /var/tmp -CHGRP := echo Not done: chgrp -CHMOD := echo Not done: chmod -CHOWN := echo Not done: chown -CONFDIR = $(DESTDIR)/etc/munin -DBDIR = $(DESTDIR)/var/lib/munin -DBDIRNODE = $(DESTDIR)/var/lib/munin-node -DOCDIR = $(DESTDIR)/usr/share/doc/munin-$(VERSION) -GROUP := nobody -HOSTNAME = localhost.localdomain -HTMLDIR = $(DESTDIR)/var/www/html/munin -JAVALIBDIR = $(DESTDIR)/usr/share/java -LIBDIR = $(DESTDIR)/usr/share/munin -LOGDIR = $(DESTDIR)/var/log/munin -PERLSITELIB := $(DESTDIR)/usr/share/perl5/vendor_perl -PERL := /usr/bin/perl -PLUGSTATE = $(DBDIR)/plugin-state -PREFIX = $(DESTDIR)/usr -PYTHON := /usr/bin/python -RUBY := /usr/bin/ruby -USER := nobody - diff --git a/bz1049262-ntp_.patch b/bz1049262-ntp_.patch deleted file mode 100644 index d26322f..0000000 --- a/bz1049262-ntp_.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- ./plugins/node.d/ntp_.in.orig 2014-03-26 18:45:21.374305323 -0500 -+++ ./plugins/node.d/ntp_.in 2015-03-06 22:31:31.154285245 -0600 -@@ -77,7 +77,7 @@ - if ($line =~ m/^\s*\d+/) { - my (undef, undef, $assid, undef, undef, undef, undef, undef, undef, undef) = split(/\s+/, $line); - chomp(my $peerinfo = `ntpq -n -c "readvar $assid srcadr"`); -- $peerinfo =~ s/\R/ /g; -+ $peerinfo =~ s/\n/ /g; - my ($peer_addr) = ($peerinfo =~ m/srcadr=(.*)/); - print $peer_addr, "\n" unless $peer_addr eq "0.0.0.0"; - } -@@ -114,7 +114,7 @@ - if ($line =~ m/^\s*\d+/) { - my (undef, undef, $assid, undef, undef, undef, undef, undef, undef, undef) = split(/\s+/, $line); - chomp(my $peerinfo = `ntpq -n -c "readvar $assid srcadr,delay,offset,jitter"`); -- $peerinfo =~ s/\R/ /g; -+ $peerinfo =~ s/\n/ /g; - ($srcadr) = ($peerinfo =~ m/srcadr=([^, ]+)/); - ($delay) = ($peerinfo =~ m/delay=([^, ]+)/); - ($offset) = ($peerinfo =~ m/offset=([^, ]+)/); -@@ -152,7 +152,7 @@ - if ($line =~ m/^\s*\d+/) { - my (undef, undef, $assid, undef, undef, undef, undef, undef, undef, undef) = split(/\s+/, $line); - chomp(my $peerinfo = `ntpq -n -c "readvar $assid srcadr,delay,offset,jitter"`); -- $peerinfo =~ s/\R/ /g; -+ $peerinfo =~ s/\n/ /g; - ($srcadr) = ($peerinfo =~ m/srcadr=([^, ]+)/); - ($delay) = ($peerinfo =~ m/delay=([^, ]+)/); - ($offset) = ($peerinfo =~ m/offset=([^, ]+)/); diff --git a/cd842e36f3ab1a55c05304d6b78dc07048bd8f84.patch b/cd842e36f3ab1a55c05304d6b78dc07048bd8f84.patch new file mode 100644 index 0000000..3f2ff29 --- /dev/null +++ b/cd842e36f3ab1a55c05304d6b78dc07048bd8f84.patch @@ -0,0 +1,36 @@ +diff -ur munin-2.0.42.orig/plugins/node.d/postfix_mailqueue.in munin-2.0.42/plugins/node.d/postfix_mailqueue.in +--- munin-2.0.42.orig/plugins/node.d/postfix_mailqueue.in 2018-09-21 05:11:11.000000000 +0300 ++++ munin-2.0.42/plugins/node.d/postfix_mailqueue.in 2018-09-30 13:33:21.825373214 +0300 +@@ -103,7 +103,7 @@ + cat <<'EOF' + graph_title Postfix Mailqueue + graph_vlabel Mails in queue +-graph_category postfix ++graph_category mail + graph_total Total + active.label active + deferred.label deferred +diff -ur munin-2.0.42.orig/plugins/node.d/postfix_mailstats.in munin-2.0.42/plugins/node.d/postfix_mailstats.in +--- munin-2.0.42.orig/plugins/node.d/postfix_mailstats.in 2018-09-21 05:11:11.000000000 +0300 ++++ munin-2.0.42/plugins/node.d/postfix_mailstats.in 2018-09-30 13:33:14.492320072 +0300 +@@ -141,7 +141,7 @@ + print "graph_vlabel mails / \${graph_period}\n"; + print "graph_scale no\n"; + print "graph_total Total\n"; +- print "graph_category postfix\n"; ++ print "graph_category mail\n"; + print "graph_period minute\n"; + print "delivered.label delivered\n"; + print "delivered.type DERIVE\n"; +diff -ur munin-2.0.42.orig/plugins/node.d/postfix_mailvolume.in munin-2.0.42/plugins/node.d/postfix_mailvolume.in +--- munin-2.0.42.orig/plugins/node.d/postfix_mailvolume.in 2018-09-21 05:11:11.000000000 +0300 ++++ munin-2.0.42/plugins/node.d/postfix_mailvolume.in 2018-09-30 13:33:06.602262890 +0300 +@@ -133,7 +133,7 @@ + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel bytes / \${graph_period}\n"; + print "graph_scale yes\n"; +- print "graph_category postfix\n"; ++ print "graph_category mail\n"; + print "volume.label delivered volume\n"; + print "volume.type DERIVE\n"; + print "volume.min 0\n"; diff --git a/cpuspeed.in.rev1243 b/cpuspeed.in.rev1243 deleted file mode 100644 index c5b4b3b..0000000 --- a/cpuspeed.in.rev1243 +++ /dev/null @@ -1,59 +0,0 @@ -#!@@GOODSH@@ -# -# Plugin to monitor CPU speed -# -# Usage: Place in /etc/munin/node.d/ (or link it there using ln -s) -# -# Parameters understood: -# -# config (required) -# autoconf (optional - used by munin-config) -# -# Magic markers - optional - used by installation scripts and -# munin-config: -# -#%# family=auto -#%# capabilities=autoconf - -if [ "$1" = "autoconf" ]; then - if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq ]; then - echo yes - exit 0 - else - echo no - exit 1 - fi -fi - - -if [ "$1" = "config" ]; then - cat < +Comment: Steve Schnepp + +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 +=bOn3 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/httpd_cgi_graphs.conf b/httpd_cgi_graphs.conf new file mode 100644 index 0000000..7a3787e --- /dev/null +++ b/httpd_cgi_graphs.conf @@ -0,0 +1,61 @@ +# Example configuration for Apache httpd with cgi generated graphs. +# +# To use this example config file you need to enable cgi graphs in Munin. Add +# following three lines to /etc/munin/conf.d/local.conf (without # character): +# +# graph_strategy cgi +# html_strategy cgi +# cgiurl_graph /munin/graph +# +# Then copy this file to /etc/httpd/conf.d/ directory and restart httpd. +# +# Access Munin at http://localhost/munin/ + + + + ServerName localhost + ServerAdmin root@localhost + ErrorLog /var/log/httpd/munin.localhost-error.log + CustomLog /var/log/httpd/munin.localhost-access.log combined + DocumentRoot /var/www/html + + # Rewrites for graph/html generated by cgi + RewriteEngine On + RewriteRule ^/munin/static/(.*) /var/www/html/munin/static/$1 [L] + RewriteRule ^/munin/graph/(.*) /munin-cgi/munin-cgi-graph/$1 [L,PT] + RewriteRule ^/munin/(.*) /munin-cgi/munin-cgi-html/$1 [L,PT] + RewriteRule ^/munin$ /munin/ [R] + ScriptAlias /munin-cgi/ /var/www/html/munin/cgi/ + + # FastCGI + + Options +ExecCGI + + SetHandler fcgid-script + + + SetHandler cgi-script + + + + + +# Uncomment following lines to require authentication: + +# +# AuthUserFile /etc/munin/munin-htpasswd +# AuthName "Munin" +# AuthType Basic +# Require valid-user +# # This next part requires mod_expires to be enabled. +# # +# # We could use around here, but I want it to be +# # as evident as possible that you either have to load mod_expires _or_ +# # you coment out/remove these lines. +# # +# # Set the default expiery time for files 5 minutes 10 seconds from +# # their creation (modification) time. There are probably new files by +# # that time. +# ExpiresActive On +# ExpiresDefault M310 +# diff --git a/httpd_cron_graphs.conf b/httpd_cron_graphs.conf new file mode 100644 index 0000000..ed34bf8 --- /dev/null +++ b/httpd_cron_graphs.conf @@ -0,0 +1,49 @@ +# Example configuration for Apache httpd with cron generated graphs. +# +# To use this example config simply copy this to /etc/httpd/conf.d/ +# directory and restart httpd. +# +# Access Munin at http://localhost/munin/ + + + + ServerName localhost + ServerAdmin root@localhost + ErrorLog /var/log/httpd/munin.localhost-error.log + CustomLog /var/log/httpd/munin.localhost-access.log combined + DocumentRoot /var/www/html + + ScriptAlias /munin-cgi/munin-cgi-graph /var/www/html/munin/cgi/munin-cgi-graph + + # FastCGI + + Options +ExecCGI + + SetHandler fcgid-script + + + SetHandler cgi-script + + + + + +# Uncomment following lines to require authentication: + +# +# AuthUserFile /etc/munin/munin-htpasswd +# AuthName "Munin" +# AuthType Basic +# Require valid-user +# # This next part requires mod_expires to be enabled. +# # +# # We could use around here, but I want it to be +# # as evident as possible that you either have to load mod_expires _or_ +# # you coment out/remove these lines. +# # +# # Set the default expiery time for files 5 minutes 10 seconds from +# # their creation (modification) time. There are probably new files by +# # that time. +# ExpiresActive On +# ExpiresDefault M310 +# diff --git a/httpd_munin-cgi.conf b/httpd_munin-cgi.conf deleted file mode 100644 index fed4640..0000000 --- a/httpd_munin-cgi.conf +++ /dev/null @@ -1,48 +0,0 @@ -# http://munin.readthedocs.org/en/latest/example/webserver/apache-virtualhost.html - - #ServerName munin.example.org - #ServerAlias munin - #ServerAdmin info@example.org - - DocumentRoot /var/www/html/munin - - ErrorLog /var/log/httpd/munin.example.org-error.log - CustomLog /var/log/httpd/munin.example.org-access.log combined - - # Rewrites - RewriteEngine On - - # Static content in /static - RewriteRule ^/favicon.ico /var/www/html/munin/static/favicon.ico [L] - RewriteRule ^/static/(.*) /var/www/html/munin/static/$1 [L] - - # workaround for some static content - RewriteRule /favicon.ico /var/www/html/munin/static/favicon.ico [L] - RewriteRule /static/(.*) /var/www/html/munin/static/$1 [L] - - # HTML - RewriteCond %{REQUEST_URI} .html$ [or] - RewriteCond %{REQUEST_URI} =/ - RewriteRule ^/(.*) /var/www/cgi-bin/munin-cgi-html/$1 [L] - - # Images - # - remove path to munin-cgi-graph, if present - RewriteRule ^/munin-cgi/munin-cgi-graph/(.*) /$1 - - RewriteCond %{REQUEST_URI} .png$ - RewriteRule ^/(.*) /var/www/cgi-bin/munin-cgi-graph/$1 [L] - - #ScriptAlias /munin-cgi/munin-cgi-graph /var/www/cgi-bin/munin-cgi-graph - - # Ensure we can run (fast)cgi scripts - - Options +ExecCGI - - SetHandler fcgid-script - - - SetHandler cgi-script - - - - diff --git a/linux-init.d_munin-asyncd.in b/linux-init.d_munin-asyncd.in deleted file mode 100644 index 239cea7..0000000 --- a/linux-init.d_munin-asyncd.in +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/bash -# -### BEGIN INIT INFO -# chkconfig: 2345 91 10 -# processname: munin-node -# config: /etc/munin/munin-node.conf -# pidfile: /var/run/munin-asyncd.pid -# Provides: munin-asyncd -# Required-Start: $local_fs $remote_fs $network munin-node -# Required-Stop: $local_fs $remote_fs $network -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Starts and stops munin-asyncd -# Description: munin-asyncd enables asyncronous fetching of -# metrics from munin-node in a Munin monitoring setup. -### END INIT INFO - -ASYNC_BIN=munin-asyncd -PATH=/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/usr/sbin/${ASYNC_BIN} -PIDFILE=/var/run/munin/${ASYNC_BIN}.pid - -is_running () { - if [ ! -e "$PIDFILE" ]; then - return 3 # No PID file exists, ${ASYNC_BIN} must not be running - else - kill -0 $(cat $PIDFILE) 2> /dev/null - if [ "$?" -eq "0" ]; then - return 0 # PID file exists, and PID found in file is in use - else - rm $PIDFILE 2> /dev/null - if [ "$?" -eq "0" ]; then - return 1 # PID file exists, but no process with the PID was found. Deletion of the PID file was a success - else - return 2 # PID file exists, but no process with the PID was found. Deletion of the PID file failed - fi - fi - fi -} - -check_root () { - operation=$1 - if [ "$(id -u)" -ne "0" ]; then - echo "Root permissions are required in order to perform the \"$operation\" operation." - exit 4 - fi -} - -sanity_check () { - if [ ! "$(type -p pidof)" ]; then - echo "The program \"pidof\" is required in order for this script to work properly, and will not run without it." - exit 1 - fi - - if [ ! -d "$(dirname $PIDFILE)" ]; then - mkdir -p $(dirname $PIDFILE) 2> /dev/null - if [ "$?" -ne "0" ]; then - echo "The directory for a PID file is missing ($(dirname $PIDFILE)), and could not be created automatically. Please correct this and try again." - exit 1 - fi - fi - - if [ ! -x "$DAEMON" ]; then - echo "${ASYNC_BIN} was expected at $DAEMON, but was not found. Are you sure Munin is correctly installed?" - exit 5 - fi -} - -case $1 in - start) - check_root $1 - sanity_check - - echo -n "Starting ${ASYNC_BIN} ... " - - is_running - if [ "$?" -eq "0" ]; then - echo "Already running (PID: $(cat $PIDFILE))." - exit 0 - fi - - $DAEMON > /dev/null 2> /dev/null < /dev/null & - - sleep 0.5 # Give ${ASYNC_BIN} time to fail, if it fails - - pid=$(pidof -o %PPID -x $DAEMON) - if [ "$?" -eq "0" ]; then - echo $pid > $PIDFILE - echo "Done." - exit 0 - else - echo "Start failed for some reason, restarting ${ASYNC_BIN} so you can see why:" - $DAEMON - echo - echo "A \"Connection refused\" message typically is because munin-node is not started prior to ${ASYNC_BIN}." - fi - ;; - stop) - check_root $1 - sanity_check - - echo -n "Stopping ${ASYNC_BIN} ... " - - # If a PID file is not found, we perform an extra check if ${ASYNC_BIN} still should be running, and if it does, then create a PID file - if [ ! -e "$PIDFILE" ]; then - pid=$(pidof -o %PPID -x $DAEMON) - if [ "$?" -eq "0" ]; then - echo $pid > $PIDFILE - fi - fi - - is_running - if [ "$?" -ne "0" ]; then - echo "Not running." - exit 0 - fi - - PID=$(cat $PIDFILE) - kill -15 $PID 2> /dev/null - HALFSECONDS="0" - while true; do - kill -0 $PID 2> /dev/null - if [ "$?" -eq "1" ]; then - break - fi - sleep 0.5 - HALFSECONDS=$(expr $HALFSECONDS + 1) - if [ "$HALFSECONDS" -ge "10" ]; then - kill -9 $PID 2> /dev/null - echo "Not stopping gracefully, killed!" - exit 0 - fi - done - echo "Done." - exit 0 - ;; - restart|try-restart|force-reload) - check_root $1 - sanity_check - - $0 stop - $0 start - - exit 0 - ;; - reload) - echo "The \"reload\" operation is not supported by ${ASYNC_BIN}. You probably want to run \"restart\" instead." - exit 3 - ;; - status) - is_running - return="$?" - if [ "$return" -eq "0" ]; then - echo "${ASYNC_BIN} is running (PID: $(cat $PIDFILE))." - exit 0 - elif [ "$return" -eq "1" ]; then - echo "${ASYNC_BIN} is not running, but PID file still existed (has been removed now)." - exit 1 - elif [ "$return" -eq "2" ]; then - echo "${ASYNC_BIN} is not running, but PID file still exists (could not be removed)." - exit 1 - elif [ "$return" -eq "3" ]; then - echo "${ASYNC_BIN} is not running." - exit 3 - fi - exit 4 - ;; - *) - echo "Usage: $0 {start|stop|restart|try-restart|force-reload|reload|status}" - exit 2 - ;; -esac diff --git a/mariadb-innodb.patch b/mariadb-innodb.patch deleted file mode 100644 index d2a2f65..0000000 --- a/mariadb-innodb.patch +++ /dev/null @@ -1,45 +0,0 @@ -commit 997d82d30040dc9749db46823a933555e586e645 -Author: Daniel Black -Date: Thu Jan 30 11:34:54 2014 +1100 - - Break mysql innodb data on full sections - - Patch from Jan Mara - https://github.com/jmara/ubuntu-munin-mysql/commit/77ae2b2d8bc1233e0f0b0e6346d66b955441ba14 - -diff --git a/plugins/node.d/mysql_.in b/plugins/node.d/mysql_.in -index 3376036..fb70e24 100644 ---- a/plugins/node.d/mysql_.in -+++ b/plugins/node.d/mysql_.in -@@ -1070,7 +1070,7 @@ sub parse_innodb_status { - - # Add a dummy section to the end in case the innodb status output - # has been truncated (Happens for status > 64K characters) -- $_ .= "\n----------\nDUMMY\n"; -+ $_ .= "\n----------\nDUMMY\n----------\n"; - - my %section_map = ( - -@@ -1114,7 +1114,12 @@ sub parse_innodb_status { - my $innodb_bigint_rx = qr{([[a-fA-F\d]+)(?: (\d+))?}; - - --sub match_dashes { return m/\G-+\n(?!-)/gc; } -+sub match_new_section { -+ return m/\G -+ -+\n # --------------------------- -+ (?= [A-Z\/ ]+\n # SECTION NAME -+ [=-]+\n)/gcx; # --------------------------- ('=' on end of output) -+} - - - sub skip_line { return m/\G.*\n/gc; } -@@ -1133,7 +1138,7 @@ sub parse_section { - - #warn substr($_, pos(), 10); - for (;;) { -- return if match_dashes(); -+ return if match_new_section; - next if $parser->(); - skip_line(); - } diff --git a/mariadb-show-status.patch b/mariadb-show-status.patch deleted file mode 100644 index c5218bd..0000000 --- a/mariadb-show-status.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit e5f12ef57c75d37aa2e3444cc448598f3c32b0ea -Author: Daniel Black -Date: Tue Jun 17 11:45:13 2014 +1000 - - Mariadb-10 show innodb status compatiblity - - show innodb status on mariadb-10 if in a transaction will show - - -------------- - ROW OPERATIONS - -------------- - 0 queries inside InnoDB, 0 queries in queue - 1 read views open inside InnoDB - 1 RW transactions active inside InnoDB - 0 RO transactions active inside InnoDB - 1 out of 1000 descriptors used - ---OLDEST VIEW--- - Normal read view - Read view low limit trx n:o 726056894 - Read view up limit trx id 726056894 - Read view low limit trx id 726056894 - Read view individually stored trx ids: - ----------------- - Main thread process no. 13048, id 140163878000384, state: sleeping - Number of rows inserted 0, updated 0, deleted 0, read 1666121005 - 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 17566.53 reads/s - ------------ - - In this patch we just skip sections like "Main thread process.." that we - don't know about. - -diff --git a/plugins/node.d/mysql_.in b/plugins/node.d/mysql_.in -index 9b6914b..1d83115 100644 ---- a/plugins/node.d/mysql_.in -+++ b/plugins/node.d/mysql_.in -@@ -1102,8 +1102,12 @@ sub parse_innodb_status { - last; - } - -- die "Unknown section: $1" unless exists $section_map{$sec}; -- die "Parse error. Expected a section separator" unless m/\G-+\n/gc; -+ if (exists $section_map{$sec}) { -+ $section_map{$sec}->(); -+ } else { -+ #warn "Unknown section: $1"; -+ skip(); -+ } - - $section_map{$sec}->(); - } diff --git a/munin-1.2.4-sendmail-config b/munin-1.2.4-sendmail-config deleted file mode 100644 index e062fbb..0000000 --- a/munin-1.2.4-sendmail-config +++ /dev/null @@ -1,3 +0,0 @@ -[sendmail*] -user root -env.mspqueue /var/spool/clientmqueue diff --git a/munin-1.2.5-hddtemp_smartctl-config b/munin-1.2.5-hddtemp_smartctl-config deleted file mode 100644 index dcdb2b6..0000000 --- a/munin-1.2.5-hddtemp_smartctl-config +++ /dev/null @@ -1,2 +0,0 @@ -[hddtemp_smartctl] -user root diff --git a/munin-1.2.6-postfix-config b/munin-1.2.6-postfix-config deleted file mode 100644 index 8a63875..0000000 --- a/munin-1.2.6-postfix-config +++ /dev/null @@ -1,4 +0,0 @@ -[postfix*] -user root -env.logfile maillog -env.logdir /var/log diff --git a/munin-1.4.5-df-config b/munin-1.4.5-df-config deleted file mode 100644 index b4f0ef5..0000000 --- a/munin-1.4.5-df-config +++ /dev/null @@ -1,2 +0,0 @@ -[df*] -env.exclude none unknown binfmt_misc debugfs devtmpfs fuse.gvfs-fuse-daemon iso9660 ramfs romfs rpc_pipefs squashfs tmpfs udf diff --git a/munin-2.0.25-postgresql-config b/munin-2.0.25-postgresql-config deleted file mode 100644 index ce59c44..0000000 --- a/munin-2.0.25-postgresql-config +++ /dev/null @@ -1,6 +0,0 @@ -[postgres_*] - -# for more detail run "man Munin::Plugin::Pgsql" -user postgres -env.PGUSER postgres -env.PGPORT 5432 diff --git a/munin-2.0.33.tar.gz.sha256sum b/munin-2.0.33.tar.gz.sha256sum deleted file mode 100644 index eed39ff..0000000 --- a/munin-2.0.33.tar.gz.sha256sum +++ /dev/null @@ -1 +0,0 @@ -1c6f994bf62d6dee89554efba0733b6f96d4130ba906162c32f77587088974c4 munin-2.0.33.tar.gz diff --git a/munin-2.0.4-Utils-cluck.patch b/munin-2.0.4-Utils-cluck.patch deleted file mode 100644 index 5ba660a..0000000 --- a/munin-2.0.4-Utils-cluck.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- master/lib/Munin/Master/Utils.pm.orig 2012-07-30 09:25:33.000000000 -0500 -+++ master/lib/Munin/Master/Utils.pm 2012-08-05 14:07:57.236121331 -0500 -@@ -904,6 +904,9 @@ - - my $storable_filename_tmp = $storable_filename . ".tmp.$$"; - -+ use Carp qw(cluck); -+ cluck "data is null at " unless $data; -+ - # Write datafile.storable, in network order to be architecture indep - Storable::nstore($data, $storable_filename_tmp); - diff --git a/munin-2.0.9-amavis-config b/munin-2.0.9-amavis-config deleted file mode 100644 index 0a7f0ba..0000000 --- a/munin-2.0.9-amavis-config +++ /dev/null @@ -1,4 +0,0 @@ -[amavis] -group adm -env.MUNIN_MKTEMP /bin/mktemp -p /tmp/ $1 -env.amavislog /var/log/mail.info diff --git a/munin-2.0.9_HTMLConfig.pm.patch b/munin-2.0.9_HTMLConfig.pm.patch deleted file mode 100644 index 3abae3a..0000000 --- a/munin-2.0.9_HTMLConfig.pm.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -ru munin-2.0.9.orig/master/lib/Munin/Master/HTMLConfig.pm munin-2.0.9/master/lib/Munin/Master/HTMLConfig.pm ---- munin-2.0.9.orig/master/lib/Munin/Master/HTMLConfig.pm 2012-12-05 13:19:35.000000000 -0600 -+++ munin-2.0.9/master/lib/Munin/Master/HTMLConfig.pm 2012-12-20 21:37:22.364028610 -0600 -@@ -499,11 +499,11 @@ - my $start_year = $epoch_now - (3600 * 24 * 400); - my $size_x = 800; - my $size_y = 400; -- my $common_url = "$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y"; -- $srv{zoomday} = "$common_url&start_epoch=$start_day&stop_epoch=$epoch_now"; -- $srv{zoomweek} = "$common_url&start_epoch=$start_week&stop_epoch=$epoch_now"; -- $srv{zoommonth} = "$common_url&start_epoch=$start_month&stop_epoch=$epoch_now"; -- $srv{zoomyear} = "$common_url&start_epoch=$start_year&stop_epoch=$epoch_now"; -+ my $common_url = "$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y"; -+ $srv{zoomday} = "$common_url&start_epoch=$start_day&stop_epoch=$epoch_now"; -+ $srv{zoomweek} = "$common_url&start_epoch=$start_week&stop_epoch=$epoch_now"; -+ $srv{zoommonth} = "$common_url&start_epoch=$start_month&stop_epoch=$epoch_now"; -+ $srv{zoomyear} = "$common_url&start_epoch=$start_year&stop_epoch=$epoch_now"; - } - - for my $scale (@times) { diff --git a/munin-asyncd.service b/munin-asyncd.service index 6a73b77..00ced51 100644 --- a/munin-asyncd.service +++ b/munin-asyncd.service @@ -1,14 +1,20 @@ [Unit] -Description=Munin Async Server. -Documentation=man:munin-node +Description=Munin Node - Asynchronous Proxy +Documentation=http://guide.munin-monitoring.org/en/latest/node/async.html Requires=munin-node.service -After=network-online.target munin-node.service -Wants=network-online.target +After=network.target +After=network-online.target +After=munin-node.service [Service] -Type=simple +Type=notify +User=munin ExecStart=/usr/sbin/munin-asyncd -PrivateTmp=true +PrivateDevices=yes +PrivateTmp=yes +ProtectHome=yes +ProtectSystem=full +TimeoutStopSec=20s [Install] WantedBy=multi-user.target diff --git a/munin-cgi-graph.service b/munin-cgi-graph.service new file mode 100644 index 0000000..36ab23f --- /dev/null +++ b/munin-cgi-graph.service @@ -0,0 +1,8 @@ +[Unit] +Description=Munin FastCGI Graphs Service +Requires=munin-cgi-graph.socket + +[Service] +User=munin +ExecStart=/var/www/html/munin/cgi/munin-cgi-graph +StandardInput=socket diff --git a/munin-cgi-graph.socket b/munin-cgi-graph.socket new file mode 100644 index 0000000..85bfae8 --- /dev/null +++ b/munin-cgi-graph.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Munin FastCGI Graphs Socket + +[Socket] +ListenStream=/run/munin/munin-cgi-graph.sock +SocketMode=0660 +SocketUser=nginx +SocketGroup=munin + +[Install] +WantedBy=sockets.target diff --git a/munin-cgi-html.service b/munin-cgi-html.service new file mode 100644 index 0000000..9859960 --- /dev/null +++ b/munin-cgi-html.service @@ -0,0 +1,8 @@ +[Unit] +Description=Munin FastCGI HTML Pages Service +Requires=munin-cgi-html.socket + +[Service] +User=munin +ExecStart=/var/www/html/munin/cgi/munin-cgi-html +StandardInput=socket diff --git a/munin-cgi-html.socket b/munin-cgi-html.socket new file mode 100644 index 0000000..3dcdec6 --- /dev/null +++ b/munin-cgi-html.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Munin FastCGI HTML Pages Socket + +[Socket] +ListenStream=/run/munin/munin-cgi-html.sock +SocketMode=0660 +SocketUser=nginx +SocketGroup=munin + +[Install] +WantedBy=sockets.target diff --git a/munin-fcgi-graph.rc b/munin-fcgi-graph.rc deleted file mode 100644 index 195281c..0000000 --- a/munin-fcgi-graph.rc +++ /dev/null @@ -1,56 +0,0 @@ -#! /bin/sh -# -# munin-fcgi-graph -# -# chkconfig: 2345 90 10 -# description: munin fcgi graph service process -# pidfile: /var/run/munin/fcgi-graph.pid - -# Source function library. -. /etc/rc.d/init.d/functions - -RETVAL=0 - -mkdir -p /var/run/munin 2>/dev/null -chown munin /var/run/munin -restorecon /var/run/munin 2>/dev/null - -# See how we were called. -case "$1" in - start) - echo -n "Starting Munin fcgi-graph: " - /usr/bin/spawn-fcgi -s /var/run/munin/fcgi-graph.sock -u munin -g munin /var/www/cgi-bin/munin-cgi-graph -P /var/run/munin/fcgi-graph.pid - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - touch /var/lock/subsys/munin-fcgi-graph - else - echo_failure - fi - echo - ;; - stop) - echo -n "Stopping Munin fcgi-graph: " - kill $(cat /var/run/munin/fcgi-graph.pid) - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - rm -f /var/lock/subsys/munin-fcgi-graph - else - echo_failure - fi - echo - ;; - restart|reload) - $0 stop - $0 start - RETVAL=$? - ;; - *) - echo "Usage: munin-fcgi-graph {start|stop|restart}" - exit 1 -esac - -exit $RETVAL diff --git a/munin-fcgi-graph.service b/munin-fcgi-graph.service deleted file mode 100644 index 800d13a..0000000 --- a/munin-fcgi-graph.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Munin FastCGI Graph -Documentation=man:spawn-fcgi - -[Service] -Type=forking -PIDFile=/run/munin/fcgi-graph.pid -ExecStart=/usr/bin/spawn-fcgi -s /run/munin/fcgi-graph.sock -u munin -g munin /var/www/cgi-bin/munin-cgi-graph -P /run/munin/fcgi-graph.pid - -[Install] -WantedBy=multi-user.target diff --git a/munin-fcgi-html.rc b/munin-fcgi-html.rc deleted file mode 100644 index 879ea4f..0000000 --- a/munin-fcgi-html.rc +++ /dev/null @@ -1,56 +0,0 @@ -#! /bin/sh -# -# munin-fcgi-html -# -# chkconfig: 2345 90 10 -# description: munin fcgi html service process -# pidfile: /var/run/munin/fcgi-html.pid - -# Source function library. -. /etc/rc.d/init.d/functions - -RETVAL=0 - -mkdir -p /var/run/munin 2>/dev/null -chown munin /var/run/munin -restorecon /var/run/munin 2>/dev/null - -# See how we were called. -case "$1" in - start) - echo -n "Starting Munin fcgi-html: " - /usr/bin/spawn-fcgi -s /var/run/munin/fcgi-html.sock -u munin -g munin /var/www/cgi-bin/munin-cgi-html -P /var/run/munin/fcgi-html.pid - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - touch /var/lock/subsys/munin-fcgi-html - else - echo_failure - fi - echo - ;; - stop) - echo -n "Stopping Munin fcgi-html: " - kill $(cat /var/run/munin/fcgi-html.pid) - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - rm -f /var/lock/subsys/munin-fcgi-html - else - echo_failure - fi - echo - ;; - restart|reload) - $0 stop - $0 start - RETVAL=$? - ;; - *) - echo "Usage: munin-fcgi-html {start|stop|restart}" - exit 1 -esac - -exit $RETVAL diff --git a/munin-fcgi-html.service b/munin-fcgi-html.service deleted file mode 100644 index 3fa4640..0000000 --- a/munin-fcgi-html.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Munin FastCGI HTML -Documentation=man:spawn-fcgi - -[Service] -Type=forking -PIDFile=/run/munin/fcgi-html.pid -ExecStart=/usr/bin/spawn-fcgi -s /run/munin/fcgi-html.sock -u munin -g munin /var/www/cgi-bin/munin-cgi-html -P /run/munin/fcgi-html.pid - -[Install] -WantedBy=multi-user.target diff --git a/munin-node b/munin-node new file mode 100644 index 0000000..34083c3 --- /dev/null +++ b/munin-node @@ -0,0 +1,5 @@ +# We moved the default config to file 00-default +# as config files in this directory are read in alphabetical order. +# +# Documentation can be found in Munin-Guide: +# http://guide.munin-monitoring.org/en/latest/plugin/use.html#configuring diff --git a/munin-node.conf b/munin-node.conf new file mode 100644 index 0000000..1d4fb01 --- /dev/null +++ b/munin-node.conf @@ -0,0 +1,65 @@ +# +# Example config file for munin-node. You don't have to edit anything in +# this file if you are using munin-asyncd. +# + +log_level 4 +log_file /var/log/munin-node/munin-node.log +pid_file /var/run/munin/munin-node.pid + +background 1 +setsid 1 + +user root +group root + +# This is the timeout for the whole transaction. +# Units are in sec. Default is 15 min +# +# global_timeout 900 + +# This is the timeout for each plugin. +# Units are in sec. Default is 1 min +# +# timeout 60 + +# Regexps for files to ignore +ignore_file [\#~]$ +ignore_file DEADJOE$ +ignore_file \.bak$ +ignore_file %$ +ignore_file \.dpkg-(tmp|new|old|dist)$ +ignore_file \.rpm(save|new|orig)$ +ignore_file \.pod$ + +# Set this if the client doesn't report the correct hostname when +# telnetting to localhost, port 4949 +# +#host_name localhost.localdomain + +# A list of addresses that are allowed to connect. This must be a +# regular expression, since Net::Server does not understand CIDR-style +# network notation unless the perl module Net::CIDR is installed. You +# may repeat the allow line as many times as you'd like + +allow ^127\.0\.0\.1$ +allow ^::1$ + +# If you have installed the Net::CIDR perl module, you can use one or more +# cidr_allow and cidr_deny address/mask patterns. A connecting client must +# match any cidr_allow, and not match any cidr_deny. Note that a netmask +# *must* be provided, even if it's /32 +# +# Example: +# +#cidr_allow 127.0.0.1/32 +#cidr_allow 192.0.2.0/24 +#cidr_deny 192.0.2.42/32 + +# Which address to bind to; +host * +#host 127.0.0.1 + +# And which port +port 4949 + diff --git a/munin-node.logrotate b/munin-node.logrotate index 843cd28..c674db4 100644 --- a/munin-node.logrotate +++ b/munin-node.logrotate @@ -1,10 +1,5 @@ /var/log/munin-node/munin-node.log { - daily missingok - rotate 7 - compress - copytruncate notifempty - create 644 root root - su root root + copytruncate } diff --git a/munin-node.rc b/munin-node.rc deleted file mode 100644 index 9104680..0000000 --- a/munin-node.rc +++ /dev/null @@ -1,65 +0,0 @@ -#! /bin/sh -# -# munin-node Control the Munin Node Server (formerly Linpro RRD client) -# -# chkconfig: 2345 90 10 -# description: munin node agents -# processname: munin-node -# config: /etc/munin/munin-node.conf -# pidfile: /var/run/munin/munin-node.pid - -# Source function library. -. /etc/rc.d/init.d/functions - -RETVAL=0 -PROCNAME=munin-node - -mkdir -p /var/run/munin 2>/dev/null -chown munin /var/run/munin -restorecon /var/run/munin 2>/dev/null - -# See how we were called. -case "$1" in - start) - echo -n "Starting Munin Node: " - /usr/sbin/munin-node & - sleep 1 - pkill -0 $PROCNAME - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - touch /var/lock/subsys/munin-node - else - echo_failure - fi - echo - ;; - stop) - echo -n "Stopping Munin Node agents: " - kill $(cat /var/run/munin/munin-node.pid) - RETVAL=$? - if [ $RETVAL -eq 0 ] - then - echo_success - rm -f /var/lock/subsys/munin-node - else - echo_failure - fi - echo - ;; - status) - status $PROCNAME - RETVAL=$? - ;; - restart|reload) - $0 stop - $0 start - RETVAL=$? - ;; - *) - echo "Usage: munin-node {start|stop|status|restart}" - exit 1 -esac - -exit $RETVAL diff --git a/munin-node.service b/munin-node.service index ac7257e..115856a 100644 --- a/munin-node.service +++ b/munin-node.service @@ -1,11 +1,18 @@ [Unit] -Description=Munin Node Server. -After=syslog.target network.target +Description=Munin Node +Documentation=man:munin-node(1) http://guide.munin-monitoring.org/en/latest/node/index.html +After=network.target +After=network-online.target +PartOf=munin-asyncd.service [Service] -Type=forking -PIDFile=/var/run/munin/munin-node.pid -ExecStart=/usr/sbin/munin-node +Type=notify +ExecStart=/usr/sbin/munin-node --foreground +PrivateDevices=no +PrivateTmp=yes +ProtectHome=read-only +ProtectSystem=full +TimeoutStopSec=30s [Install] WantedBy=multi-user.target diff --git a/munin-node.service-privatetmp b/munin-node.service-privatetmp deleted file mode 100644 index 87c1347..0000000 --- a/munin-node.service-privatetmp +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Munin Node Server. -Documentation=man:munin-node -After=network-online.target -Wants=network-online.target - -[Service] -Type=forking -PIDFile=/var/run/munin/munin-node.pid -ExecStart=/usr/sbin/munin-node -PrivateTmp=true - -[Install] -WantedBy=multi-user.target diff --git a/munin-rrdcached.service b/munin-rrdcached.service new file mode 100644 index 0000000..c803b7e --- /dev/null +++ b/munin-rrdcached.service @@ -0,0 +1,18 @@ +[Unit] +Description=Munin RRDtool Cache +After=network.target + +[Service] +User=munin +ExecStart=/usr/bin/rrdcached \ + -g -p /run/munin/munin-rrdcached.pid \ + -m 0660 -l unix:/run/munin/rrdcached.sock \ + -w 1800 -z 1800 -f 3600 \ + -B -b /var/lib/munin/ \ + -F -j /var/lib/munin/rrdcached/ +PIDFile=/run/munin/munin-rrdcached.pid +StandardOutput=null +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/munin-run_no_systemd.patch b/munin-run_no_systemd.patch new file mode 100644 index 0000000..6b7a80e --- /dev/null +++ b/munin-run_no_systemd.patch @@ -0,0 +1,28 @@ +diff -ur munin-2.0.63.orig/node/sbin/munin-run munin-2.0.63/node/sbin/munin-run +--- munin-2.0.63.orig/node/sbin/munin-run 2020-05-27 23:52:55.000000000 +0300 ++++ munin-2.0.63/node/sbin/munin-run 2020-07-04 10:55:27.079868324 +0300 +@@ -31,7 +31,7 @@ + # --pipe: 235 or later + # --collect: 236 or later + +-my $REQUIRED_SYSTEMD_VERSION = 236; ++my $REQUIRED_SYSTEMD_VERSION = 999; + + # See "man systemd.exec" for the list of all systemd properties. + # The following properties belong to the relevant sections "Capabilities", +@@ -50,7 +50,6 @@ + EnvironmentFile + Group + Limit\w+ +- LockPersonality + MemoryDenyWriteExecute + MountFlags + NetworkNamespacePath +@@ -189,6 +188,7 @@ + # "systemd show" does not output the EnvironmentFile property in a readable format. + # See https://github.com/systemd/systemd/issues/14723. + next if ($property_definition =~ /^EnvironmentFiles?=(.*) \(ignore_errors=(yes|no)\)$/); ++ next if ($property_definition =~ /^RestrictSUIDSGID=/); + push @flag_list, $1 if $property_definition =~ /$flag_name_regex/; + } + return @flag_list; diff --git a/munin.conf b/munin.conf index f3c7348..ee4aa79 100644 --- a/munin.conf +++ b/munin.conf @@ -1 +1,156 @@ -D /var/run/munin 0755 munin munin - +########################################################################### +# # +# Please don't edit this example config file. Create and edit # +# file /etc/munin/munin-conf.d/local.conf instead. # +# # +# You must also install munin-nginx or munin-apache sub-package. See # +# /usr/share/doc/munin-*/*.conf for example nginx/apache config files # +# and installation instructions. # +# # +########################################################################### + +# The next three variables specifies where the location of the RRD +# databases, the HTML output, logs and the lock/pid files. They all +# must be writable by the user running munin-cron. They are all +# defaulted to the values you see here. +# +#dbdir /var/lib/munin +#htmldir /var/www/html/munin +#logdir /var/log/munin +#rundir /run/munin + +# Where to look for the HTML templates +# +#tmpldir /etc/munin/templates + +# Where to look for the static www files +# +#staticdir /etc/munin/static + +# Temporary cgi files are here. Note that it has to be writable by the cgi +# user (usually apache). +# +#cgitmpdir /var/lib/munin/cgi-tmp + +# (Exactly one) directory to include all files from. +includedir /etc/munin/munin-conf.d + +# You can choose the time reference for "DERIVE" like graphs, and show +# "per minute", "per hour" values instead of the default "per second" +# +#graph_period second + +# Graphics files are generated either via cron or by a CGI process. +# See http://munin-monitoring.org/wiki/CgiHowto2 for more +# documentation. +# Since 2.0, munin-graph has been rewritten to use the cgi code. +# It is single threaded *by design* now. +# +#graph_strategy cron + +# munin-cgi-graph is invoked by the web server up to very many times at the +# same time. This is not optimal since it results in high CPU and memory +# consumption to the degree that the system can thrash. Again the default is +# 6. Most likely the optimal number for max_cgi_graph_jobs is the same as +# max_graph_jobs. +# +#munin_cgi_graph_jobs 6 + +# If the automatic CGI url is wrong for your system override it here: +# +#cgiurl_graph /munin-cgi/munin-cgi-graph + +# max_size_x and max_size_y are the max size of images in pixel. +# Default is 4000. Do not make it too large otherwise RRD might use all +# RAM to generate the images. +# +#max_size_x 4000 +#max_size_y 4000 + +# HTML files are normally generated by munin-html, no matter if the +# files are used or not. You can change this to on-demand generation +# by following the instructions in http://munin-monitoring.org/wiki/CgiHowto2 +# +# Notes: +# - moving to CGI for HTML means you cannot have graph generated by cron. +# - cgi html has some bugs, mostly you still have to launch munin-html by hand +# +#html_strategy cron + +# munin-update runs in parallel. +# +# The default max number of processes is 16, and is probably ok for you. +# +# If set too high, it might hit some process/ram/filedesc limits. +# If set too low, munin-update might take more than 5 min. +# +# If you want munin-update to not be parallel set it to 0. +# +#max_processes 16 + +# RRD updates are per default, performed directly on the rrd files. +# To reduce IO and enable the use of the rrdcached, uncomment it and set it to +# the location of the socket that rrdcached uses. +# +#rrdcached_socket /run/munin/rrdcached.sock + +# Drop somejuser@fnord.comm and anotheruser@blibb.comm an email everytime +# something changes (OK -> WARNING, CRITICAL -> OK, etc) +#contact.someuser.command mail -s "Munin ${var:worst}: ${var:group}::${var:host}::${var:plugin}" somejuser@fnord.comm +#contact.anotheruser.command mail -s "Munin ${var:worst}: ${var:group}::${var:host}::${var:plugin}" anotheruser@blibb.comm +# +# For those with Nagios, the following might come in handy. In addition, +# the services must be defined in the Nagios server as well. +#contact.nagios.command /usr/bin/send_nsca nagios.host.comm -c /etc/nsca.conf + +# +# A simple host tree +# +# [localhost] +# address 127.0.0.1 +# use_node_name yes + +# +# A more complex example of a host tree +# +## First our "normal" host. +# [fii.foo.com] +# address foo +# +## Then our other host... +# [fay.foo.com] +# address fay +# +## IPv6 host. note that the ip address has to be in brackets +# [ip6.foo.com] +# address [2001::1234:1] +# +## Then we want totals... +# [foo.com;Totals] #Force it into the "foo.com"-domain... +# update no # Turn off data-fetching for this "host". +# +# # The graph "load1". We want to see the loads of both machines... +# # "fii=fii.foo.com:load.load" means "label=machine:graph.field" +# load1.graph_title Loads side by side +# load1.graph_order fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# +# # The graph "load2". Now we want them stacked on top of each other. +# load2.graph_title Loads on top of each other +# load2.dummy_field.stack fii=fii.foo.com:load.load fay=fay.foo.com:load.load +# load2.dummy_field.draw AREA # We want area instead the default LINE2. +# load2.dummy_field.label dummy # This is needed. Silly, really. +# +# # The graph "load3". Now we want them summarised into one field +# load3.graph_title Loads summarised +# load3.combined_loads.sum fii.foo.com:load.load fay.foo.com:load.load +# load3.combined_loads.label Combined loads # Must be set, as this is +# # not a dummy field! +# +## ...and on a side note, I want them listen in another order (default is +## alphabetically) +# +# # Since [foo.com] would be interpreted as a host in the domain "com", we +# # specify that this is a domain by adding a semicolon. +# [foo.com;] +# node_order Totals fii.foo.com fay.foo.com +# diff --git a/munin.cron.d b/munin.cron.d deleted file mode 100644 index 9f15408..0000000 --- a/munin.cron.d +++ /dev/null @@ -1,7 +0,0 @@ -# -# cron-jobs for munin -# - -MAILTO=root - -*/5 * * * * munin test -x /usr/bin/munin-cron && /usr/bin/munin-cron diff --git a/munin.logrotate b/munin.logrotate index 11abd53..109748b 100644 --- a/munin.logrotate +++ b/munin.logrotate @@ -1,39 +1,9 @@ +/var/log/munin/munin-cgi-graph.log +/var/log/munin/munin-cgi-html.log +/var/log/munin/munin-graph.log +/var/log/munin/munin-html.log +/var/log/munin/munin-limits.log /var/log/munin/munin-update.log { - daily - missingok - rotate 7 - compress - notifempty - create 640 munin munin - su munin munin -} - -/var/log/munin/munin-graph.log { - daily - missingok - rotate 7 - compress - notifempty - create 640 munin munin - su munin munin -} - -/var/log/munin/munin-html.log { - daily - missingok - rotate 7 - compress - notifempty - create 640 munin munin - su munin munin -} - -/var/log/munin/munin-limits.log { - daily - missingok - rotate 7 - compress - notifempty - create 640 munin munin - su munin munin + missingok + notifempty } diff --git a/munin.service b/munin.service new file mode 100644 index 0000000..75be8bb --- /dev/null +++ b/munin.service @@ -0,0 +1,15 @@ +[Unit] +Description=Munin server to collect data from nodes +Documentation=man:munin-cron(8) +After=network.target +After=network-online.target +After=munin-node.service +After=munin-rrdcached.service + +[Service] +User=munin +ExecStart=/usr/bin/munin-cron +PrivateDevices=no +PrivateTmp=yes +ProtectHome=yes +ProtectSystem=full diff --git a/munin.spec b/munin.spec index 2aa86ea..85e913d 100644 --- a/munin.spec +++ b/munin.spec @@ -1,166 +1,111 @@ Name: munin -Version: 2.0.33 -Release: 1%{?dist} -Summary: Network-wide graphing framework (grapher/gatherer) - -Group: System Environment/Daemons -License: GPLv2 +Version: 2.0.76 +Release: 10%{?dist} +Summary: Network-wide resource monitoring tool +License: GPL-2.0-only URL: http://munin-monitoring.org/ -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + Source0: http://downloads.munin-monitoring.org/munin/stable/%{version}/%{name}-%{version}.tar.gz -Source10: http://downloads.munin-monitoring.org/munin/stable/%{version}/%{name}-%{version}.tar.gz.sha256sum -Source1: munin-1.2.4-sendmail-config -Source2: munin-1.2.5-hddtemp_smartctl-config -Source3: munin-node.logrotate -Source4: munin.logrotate -Source6: munin-1.2.6-postfix-config -Source7: munin-1.4.5-df-config -Source8: munin-node.service -Source9: %{name}.conf -Source11: munin-node.service-privatetmp -# BZ#747663 http://munin-monitoring.org/ticket/1155 -Source12: cpuspeed.in.rev1243 -Source13: linux-init.d_munin-asyncd.in -Source14: munin-asyncd.service -Source15: munin-fcgi-html.service -Source16: munin-fcgi-graph.service -Source17: munin.cron.d -Source18: munin-node.rc -Source19: httpd_munin-cgi.conf -Source20: Makefile.config-dist -Source21: nginx_munin.conf -Source22: munin-fcgi-html.rc -Source23: munin-fcgi-graph.rc -Source24: munin-2.0.9-amavis-config -Source25: munin-node.xml -Source26: munin-2.0.25-postgresql-config +Source1: http://downloads.munin-monitoring.org/munin/stable/%{version}/%{name}-%{version}.tar.gz.asc +# fpr=910846ADEE4C5D67C19B3E6F0A24C05998BA4133 +# gpg --recv-keys $fpr +# gpg -a --export-options export-minimal --export $fpr > gpgkey-$fpr.asc +Source2: gpgkey-910846ADEE4C5D67C19B3E6F0A24C05998BA4133.asc -#Patch1: munin-1.4.6-restorecon.patch -#Patch2: munin-1.4.2-fontfix.patch -Patch4: munin-2.0.4-Utils-cluck.patch -#Patch5: acpi-2.0.5.patch -#Patch6: munin-2.0.7-http_loadtime.patch -#Patch7: munin-2.0-defect-1213.patch -#Patch8: munin-2.0.2-defect-1245-LimitsOld.pm-notify_alias.patch -#Patch9: munin-2.0.8-cgitmp.patch -# BZ# 877116 Patch using '&' in the URLs instead of '&' in HTMLConfig -Patch10: munin-2.0.9_HTMLConfig.pm.patch -Patch11: https://github.com/munin-monitoring/munin/pull/274.patch -Patch12: bz1049262-ntp_.patch -Patch13: mariadb-show-status.patch -Patch14: mariadb-innodb.patch -#Patch15: https://patch-diff.githubusercontent.com/raw/munin-monitoring/munin/pull/737.patch -#Patch16: https://patch-diff.githubusercontent.com/raw/munin-monitoring/munin/pull/759.patch -#Patch17: https://patch-diff.githubusercontent.com/raw/munin-monitoring/munin/pull/797.patch +# Master sources +Source10: munin.conf +Source11: munin.logrotate +Source12: munin.tmpfilesd +Source13: munin.timer +Source14: munin.service +Source15: munin-rrdcached.service +Source16: httpd_cgi_graphs.conf +Source17: httpd_cron_graphs.conf +Source18: nginx_cgi_graphs.conf -BuildArch: noarch +# Node sources +Source20: munin-node.conf +Source21: munin-node.logrotate +Source23: munin-node.service +Source25: munin-asyncd.service +Source26: munin-node.xml -%if 0%{?fedora} > 20 -BuildRequires: /usr/bin/hostname -%else -BuildRequires: /bin/hostname -%endif -BuildRequires: perl >= 5.8 -%if 0%{?rhel} > 6 || 0%{?fedora} > 12 -BuildRequires: perl(Directory::Scratch) -%endif -BuildRequires: perl(Module::Build) -BuildRequires: perl(Net::Server) -BuildRequires: perl(Net::SNMP) -BuildRequires: perl(Test::Exception) -BuildRequires: perl(Test::MockModule) -BuildRequires: perl(Test::MockObject) -#BuildRequires: perl(Test::Perl::Critic) >= 1.096 ## Not packaged -BuildRequires: perl(Test::Pod::Coverage) -BuildRequires: perl(Time::HiRes) -BuildRequires: perl(Net::SSLeay) +# CGI sources +Source32: munin-cgi-graph.service +Source33: munin-cgi-graph.socket +Source34: munin-cgi-html.service +Source35: munin-cgi-html.socket + +# Common sources +Source40: munin.sysusers + +# Patches +Patch101: 21b3d860c17d7997d64267963f91ed75ca8a3e03.patch +Patch102: cd842e36f3ab1a55c05304d6b78dc07048bd8f84.patch +Patch103: munin-run_no_systemd.patch + +# Use mysql plugin from Munin 3.0 branch for Galera support +Source200: mysql_ + +# Plugin config +Source300: 00-default +Source301: munin-node + +BuildRequires: firewalld-filesystem +BuildRequires: gnupg2 +BuildRequires: make +BuildRequires: perl(Carp) +BuildRequires: perl(English) +BuildRequires: perl(File::Spec) BuildRequires: perl(HTML::Template) -BuildRequires: perl(LWP::UserAgent) -# Work-around for koji -%if 0%{?rhel} > 6 || 0%{?fedora} > 16 -BuildRequires: perl-Carp -BuildRequires: perl-generators -%endif -# RHEL6+ BuildRequires: perl(Log::Log4perl) >= 1.18 -%if 0%{?rhel} > 5 || 0%{?fedora} > 11 -BuildRequires: perl(Log::Log4perl) >= 1.18 -%else BuildRequires: perl(Log::Log4perl) -%endif -Requires(pre): shadow-utils -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) +BuildRequires: perl(Module::Build) +BuildRequires: perl(Net::SNMP) +BuildRequires: perl(Net::SSLeay) +BuildRequires: perl(Net::Server) +BuildRequires: perl(Text::Balanced) +BuildRequires: perl(base) +BuildRequires: perl(lib) +BuildRequires: perl(strict) +BuildRequires: perl(warnings) +BuildRequires: perl-generators +BuildRequires: perl-interpreter >= 5.8 +BuildRequires: systemd # Munin server requires +Requires: %{name}-common = %{version} +Requires: %{name}-web-support +Requires: /bin/mail +Requires: dejavu-sans-mono-fonts Requires: logrotate -Requires: perl >= 5.8 -Requires: perl(CGI::Fast) -Requires: perl(FCGI) +Requires: perl(DateTime) Requires: perl(Digest::MD5) +Requires: perl(FCGI) Requires: perl(File::Copy::Recursive) Requires: perl(Getopt::Long) Requires: perl(HTML::Template) Requires: perl(IO::Socket::INET6) -Requires: perl(Net::Server) Requires: perl(Net::SNMP) Requires: perl(Net::SSLeay) +Requires: perl(Net::Server) Requires: perl(Params::Validate) Requires: perl(RRDs) Requires: perl(Storable) -Requires: perl(Text::Balanced) -Requires: perl(DateTime) -Requires: perl(Time::HiRes) Requires: perl(Taint::Runtime) -Requires: sysstat -Requires: crontabs -# BZ#913111 : Removed because it pulls boa .. and no clean way to prefer apache. -#Requires: webserver - -# SystemD -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -BuildRequires: systemd-units -%endif - -# Munin node requires -%if 0%{?rhel} > 6 -#Requires: perl(Cache::Memcached) -#Requires: perl(Carp::Always) -# This one is in fact optional, only needed for cidr_allow in munin-node, -# which is documented in the manual page. Not present in el7. -#Requires: perl(Net::CIDR) -%else -Requires: perl(Cache::Memcached) -Requires: perl(Carp::Always) -Requires: perl(Net::CIDR) -%endif -Requires: perl(Crypt::DES) -Requires: perl(Digest::HMAC) -Requires: perl(Digest::SHA1) -Requires: perl(Net::Server) -Requires: perl(Net::Server::Fork) -Requires: perl(Net::SNMP) -Requires: perl(Net::SSLeay) +Requires: perl(Text::Balanced) Requires: perl(Time::HiRes) -# mysql plugin requires perl(Cache::Cache) -Requires: perl(Cache::Cache) +Requires: rrdtool +%{?systemd_requires} -# Munin node java monitor requires -#Requires: java-jmx # rhel<5 -BuildRequires: java-devel -BuildRequires: jpackage-utils -%if 0%{?rhel} > 6 -# RHEL7 does not have mx4j -#BuildRequires: mx4j -%else -BuildRequires: mx4j -%endif +BuildArch: noarch -# CGI requires -# RHEL6+ Requires: dejavu-sans-mono-fonts +# Some plugins are php or python3, remove them from autogenerated requires +%global __requires_exclude ^/usr/bin/(php|python3)$ %description -Munin is a highly flexible and powerful solution used to create graphs -of virtually everything imaginable throughout your network, while still +Munin is a highly flexible and powerful solution used to create graphs of +virtually everything imaginable throughout your network, while still maintaining a rattling ease of installation and configuration. This package contains the grapher/gatherer. You will only need one instance of @@ -168,36 +113,35 @@ it in your network. It will periodically poll all the nodes in your network it's aware of for data, which it in turn will use to create graphs and HTML pages, suitable for viewing with your graphical web browser of choice. -Munin is written in Perl, and relies heavily on Tobi Oetiker's excellent -RRDtool. - -Creaete a munin web user after installing: -htpasswd -bc /etc/munin/munin-htpasswd MUNIN_WEB_USER PASSWORD +You must also install munin-nginx or munin-apache sub-package to generate +web graphs. See /usr/share/doc/munin-*/*.conf for example nginx/apache config +files and installation instructions. %package node -Group: System Environment/Daemons -Summary: Network-wide graphing framework (node) -BuildArch: noarch +Summary: Network-wide resource monitoring tool (node) Requires: %{name}-common = %{version} -Requires: perl(LWP::UserAgent) -Requires: perl-Net-CIDR -Requires: perl-Net-Server -Requires: procps >= 2.0.7 -Requires: sysstat, /usr/bin/which, hdparm -Requires(pre): shadow-utils -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -Requires(post): systemd -Requires(preun): systemd -%else -Requires(post): /sbin/chkconfig -Requires(preun): /sbin/chkconfig -Requires(preun): /sbin/service -%endif +Requires: /usr/bin/which +Requires: bc +Requires: conntrack-tools +Requires: firewalld-filesystem +Requires: hdparm +Requires: jo +Requires: perl(Cache::Cache) +Requires: perl(IO::Socket::INET6) +Requires: perl(Net::CIDR) +Requires: perl(Net::SSLeay) +Requires: perl(Net::Server) +Requires: procps-ng +Requires(pre): %{_sbindir}/semanage +Requires(pre): %{_sbindir}/restorecon +%{?systemd_requires} +BuildArch: noarch + %description node -Munin is a highly flexible and powerful solution used to create graphs -of virtually everything imaginable throughout your network, while still +Munin is a highly flexible and powerful solution used to create graphs of +virtually everything imaginable throughout your network, while still maintaining a rattling ease of installation and configuration. This package contains node software. You should install it on all the nodes @@ -210,676 +154,704 @@ cpu usage, network usage, load average, and so on. Creating your own plugins which are capable of extracting other system-specific values is very easy, and is often done in a matter of minutes. You can also create plugins which relay information from other devices in your network that can't run Munin, -such as a switch or a server running another operating system, by using SNMP -or similar technology. - -Munin is written in Perl, and relies heavily on Tobi Oetiker's excellent -RRDtool. - -%package async -Group: System Environment/Daemons -Summary: Network-wide graphing framework (asynchronous client tools) -BuildArch: noarch -Requires: %{name}-node = %{version} - -%description async -Munin is a highly flexible and powerful solution used to create graphs of -virtually everything imaginable throughout your network, while still -maintaining a rattling ease of installation and configuration. - -This package contains the tools necessary for setting up an asynchronous -client / spooling system. - -See documentation for setup instructions: -https://munin.readthedocs.org/en/latest/node/async.html +such as a switch or a server running another operating system, by using +SNMP or similar technology. %package common -Group: System Environment/Daemons -Summary: Network-wide graphing framework (common files) +Summary: Network-wide resource monitoring tool (common files) +Requires: acl +%{?systemd_requires} +%{?sysusers_requires_compat} BuildArch: noarch -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) -Requires(pre): shadow-utils + %description common -Munin is a highly flexible and powerful solution used to create graphs -of virtually everything imaginable throughout your network, while still +Munin is a highly flexible and powerful solution used to create graphs of +virtually everything imaginable throughout your network, while still maintaining a rattling ease of installation and configuration. This package contains common files that are used by both the server (munin) and node (munin-node) packages. -%package java-plugins -Group: System Environment/Daemons -Summary: java-plugins for munin -Requires: %{name}-node = %{version} -BuildArch: noarch -Requires: jpackage-utils - -%description java-plugins -java-plugins for munin-node. - -Install this sub-package for the jmx node plugin. - -%package ruby-plugins -Group: System Environment/Daemons -Summary: ruby-plugins for munin +%package plugins-ruby +Summary: Ruby plugins for Munin resource monitoring Requires: %{name}-node = %{version} BuildArch: noarch -%description ruby-plugins -ruby-plugins for munin-node. -Install this sub-package for the tomcat node plugin. +%description plugins-ruby +Additional Ruby plugins for munin-node. -# BZ# 861816 munin-2.x CGI support is broken without manual hacks -%package cgi -Group: System Environment/Daemons -Summary: Network-wide graphing framework (cgi files for apache) -BuildArch: noarch -Requires: %{name}-common = %{version} -Requires: mod_fcgid -Requires: spawn-fcgi -Requires(pre): shadow-utils - -%description cgi -Munin package uses cron by default. This package contains the CGI files that -can generate HTML and graphs dynamically. This enables munin to scale better -for a master with many nodes. - -See documentation for setup instructions: -http://munin-monitoring.org/wiki/CgiHowto2 -http://munin.readthedocs.org/en/latest/example/webserver/apache-virtualhost.html - -QUICK-HOWTO: -sed -i 's/\(.*\)_strategy.*/\1_strategy cgi/' /etc/munin/munin.conf -htpasswd -bc /etc/munin/munin-htpasswd MUNIN_WEB_USER PASSWORD -for svc in httpd munin-node ; do - service $svc stop - chkconfig $svc on - service $svc start -done - -# BZ# 905241 %package nginx -Group: System Environment/Daemons -Summary: Network-wide graphing framework (cgi files for nginx) +Summary: NGINX support for Munin resource monitoring +Requires: %{name} = %{version} +Requires: munin-cgi +Requires: nginx-filesystem +Provides: munin-web-support = %{version}-%{release} +Conflicts: munin-apache BuildArch: noarch -Requires: %{name}-common = %{version} -Requires: spawn-fcgi + %description nginx -Munin package uses cron by default. This package contains the CGI files that -can generate HTML and graphs dynamically. This enables munin to scale better -for a master with many nodes. +NGINX support for Munin resource monitoring. -QUICK-HOWTO: -sed -i 's/\(.*\)_strategy.*/\1_strategy cgi/;s/#cgiurl_graph/cgiurl_graph/' /etc/munin/munin.conf -for svc in munin-fcgi-graph munin-fcgi-html nginx ; do - service $svc stop - chkconfig $svc on - service $svc start -done -%package netip-plugins -Group: System Environment/Daemons -Summary: Network-wide graphing framework (dhcpd3 and ntp plugins) +%package apache +Summary: Apache support for Munin resource monitoring +Requires: %{name} = %{version} +Requires: httpd +Requires: mod_fcgid +Provides: munin-web-support = %{version}-%{release} +Conflicts: munin-nginx BuildArch: noarch -Requires: %{name}-common = %{version} -%description netip-plugins -Munin plugins that require Net::IP. This is only dhcpd3 and ntp currently. + +%description apache +Apache support for Munin resource monitoring. + + +%package cgi +Summary: FastCGI startup scripts for Munin resource monitoring +Requires: %{name} = %{version} +Requires: nginx-filesystem +%{?systemd_requires} +BuildArch: noarch + + +%description cgi +FastCGI startup scripts for Munin resource monitoring. Use these with +NGINX to generate graphs on demand. Apache has built in support for +FastCGI so you don't need this package. %prep -%setup -q -n munin-%{version} +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%setup -q -%if 0%{?rhel} < 6 && 0%{?fedora} < 11 -install -c %{SOURCE12} ./plugins/node.d.linux/cpuspeed.in -%endif +sed -i -e ' + s,^PREFIX = \(.*\),PREFIX = $(DESTDIR)%{_prefix},; + s,^SBINDIR = \(.*\),SBINDIR = $(DESTDIR)%{_sbindir},; + s,^CONFDIR = \(.*\),CONFDIR = $(DESTDIR)%{_sysconfdir}/munin,; + s,^DOCDIR = \(.*\),DOCDIR = $(DESTDIR)%{_docdir}/%{name}-%{version},; + s,^MANDIR = \(.*\),MANDIR = $(DESTDIR)%{_mandir},; + s,^LIBDIR = \(.*\),LIBDIR = $(DESTDIR)%{_datadir}/munin,; + s,^HTMLDIR = \(.*\),HTMLDIR = $(DESTDIR)%{_localstatedir}/www/html/munin,; + s,^CGIDIR = \(.*\),CGIDIR = $(HTMLDIR)/cgi,; + s,^DBDIR = \(.*\),DBDIR = $(DESTDIR)%{_sharedstatedir}/munin,; + s,^DBDIRNODE = \(.*\),DBDIRNODE = $(DESTDIR)%{_sharedstatedir}/munin-node,; + s,^LOGDIR = \(.*\),LOGDIR = $(DESTDIR)%{_localstatedir}/log/munin,; + s,^PYTHON := \(.*\),PYTHON := /usr/bin/python3,; + s,^RUBY := \(.*\),RUBY := /usr/bin/ruby,; + s,^PERLLIB = \(.*\),PERLLIB = $(DESTDIR)%{perl_vendorlib},; + s,^HOSTNAME := \(.*\),HOSTNAME := localhost.localdomain,; + s,^PLUGINUSER := \(.*\),PLUGINUSER := munin,; + s,^CGIUSER := \(.*\),CGIUSER := munin,; + s,^CHECKUSER := \(.*\),CHECKUSER := /bin/true,; + s,^CHECKGROUP := \(.*\),CHECKGROUP := /bin/true,; + s,^CHOWN := \(.*\),CHOWN := echo Not done: chown,; + s,^CHMOD := \(.*\),CHMOD := echo Not done: chmod,; + s,^CHGRP := \(.*\),CHGRP := echo Not done: chgrp,; + s,^JC := \(.*\),JC := /bin/false,; + ' Makefile.config -%if 0%{?rhel} > 6 -# This one relies on Cache::Memcached, which is not shipped with el7 -rm -f plugins/node.d/memcached_.in -%endif +sed -i -e 's,@@DBDIR@@,%{_sharedstatedir}/munin-node,g' node/_bin/munin-get.in -%patch4 -p0 -#% patch5 -p0 -#% patch7 -p1 -#% patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -#% patch15 -p1 -#% patch16 -p1 -install -c %{SOURCE13} ./resources/ +%patch -P 101 -p1 +%patch -P 102 -p1 +%patch -P 103 -p1 -# Create Makefile.config-dist -install -c %{SOURCE20} . -sed -i -e 's,^PERLSITELIB := \(.*\),PERLSITELIB := %{perl_vendorlib},;' Makefile.config-dist - -#%% patch17 -p1 -F2 +cp %SOURCE16 . +cp %SOURCE17 . +cp %SOURCE18 . %build -%if 0%{?rhel} > 6 -export CLASSPATH=plugins/javalib/org/munin/plugin/jmx:$CLASSPATH -%else -export CLASSPATH=plugins/javalib/org/munin/plugin/jmx:$(build-classpath mx4j):$CLASSPATH -%endif -make CONFIG=Makefile.config-dist - -# Convert to utf-8 -for file in Announce-2.0 COPYING ChangeLog Checklist HACKING.pod README RELEASE UPGRADING UPGRADING-1.4; do - iconv -f ISO-8859-1 -t UTF-8 -o $file.new $file && \ - touch -r $file $file.new && \ - mv $file.new $file -done - -# Fix the wrong FSF address -for FILE in plugins/node.d.linux/tcp.in COPYING plugins/node.d.linux/bonding_err_.in; do - sed -i 's|59 Temple Place.*Suite 330, Boston, MA *02111-1307|51 Franklin St, Fifth Floor, Boston, MA 02110-1301|g' $FILE -done +make CONFIG=Makefile.config %install -rm -rf ${buildroot} +make CONFIG=Makefile.config DESTDIR=%{buildroot} install -## Node -%if 0%{?rhel} > 6 -export CLASSPATH=plugins/javalib/org/munin/plugin/jmx:$CLASSPATH -%else -export CLASSPATH=plugins/javalib/org/munin/plugin/jmx:$(build-classpath mx4j):$CLASSPATH -%endif -make CONFIG=Makefile.config-dist \ - DESTDIR=%{buildroot} \ -%if 0%{?rhel} > 7 || 0%{?fedora} > 19 - DOCDIR=%{buildroot}%{_docdir}/%{name} \ -%else - DOCDIR=%{buildroot}%{_docdir}/%{name}-%{version} \ -%endif - JAVALIBDIR=%{buildroot}%{_datadir}/java \ - MANDIR=%{buildroot}%{_mandir} \ - PREFIX=%{buildroot}%{_prefix} \ - USER=nobody GROUP=nobody \ - install +# Remove bundled fonts +rm -f %{buildroot}%{_datadir}/munin/DejaVuSans*.ttf -# Remove fonts -rm %{buildroot}%{_datadir}/munin/DejaVuSans*.ttf -# install logrotate scripts -mkdir -p %{buildroot}/etc/logrotate.d -install -m 0644 %{SOURCE3} %{buildroot}/etc/logrotate.d/munin-node -install -m 0644 %{SOURCE4} %{buildroot}/etc/logrotate.d/munin +### Node ### -# BZ#821912 - Move .htaccess to apache config to allow easier user-access changes. -mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d -sed -e 's/# %{buildroot}%{_sysconfdir}/httpd/conf.d/munin.conf +# Overwrite default config file +cp %{SOURCE20} %{buildroot}%{_sysconfdir}/munin/ -# BZ#1312121 - Munin dynamic graph zoom (dynazoom) failing due to Apache config. -cat - >> %{buildroot}%{_sysconfdir}/httpd/conf.d/munin.conf < - Options ExecCGI - SetHandler cgi-script +# Move munin-asyncd to /usr/sbin/ (FHS) +mv %{buildroot}%{_datadir}/munin/munin-asyncd %{buildroot}%{_sbindir}/munin-asyncd - AuthUserFile /etc/munin/munin-htpasswd - AuthName "Munin" - AuthType Basic - require valid-user - +# Remove the Sybase plugin for now, as they need perl modules that are not available +rm -f %{buildroot}%{_datadir}/munin/plugins/sybase_space -EOT +# Update plugins from 3.0 branch +cp %{SOURCE200} %{buildroot}%{_datadir}/munin/plugins/ -rm %{buildroot}/var/www/html/munin/.htaccess +# Install plugin config +cp %{SOURCE300} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/ +cp %{SOURCE301} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/ -# install cron script -mkdir -p %{buildroot}/etc/cron.d -install -m 0644 %{SOURCE17} %{buildroot}/etc/cron.d/munin +# Create plugin state dirs +mkdir -p %{buildroot}%{_sharedstatedir}/munin-node/plugin-state/munin +mkdir -p %{buildroot}%{_sharedstatedir}/munin-node/plugin-state/root -# BZ# 908711 -mv %{buildroot}/usr/share/munin/munin-asyncd %{buildroot}/usr/sbin/munin-asyncd +# munin-get plugin directory +mkdir -p %{buildroot}%{_sharedstatedir}/munin-node/munin-get-plugins -# SystemD -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -mkdir -p %{buildroot}/lib/systemd/system -%endif -# Fedora 17 and higer uses privatetmp -%if 0%{?fedora} == 16 -install -m 0644 %{SOURCE8} %{buildroot}/lib/systemd/system/munin-node.service -install -m 0644 %{SOURCE14} %{buildroot}/lib/systemd/system/munin-asyncd.service -install -m 0644 %{SOURCE15} %{buildroot}/lib/systemd/system/munin-fcgi-html.service -install -m 0644 %{SOURCE16} %{buildroot}/lib/systemd/system/munin-fcgi-graph.service -%endif -%if 0%{?rhel} > 6 || 0%{?fedora} > 16 -install -m 0644 %{SOURCE11} %{buildroot}/lib/systemd/system/munin-node.service -install -m 0644 %{SOURCE14} %{buildroot}/lib/systemd/system/munin-asyncd.service -install -m 0644 %{SOURCE15} %{buildroot}/lib/systemd/system/munin-fcgi-html.service -install -m 0644 %{SOURCE16} %{buildroot}/lib/systemd/system/munin-fcgi-graph.service -%endif -mkdir -p %{buildroot}/var/lib/munin/spool +# firewalld config +mkdir -p %{buildroot}/%{_prefix}/lib/firewalld/services +cp %{SOURCE26} %{buildroot}/%{_prefix}/lib/firewalld/services/ -# install tmpfiles.d entry -%if 0%{?rhel} > 6 || 0%{?fedora} > 14 + +# Disable some plugins from autoconfig +for i in if_err_ bonding_err_ yum ntp_ ntp_kernel_err ntp_kernel_pll_freq ntp_kernel_pll_off ntp_states nfsd; do + sed -i -e 's/family=auto/family=manual/' %{buildroot}%{_datadir}/munin/plugins/$i +done + +# Fix plugin charsets +for i in courier_mta_mailqueue courier_mta_mailstats courier_mta_mailvolume \ + dhcpd3 mysql_isam_space_ snmp__print_pages snmp__print_supplies \ + snmp__rdp_users tomcat_jvm; do + fname="%{buildroot}%{_datadir}/munin/plugins/$i" + iconv -f iso8859-1 -t UTF-8 $fname > $fname.tmp + chmod --reference=$fname $fname.tmp + mv -f $fname.tmp $fname +done + + +### Server ### + +# Create compatibility symlink ghost +ln -s munin-conf.d %{buildroot}%{_sysconfdir}/munin/conf.d + +# Overwrite default config file +cp %{SOURCE10} %{buildroot}%{_sysconfdir}/munin/ + +# Add missing custom.css +touch %{buildroot}%{_sysconfdir}/munin/static/custom.css + +# Install logrotate script +cp %{SOURCE11} %{buildroot}%{_sysconfdir}/logrotate.d/munin + +# Install tmpfiles config mkdir -p %{buildroot}%{_tmpfilesdir} -install -m 0644 %{SOURCE9} %{buildroot}%{_tmpfilesdir}/%{name}.conf -%endif +mkdir -p %{buildroot}%{_rundir}/munin +cp %{SOURCE12} %{buildroot}%{_tmpfilesdir}/%{name}.conf -# Fedora 15 and rhel use sysvinit / upstart -%if (0%{?rhel} > 4 && 0%{?rhel} <= 6) || 0%{?fedora} == 15 -mkdir -p %{buildroot}/etc/rc.d/init.d -cat %{SOURCE18} | sed -e 's/2345/\-/' > %{buildroot}/etc/rc.d/init.d/munin-node -chmod 755 %{buildroot}/etc/rc.d/init.d/munin-node -install -m 0755 %{SOURCE13} %{buildroot}/etc/rc.d/init.d/munin-asyncd -install -m 0755 %{SOURCE22} %{buildroot}/etc/rc.d/init.d/munin-fcgi-html -install -m 0755 %{SOURCE23} %{buildroot}/etc/rc.d/init.d/munin-fcgi-graph -%endif +# Add timer and service +cp %{SOURCE13} %{buildroot}%{_unitdir} +cp %{SOURCE14} %{buildroot}%{_unitdir} -# Fix default config file -sed -i ' - s,/etc/munin/munin-conf.d,/etc/munin/conf.d,; - s,#html_strategy.*,html_strategy cron,; - s,#graph_strategy.*,graph_strategy cron,; - s,#cgiurl_graph,cgiurl_graph,; - s,# cgitmpdir .*,cgitmpdir /var/tmp,; - ' %{buildroot}/etc/munin/munin.conf -mkdir -p %{buildroot}/etc/munin/conf.d -mkdir -p %{buildroot}/etc/munin/plugin-conf.d -mkdir -p %{buildroot}/etc/munin/node.d -mkdir -p %{buildroot}/etc/munin/plugin-node.d +# ssh for asyncd +mkdir -p %{buildroot}%{_sharedstatedir}/munin/.ssh -# install config for sendmail under fedora -install -m 0644 %{SOURCE1} %{buildroot}/etc/munin/plugin-conf.d/sendmail +# rrdcached +mkdir -p %{buildroot}%{_sharedstatedir}/munin/rrdcached +cp %{SOURCE15} %{buildroot}%{_unitdir} -# install config for hddtemp_smartctl -install -m 0644 %{SOURCE2} %{buildroot}/etc/munin/plugin-conf.d/hddtemp_smartctl - -# install logrotate scripts -install -m 0644 %{SOURCE3} %{buildroot}/etc/logrotate.d/munin-node -install -m 0644 %{SOURCE4} %{buildroot}/etc/logrotate.d/munin -%if 0%{?fedora} > 15 || 0%{?rhel} > 6 -echo 'Using SU directive for logrotate.d' -%else -# Fedora >= 16 requires 'su' directive. -echo 'Commenting out SU directive for logrotate.d' -sed -i 's/su /#su /' %{buildroot}/etc/logrotate.d/munin-node -sed -i 's/su /#su /' %{buildroot}/etc/logrotate.d/munin -%endif - -# install config for postfix under fedora -install -m 0644 %{SOURCE6} %{buildroot}/etc/munin/plugin-conf.d/postfix - -# install df config to exclude fses we shouldn't try and monitor -install -m 0644 %{SOURCE7} %{buildroot}/etc/munin/plugin-conf.d/df - -# Install amavis config file to set MUNIN_MKTEMP env -install -m 0644 %{SOURCE24} %{buildroot}/etc/munin/plugin-conf.d/amavis - -# Install config file for postgres -install -m 0644 %{SOURCE26} %{buildroot}/etc/munin/plugin-conf.d/postgres - -# Append for BZ# 746083 -cat - >> %{buildroot}/etc/munin/plugin-conf.d/munin-node <> %{buildroot}/etc/munin/plugin-conf.d/fw_ < 6 || 0%{?fedora} > 19 -mkdir -p %{buildroot}/%{_prefix}/lib/firewalld/services/ -cp %{SOURCE25} %{buildroot}/%{_prefix}/lib/firewalld/services/munin-node.xml -%endif - -%clean -rm -rf %{buildroot} +# Use UTF-8 in XML templates +for i in static/definitions.html templates/partial/head.tmpl; do + sed -i -e 's/iso-8859-1/utf-8/g' %{buildroot}%{_sysconfdir}/munin/$i +done -# -# node package scripts -# -# adding because of f17. -%pre common -/usr/bin/getent group munin >/dev/null || \ - /usr/sbin/groupadd -r munin -/usr/bin/getent passwd munin >/dev/null || \ - /usr/sbin/useradd -r -g munin -d /var/lib/munin -s /sbin/nologin \ - -c "Munin user" munin -exit 0 +### CGI ### -%pre node -/usr/bin/getent group munin >/dev/null || \ - /usr/sbin/groupadd -r munin -/usr/bin/getent passwd munin >/dev/null || \ - /usr/sbin/useradd -r -g munin -d /var/lib/munin -s /sbin/nologin \ - -c "Munin user" munin -exit 0 +cp %{SOURCE32} %{buildroot}%{_unitdir} +cp %{SOURCE33} %{buildroot}%{_unitdir} +cp %{SOURCE34} %{buildroot}%{_unitdir} +cp %{SOURCE35} %{buildroot}%{_unitdir} + + +### Log files (ghost) ### + +touch %{buildroot}%{_localstatedir}/log/munin/munin-cgi-graph.log +touch %{buildroot}%{_localstatedir}/log/munin/munin-cgi-html.log +touch %{buildroot}%{_localstatedir}/log/munin/munin-graph.log +touch %{buildroot}%{_localstatedir}/log/munin/munin-html.log +touch %{buildroot}%{_localstatedir}/log/munin/munin-limits.log +touch %{buildroot}%{_localstatedir}/log/munin/munin-update.log +mkdir -p %{buildroot}%{_localstatedir}/log/munin-node +touch %{buildroot}%{_localstatedir}/log/munin-node/munin-node.log + + +### Keep old apache munin.conf files (ghost) ### + +mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d +touch %{buildroot}%{_sysconfdir}/httpd/conf.d/munin.conf +touch %{buildroot}%{_sysconfdir}/httpd/conf.d/munin-cgi.conf +touch %{buildroot}%{_sysconfdir}/munin/munin-htpasswd + + +### Common ### + +install -m0644 -D %{SOURCE40} %{buildroot}%{_sysusersdir}/munin.conf + + +%post +# Create log files +mkdir -p %{_localstatedir}/log/munin +[ -f %{_localstatedir}/log/munin/munin-html.log ] || \ + /usr/bin/install -m 0640 -o munin -g adm /dev/null %{_localstatedir}/log/munin/munin-html.log +[ -f %{_localstatedir}/log/munin/munin-limits.log ] || \ + /usr/bin/install -m 0640 -o munin -g adm /dev/null %{_localstatedir}/log/munin/munin-limits.log +[ -f %{_localstatedir}/log/munin/munin-update.log ] || \ + /usr/bin/install -m 0640 -o munin -g adm /dev/null %{_localstatedir}/log/munin/munin-update.log +# On new install only: create simple localhost config. +if [ "$1" = "1" ]; then + if [ ! -f %{_sysconfdir}/munin/munin-conf.d/local.conf ]; then + cat - >> %{_sysconfdir}/munin/munin-conf.d/local.conf < 6 || 0%{?fedora} > 15 - %if 0%{?systemd_post:1} - %systemd_post munin-node.service - %else - if [ $1 -eq 1 ] ; then - # Initial installation - /bin/systemctl daemon-reload >/dev/null 2>&1 || : - fi - %endif -%else - # sysvinit only in f15 and older and epel - /sbin/chkconfig --add munin-node -%endif -# Only run configure on a new install, not an upgrade. +# Create log file +[ -f %{_localstatedir}/log/munin-node/munin-node.log ] || \ + /usr/bin/install -m 0640 -o root -g adm /dev/null %{_localstatedir}/log/munin-node/munin-node.log +# Fix munin-node/plugin-state and munin-node/munin-get-plugins SELinux +%{_sbindir}/semanage fcontext --delete --equal %{_sharedstatedir}/munin %{_sharedstatedir}/munin-node 2> /dev/null || : +%{_sbindir}/semanage fcontext --add --type munin_plugin_state_t "%{_sharedstatedir}/munin-node/plugin-state(/.*)?" 2> /dev/null || : +%{_sbindir}/semanage fcontext --add --type unconfined_munin_plugin_exec_t "%{_sharedstatedir}/munin-node/munin-get-plugins(/.*)?" 2> /dev/null || : +%{_sbindir}/restorecon -R %{_sharedstatedir}/munin-node || : +# Is this new install, not upgrade? if [ "$1" = "1" ]; then - /usr/sbin/munin-node-configure --shell 2> /dev/null | sh >& /dev/null || : -fi - -%post async -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 - %if 0%{?systemd_post:1} - %systemd_post munin-asyncd.service - %else - if [ $1 -eq 1 ] ; then - # Initial installation - /bin/systemctl daemon-reload >/dev/null 2>&1 || : + # Run configure + %{_sbindir}/munin-node-configure --shell 2> /dev/null | sh >& /dev/null || : + # Clean up munin mysql_ plugin shmems and semaphores to fix selinux issue + if [ -x %{_bindir}/ipcs -a -x %{_bindir}/ipcrm ]; then + for mem in $(%{_bindir}/ipcs --shmems | grep munin | cut --delimiter=' ' --fields=1); do + %{_bindir}/ipcrm --shmem-key ${mem} 2>/dev/null || : + done + for sem in $(%{_bindir}/ipcs --semaphores | grep munin | cut --delimiter=' ' --fields=1); do + %{_bindir}/ipcrm --semaphore-key ${sem} 2>/dev/null || : + done fi - %endif -%else - # sysvinit only in f15 and older and epel - /sbin/chkconfig --add munin-asyncd -%endif +fi +%systemd_post munin-node.service munin-asyncd.service + %preun node -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -# Newer installs use systemd - %if 0%{?systemd_preun:1} - %systemd_preun munin-node.service - %else - if [ "$1" = 0 ]; then - /bin/systemctl --no-reload disable munin-node.service >/dev/null 2>&1 || : - /bin/systemctl stop munin-node.service >/dev/null 2>&1 || : - fi - %endif -%else -# Older installs use sysvinit / upstart -if [ "$1" = 0 ]; then - service munin-node stop &>/dev/null || : - /sbin/chkconfig --del munin-node -fi -%endif +%systemd_preun munin-node.service munin-asyncd.service -%preun nginx -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -# Newer installs use systemd - %if 0%{?systemd_preun:1} - for svc in fcgi-html fcgi-graph ; do - %systemd_preun munin-${svc}.service - done - %else - if [ "$1" = 0 ]; then - for svc in fcgi-html fcgi-graph ; do - /bin/systemctl --no-reload disable munin-${svc}.service >/dev/null 2>&1 || : - /bin/systemctl stop munin-${svc}.service >/dev/null 2>&1 || : - done - fi - %endif -%else -# Older installs use sysvinit / upstart -if [ "$1" = 0 ]; then - for svc in fcgi-html fcgi-graph; do - service munin-${svc} stop &>/dev/null || : - /sbin/chkconfig --del munin-${svc} - done -fi -%endif %postun node +# Is this uninstall, not upgrade? if [ "$1" = "0" ]; then - [ -d %{_sysconfdir}/munin/plugins ] && \ - find %{_sysconfdir}/munin/plugins/ -maxdepth 1 -type l -print0 | \ - xargs -0 rm || : + %{_sbindir}/semanage fcontext --delete --type munin_plugin_state_t "%{_sharedstatedir}/munin-node/plugin-state(/.*)?" 2> /dev/null || : + %{_sbindir}/semanage fcontext --delete --type unconfined_munin_plugin_exec_t "%{_sharedstatedir}/munin-node/munin-get-plugins(/.*)?" 2> /dev/null || : fi - -%triggerun node -- munin-node < 1.4.7-2 -mv -f %{_sysconfdir}/munin/plugins %{_sysconfdir}/munin/plugins.bak || : - -%triggerpostun node -- munin-node < 1.4.7-2 -mv -f %{_sysconfdir}/munin/plugins.bak %{_sysconfdir}/munin/plugins || : +%systemd_postun_with_restart munin-node.service munin-asyncd.service -# -# main package scripts -# -%pre -/usr/bin/getent group munin >/dev/null || \ - /usr/sbin/groupadd -r munin -/usr/bin/getent passwd munin >/dev/null || \ - /usr/sbin/useradd -r -g munin -d /var/lib/munin -s /sbin/nologin \ - -c "Munin user" munin -exit 0 +%pre common +%sysusers_create_compat %{SOURCE40} + + +%post nginx +# Create log files +[ -f %{_localstatedir}/log/munin/munin-cgi-graph.log ] || \ + /usr/bin/install -m 0660 -o munin -g munin /dev/null %{_localstatedir}/log/munin/munin-cgi-graph.log +[ -f %{_localstatedir}/log/munin/munin-cgi-html.log ] || \ + /usr/bin/install -m 0660 -o munin -g munin /dev/null %{_localstatedir}/log/munin/munin-cgi-html.log +[ -f %{_localstatedir}/log/munin/munin-graph.log ] || \ + /usr/bin/install -m 0660 -o munin -g munin /dev/null %{_localstatedir}/log/munin/munin-graph.log + + +%post apache +# Create log files +[ -f %{_localstatedir}/log/munin/munin-cgi-graph.log ] || \ + /usr/bin/install -m 0660 -o munin -g apache /dev/null %{_localstatedir}/log/munin/munin-cgi-graph.log +[ -f %{_localstatedir}/log/munin/munin-cgi-html.log ] || \ + /usr/bin/install -m 0660 -o munin -g apache /dev/null %{_localstatedir}/log/munin/munin-cgi-html.log +[ -f %{_localstatedir}/log/munin/munin-graph.log ] || \ + /usr/bin/install -m 0660 -o munin -g apache /dev/null %{_localstatedir}/log/munin/munin-graph.log + + +%post cgi +%systemd_post munin-cgi-graph.socket munin-cgi-graph.service +%systemd_post munin-cgi-html.socket munin-cgi-html.service + + +%preun cgi +%systemd_preun munin-cgi-graph.socket munin-cgi-graph.service +%systemd_preun munin-cgi-html.socket munin-cgi-html.service + + +%postun cgi +%systemd_postun_with_restart munin-cgi-graph.socket munin-cgi-graph.service +%systemd_postun_with_restart munin-cgi-html.socket munin-cgi-html.service %files -%defattr(-,root,root) -%doc %{_mandir}/man1/munindoc* -%doc %{_mandir}/man1/munin-sched* -%doc %{_mandir}/man3/Munin::Master* %doc %{_mandir}/man5/munin.conf* %doc %{_mandir}/man8/munin* %dir %{_sysconfdir}/munin -%dir %{_sysconfdir}/munin/conf.d -%dir %{_sysconfdir}/munin/static +%dir %{_sysconfdir}/munin/munin-conf.d %dir %{_sysconfdir}/munin/templates -%dir %{_sysconfdir}/munin/templates/partial -%dir %{_datadir}/munin -%dir %{_datadir}/munin/plugins -#BUG. User apache does not necessarily exists when installing package munin -#since httpd is not required. it matters if httpd is later installed and -#the munin graph or html cgi programs are used - they log here. -#this is fixed with %%pre cgi, but if user tries to use the cgi programs -#without the cgi package, it's tough luck. -#proper fix may be to create the apache user in pre, but I'm not gonna do it. -%dir %attr(0775,apache,munin) /var/log/munin -%dir %attr(0775,root,munin) /var/lib/munin/plugin-state -%attr(0755,munin,munin) %dir /var/www/html/munin -%attr(0755,munin,munin) %dir /var/www/html/munin/static -%attr(0755,root,munin) /var/www/cgi-bin/munin-cgi-graph -%attr(0755,root,munin) /var/www/cgi-bin/munin-cgi-html -%attr(0644,munin,munin) /var/www/html/munin/static/* -%config(noreplace) %attr(0644,root,root) %{_sysconfdir}/cron.d/munin -%config(noreplace) %{_sysconfdir}/httpd/conf.d/munin.conf +%dir %{_sysconfdir}/munin/static +%{_unitdir}/munin.timer +%{_unitdir}/munin.service +%ghost %{_sysconfdir}/munin/conf.d %config(noreplace) %{_sysconfdir}/logrotate.d/munin %config(noreplace) %{_sysconfdir}/munin/munin.conf -%config(noreplace) %{_sysconfdir}/munin/munin-htpasswd +%config(noreplace) %{_sysconfdir}/munin/templates/* %config(noreplace) %{_sysconfdir}/munin/static/* -%config(noreplace) %{_sysconfdir}/munin/templates/partial/*.tmpl -%config(noreplace) %{_sysconfdir}/munin/templates/*.tmpl -%attr(0755,root,root) %{_bindir}/munin-check -%attr(0755,root,root) %{_bindir}/munin-cron -%attr(0755,root,root) %{_bindir}/munindoc -%attr(0755,root,root) %{_sbindir}/munin-sched +%{_bindir}/munin-check +%{_bindir}/munin-cron +%dir %{_datadir}/munin %{_datadir}/munin/munin-datafile2storable %{_datadir}/munin/munin-graph %{_datadir}/munin/munin-html %{_datadir}/munin/munin-limits %{_datadir}/munin/munin-storable2datafile %{_datadir}/munin/munin-update -%{perl_vendorlib}/Munin/Master/*.pm +%{perl_vendorlib}/Munin/Master +%attr(-, munin, munin) %dir %{_sharedstatedir}/munin +%attr(0700, munin, munin) %dir %{_sharedstatedir}/munin/.ssh +%attr(-, munin, munin) %dir %{_localstatedir}/www/html/munin +%attr(-, munin, munin) %{_localstatedir}/www/html/munin/cgi +%attr(0640, munin, adm) %ghost %{_localstatedir}/log/munin/munin-html.log +%attr(0640, munin, adm) %ghost %{_localstatedir}/log/munin/munin-limits.log +%attr(0640, munin, adm) %ghost %{_localstatedir}/log/munin/munin-update.log +%attr(-, munin, munin) %dir %{_sharedstatedir}/munin/rrdcached +%{_unitdir}/munin-rrdcached.service +%dir %{_datadir}/munin/plugins +%{_datadir}/munin/plugins/munin_stats +%config(noreplace) %ghost %{_sysconfdir}/munin/munin-htpasswd +%config(noreplace) %ghost %{_sysconfdir}/httpd/conf.d/munin.conf +%config(noreplace) %ghost %{_sysconfdir}/httpd/conf.d/munin-cgi.conf +%config(noreplace) %ghost %{_localstatedir}/www/html/munin/.htaccess %files node -%defattr(-,root,root) -%doc %{_mandir}/man1/munin-node* -%doc %{_mandir}/man1/munin-run* -%doc %{_mandir}/man3/Munin::Common* -%doc %{_mandir}/man3/Munin::Node* -%doc %{_mandir}/man3/Munin::Plugin* -%doc %{_mandir}/man5/munin-node* -%dir %{_sysconfdir}/munin/node.d -%dir %{_sysconfdir}/munin/plugins +%doc %{_mandir}/man1/munin* +%doc %{_mandir}/man3/Munin* +%doc %{_mandir}/man5/munin-node.conf* %dir %{_sysconfdir}/munin -%dir %{_datadir}/munin -%dir %attr(-,munin,munin) /var/lib/munin -%dir %attr(0775,nobody,munin) /var/lib/munin-node/plugin-state -%dir %attr(0755,root,root) /var/log/munin-node +%dir %{_sysconfdir}/munin/plugin-conf.d +%dir %{_sysconfdir}/munin/plugins %config(noreplace) %{_sysconfdir}/logrotate.d/munin-node %config(noreplace) %{_sysconfdir}/munin/munin-node.conf -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/amavis -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/df -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/fw_ -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/hddtemp_smartctl -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/munin-node -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/postfix -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/postgres -%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/sendmail -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -/lib/systemd/system/munin-node.service -%else -%{_sysconfdir}/rc.d/init.d/munin-node -%endif -%if 0%{?rhel} > 6 || 0%{?fedora} > 19 -%{_prefix}/lib/firewalld/services/munin-node.xml -%endif -%attr(0755,root,root) %{_sbindir}/munin-run -%attr(0755,root,root) %{_sbindir}/munin-node -%attr(0755,root,root) %{_sbindir}/munin-node-configure -%attr(-,munin,munin) /var/lib/munin/plugin-state/yum.state -%exclude %{_datadir}/munin/plugins/dhcpd3 -%exclude %{_datadir}/munin/plugins/jmx_ -%exclude %{_datadir}/munin/plugins/ntp_ -%exclude %{_datadir}/munin/plugins/tomcat_ +%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/* +%{_unitdir}/munin-node.service +%{_unitdir}/munin-asyncd.service +%{_bindir}/munindoc +%{_bindir}/munin-get +%{_sbindir}/munin-node +%{_sbindir}/munin-node-configure +%{_sbindir}/munin-run +%{_sbindir}/munin-asyncd +%dir %{_datadir}/munin +%{_datadir}/munin/munin-async %{_datadir}/munin/plugins/ +%exclude %{_datadir}/munin/plugins/tomcat_ +%exclude %{_datadir}/munin/plugins/munin_stats %{perl_vendorlib}/Munin/Node %{perl_vendorlib}/Munin/Plugin* - - -%files async -%defattr(-,root,root) -%{_sbindir}/munin-asyncd -%{_datadir}/munin/munin-async -%dir /var/lib/munin/spool -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -/lib/systemd/system/munin-asyncd.service -%else -%{_sysconfdir}/rc.d/init.d/munin-asyncd -%endif +%{_prefix}/lib/firewalld/services/munin-node.xml +%attr(-, munin, munin) %dir %{_sharedstatedir}/munin +%attr(-, root, root) %dir %{_sharedstatedir}/munin-node +%attr(-, root, root) %dir %{_sharedstatedir}/munin-node/munin-get-plugins +%attr(-, root, root) %dir %{_sharedstatedir}/munin-node/plugin-state +%attr(-, munin, root) %dir %{_sharedstatedir}/munin-node/plugin-state/munin +%attr(-, root, root) %dir %{_sharedstatedir}/munin-node/plugin-state/root +%attr(-, munin, munin) %dir %{_sharedstatedir}/munin/spool +%attr(0700, munin, munin) %dir %{_sharedstatedir}/munin/.ssh +%attr(0750, root, adm) %dir %{_localstatedir}/log/munin-node +%attr(0640, root, adm) %ghost %{_localstatedir}/log/munin-node/munin-node.log %files common -%defattr(-,root,root) -%doc Announce-2.0 COPYING ChangeLog Checklist HACKING.pod README RELEASE UPGRADING UPGRADING-1.4 +%license COPYING +%doc ChangeLog HACKING.pod perltidyrc +%doc httpd_cgi_graphs.conf httpd_cron_graphs.conf nginx_cgi_graphs.conf %dir %{perl_vendorlib}/Munin -%dir %attr(-,munin,munin) %{_localstatedir}/run/%{name}/ -%if 0%{?rhel} > 6 || 0%{?fedora} > 14 -%config(noreplace) %{_tmpfilesdir}/%{name}.conf -%endif %{perl_vendorlib}/Munin/Common +%{_tmpfilesdir}/%{name}.conf +%{_sysusersdir}/munin.conf +%attr(0775, root, munin) %dir %{_rundir}/munin -%files java-plugins -%defattr(-,root,root) -%{_datadir}/java/munin-jmx-plugins.jar -%{_datadir}/munin/plugins/jmx_ - - -%files ruby-plugins -%defattr(-,root,root) +%files plugins-ruby %{_datadir}/munin/plugins/tomcat_ -%files cgi -%defattr(-,root,root) -%config(noreplace) %{_sysconfdir}/httpd/conf.d/munin-cgi.conf -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -/lib/systemd/system/munin-fcgi-html.service -/lib/systemd/system/munin-fcgi-graph.service -%endif -%attr(0755,root,root) %dir /var/lib/munin/cgi-tmp -%attr(0755,apache,apache) %dir /var/lib/munin/cgi-tmp/munin-cgi-graph - - %files nginx -%defattr(-,root,root) -%config(noreplace) %{_sysconfdir}/nginx/conf.d/munin.conf -%if 0%{?rhel} > 6 || 0%{?fedora} > 15 -/lib/systemd/system/munin-fcgi-html.service -/lib/systemd/system/munin-fcgi-graph.service -%else -%{_sysconfdir}/rc.d/init.d/munin-fcgi-html -%{_sysconfdir}/rc.d/init.d/munin-fcgi-graph -%endif +%attr(0775, munin, munin) %dir %{_sharedstatedir}/munin/cgi-tmp +%attr(0750, munin, adm) %dir %{_localstatedir}/log/munin +%attr(0660, munin, munin) %ghost %{_localstatedir}/log/munin/munin-cgi-graph.log +%attr(0660, munin, munin) %ghost %{_localstatedir}/log/munin/munin-cgi-html.log +%attr(0660, munin, munin) %ghost %{_localstatedir}/log/munin/munin-graph.log -%files netip-plugins -%defattr(-,root,root) -%{_datadir}/munin/plugins/dhcpd3 -%{_datadir}/munin/plugins/ntp_ +%files apache +%attr(0775, munin, apache) %dir %{_sharedstatedir}/munin/cgi-tmp +%attr(0750, munin, apache) %dir %{_localstatedir}/log/munin +%attr(0660, munin, apache) %ghost %{_localstatedir}/log/munin/munin-cgi-graph.log +%attr(0660, munin, apache) %ghost %{_localstatedir}/log/munin/munin-cgi-html.log +%attr(0660, munin, apache) %ghost %{_localstatedir}/log/munin/munin-graph.log + + +%files cgi +%{_unitdir}/munin-cgi-graph.service +%{_unitdir}/munin-cgi-graph.socket +%{_unitdir}/munin-cgi-html.service +%{_unitdir}/munin-cgi-html.socket %changelog +* Thu Jul 16 2026 Fedora Release Engineering - 2.0.76-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild + +* Fri Jan 16 2026 Fedora Release Engineering - 2.0.76-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + +* Sun Dec 28 2025 Kim B. Heino - 2.0.76-8 +- rhbz 2406177: Move sysusers.d config to munin-common + +* Thu Jul 24 2025 Fedora Release Engineering - 2.0.76-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Tue Feb 11 2025 Zbigniew Jędrzejewski-Szmek - 2.0.76-6 +- Add sysusers.d config file to allow rpm to create users/groups automatically + +* Mon Jan 27 2025 Kim B. Heino - 2.0.76-5 +- rhbz 2340895: Fix build on Fedora 42 + +* Fri Jan 17 2025 Fedora Release Engineering - 2.0.76-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Mon Oct 21 2024 Kim B. Heino - 2.0.76-3 +- Don't restart firewalld on package update, rhbz #2295597 + +* Thu Jul 18 2024 Fedora Release Engineering - 2.0.76-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Wed Jun 19 2024 Kim B. Heino - 2.0.76-1 +- Upgrade to 2.0.76 + +* Thu Jan 25 2024 Fedora Release Engineering - 2.0.75-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sun Jan 21 2024 Fedora Release Engineering - 2.0.75-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Mon Nov 6 2023 Kim B. Heino - 2.0.75-1 +- Upgrade to 2.0.75 + +* Wed Oct 4 2023 Kim B. Heino - 2.0.74-1 +- Upgrade to 2.0.74 + +* Thu Jul 20 2023 Fedora Release Engineering - 2.0.73-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Wed May 17 2023 Kim B. Heino - 2.0.73-1 +- Upgrade to 2.0.73 +- rhbz 2183484: Permission denied for group apache on /var/log/munin + +* Tue Mar 7 2023 Kim B. Heino - 2.0.72-1 +- Upgrade to 2.0.72 +- Add munin-get plugin directory +- Mangle /var/lib/munin-node SELinux +- Fix service startup order + +* Thu Jan 19 2023 Fedora Release Engineering - 2.0.69-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Sun Jul 24 2022 Kim B. Heino - 2.0.69-5 +- Bump release for rebuild + +* Sat Jul 23 2022 Kim B. Heino - 2.0.69-4 +- Replace /var/lib/munin/plugin-state with upstream default /var/lib/munin-node/plugin-state + +* Fri Jul 22 2022 Fedora Release Engineering - 2.0.69-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jul 20 2022 Kim B. Heino - 2.0.69-2 +- Replace /etc/munin/conf.d with upstream default /etc/munin/munin-conf.d +- Add compatibility symlink /etc/munin/conf.d if necessary + +* Wed Jul 20 2022 Kim B. Heino - 2.0.69-1 +- Upgrade to 2.0.69 + +* Wed Jun 01 2022 Jitka Plesnikova - 2.0.67-6 +- Perl 5.36 rebuild + +* Thu Jan 20 2022 Fedora Release Engineering - 2.0.67-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Thu Jul 22 2021 Fedora Release Engineering - 2.0.67-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Sat May 22 2021 Jitka Plesnikova - 2.0.67-3 +- Perl 5.34 rebuild + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2.0.67-2 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* Wed Feb 24 2021 Kim B. Heino - 2.0.67-1 +- Upgrade to 2.0.67 + +* Fri Feb 05 2021 Todd Zullinger - 2.0.66-1 +- Upgrade to 2.0.66 +- Verify upstream signature + +* Tue Jan 26 2021 Fedora Release Engineering - 2.0.65-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Dec 14 2020 Kim B. Heino - 2.0.65-2 +- Add plugin-state subdirs for munin and root + +* Tue Nov 17 2020 Kim B. Heino - 2.0.65-1 +- Upgrade to 2.0.65 +- Improve plugin-state directory owners +- Don't require tmpwatch +- Change log file owner to root:adm or munin:adm + +* Tue Jul 28 2020 Fedora Release Engineering - 2.0.63-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 6 2020 Kim B. Heino - 2.0.63-1 +- Upgrade to 2.0.63 +- Don't use systemd-run in munin-run, rhbz #1852345 +- Use "Type=notify" for munin-node and munin-asyncd + +* Thu Jun 25 2020 Jitka Plesnikova - 2.0.54-5 +- Perl 5.32 rebuild + +* Tue Mar 24 2020 Jitka Plesnikova - 2.0.54-4 +- Specify all perl's dependencies for build + +* Wed Jan 29 2020 Fedora Release Engineering - 2.0.54-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Jan 24 2020 Kim B. Heino - 2.0.54-2 +- Convert cronjob to systemd timer and tmpfiles + +* Tue Jan 21 2020 Kim B. Heino - 2.0.54-1 +- Upgrade to 2.0.54 +- Improve df's ignore list +- Use systemd hardening options for node and asyncd + +* Sat Oct 19 2019 Kim B. Heino - 2.0.51-1 +- Upgrade to 2.0.51 + +* Thu Oct 17 2019 Kim B. Heino - 2.0.50-2 +- Revert 290650ee2c as it breaks munin-limits on rhel + +* Thu Oct 17 2019 Kim B. Heino - 2.0.50-1 +- Upgrade to 2.0.50 + +* Thu Jul 25 2019 Fedora Release Engineering - 2.0.49-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Sat Jul 13 2019 Kim B. Heino - 2.0.49-3 +- rhbz#1721384: Mark .htaccess as ghost, include it to example config files + +* Fri May 31 2019 Jitka Plesnikova - 2.0.49-2 +- Perl 5.30 rebuild + +* Thu May 16 2019 Kim B. Heino - 2.0.49-1 +- Upgrade to 2.0.49 + +* Mon Mar 18 2019 Kim B. Heino - 2.0.45-2 +- Drop munin-plugins-java subpackage + +* Fri Feb 8 2019 Kim B. Heino - 2.0.45-1 +- Upgrade to 2.0.45 + +* Mon Jan 28 2019 Kim B. Heino - 2.0.44-2 +- Add smart_ plugin config to 00-default + +* Thu Dec 20 2018 Kim B. Heino - 2.0.44-1 +- Upgrade to 2.0.44 + +* Mon Nov 19 2018 Kim B. Heino - 2.0.43-1 +- Upgrade to 2.0.43 + +* Sun Sep 30 2018 Kim B. Heino - 2.0.42-3 +- Fix postfix and nginx categories + +* Sat Sep 22 2018 Kim B. Heino - 2.0.42-2 +- Change /run/munin owner to root:munin for clean update without dac override + +* Fri Sep 21 2018 Kim B. Heino - 2.0.42-1 +- Upgrade to 2.0.42 + +* Thu Sep 20 2018 Kim B. Heino - 2.0.41-1 +- Upgrade to 2.0.41 + +* Mon Sep 17 2018 Kim B. Heino - 2.0.40-4 +- rhbz#1327512: munin-limits not reporting actual state of variable to NSCA +- rhbz#1629438: Create localhost-config on first install +- rhbz#1629438: Include old httpd config files as ghost + +* Fri Sep 14 2018 Kim B. Heino - 2.0.40-3 +- rhbz#1628390: Fix missing Perl dependencies in Fedora +- Obsolete munin-netip-plugins for epel upgrade path + +* Sat Aug 25 2018 Kim B. Heino - 2.0.40-2 +- Fix upgrade path for munin-asyncd and force restart on first upgrade + +* Fri Aug 24 2018 Kim B. Heino - 2.0.40-1 +- Upgrade to 2.0.40 +- This is major update with rpm package reorganize and directory changes + +* Fri Jul 13 2018 Fedora Release Engineering - 2.0.33-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Sat Jun 30 2018 Jitka Plesnikova - 2.0.33-7 +- Perl 5.28 rebuild + +* Thu Feb 08 2018 Fedora Release Engineering - 2.0.33-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 2.0.33-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Thu Jul 13 2017 Petr Pisar - 2.0.33-4 +- perl dependency renamed to perl-interpreter + + +* Tue Jun 06 2017 Jitka Plesnikova - 2.0.33-3 +- Perl 5.26 rebuild + +* Thu May 25 2017 Jitka Plesnikova - 2.0.33-2 +- Fix building on Perl without '.' in @INC + * Fri Mar 03 2017 "D. Johnson" - 2.0.33-1 - Upstream released 2.0.33 diff --git a/munin.sysusers b/munin.sysusers new file mode 100644 index 0000000..50515ab --- /dev/null +++ b/munin.sysusers @@ -0,0 +1 @@ +u munin - "Munin user" /var/lib/munin /bin/sh diff --git a/munin.timer b/munin.timer new file mode 100644 index 0000000..1e06efb --- /dev/null +++ b/munin.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Munin server to collect data from nodes +Documentation=man:munin-cron(8) + +[Timer] +OnCalendar=*:00/5 + +[Install] +WantedBy=timers.target diff --git a/munin.tmpfilesd b/munin.tmpfilesd new file mode 100644 index 0000000..7d62768 --- /dev/null +++ b/munin.tmpfilesd @@ -0,0 +1,13 @@ +# Create runtime directory + +d /run/munin 0775 root munin - + +# Cleanup for old rrd/png etc files + +x /var/lib/munin/.ssh +x /var/lib/munin/cgi-tmp +x /var/lib/munin/rrdcached + +e /var/lib/munin/cgi-tmp/* - - - 1d +e /var/lib/munin/spool - - - 14d +e /var/lib/munin - - - 30d diff --git a/mysql_ b/mysql_ new file mode 100755 index 0000000..9de8628 --- /dev/null +++ b/mysql_ @@ -0,0 +1,2550 @@ +#!/usr/bin/perl + +=encoding utf8 + +=head1 NAME + +mysql_ - Munin plugin to display misc MySQL server status + +=head1 APPLICABLE SYSTEMS + +Any MySQL platform, tested by the authors on: +* MySQL 5.6.12 +* MySQL 5.5.32, 5.5.37 +* MySQL 5.1.29, +* MySQL 5.0.51 +* MariaDB 5.5.39 +* MariaDB-5.5.39(galera). +* MariaDB 10.0.18 + +Plugins: +* MariaDB-10 Query Response Time: https://mariadb.com/kb/en/mariadb/query_response_time-plugin/ + +Information Schema tables: +* User statistics - MariaDB-5.2+, OurDelta, Percona Server - https://mariadb.com/kb/en/mariadb/user-statistics + +=head1 CONFIGURATION + +This script is used to generate data for several graphs. To generate +data for one specific graph, you need to create a symbolic link with a +name like mysql_ to this script. + +If you need to run against multiple MySQL instances on the same host, +create your symlinks with names like mysql_ where N is any +non-negative integer. You must also set the env.cachenamespace variable +to a unique value for each group of symlinks. + +To get a list of symlinks that can be created, run: + + ./mysql_ suggest + +In addition you might need to specify connection parameters in the +plugin configuration to override the defaults. These are the defaults: + + [mysql_*] + env.mysqlconnection DBI:mysql:information_schema + env.mysqluser root + +Non-default example: + + [mysql_*] + env.mysqlconnection DBI:mysql:information_schema;host=127.0.0.1;port=3306 + env.mysqluser munin + env.mysqlpassword geheim + env.cachenamespace munin_mysql_pri + [mysql2_*] + env.mysqlconnection DBI:mysql:information_schema;host=127.0.0.1;port=13306 + env.mysqluser munin + env.mysqlpassword ryuWyawEv + env.cachenamespace munin_mysql_alt + [mysql10_*] + user munin + env.mysqluser munin + env.mysqlconnection DBI:mysql:information_schema;mysql_read_default_file=/etc/munin/.my-10.cnf + env.cachenamespace munin_mysql_10 + # here the [client] section of /etc/munin/.my-10.cnf is read. socket= can + # be specified here. + +Creating a munin user: + + CREATE USER 'munin'@'localhost' IDENTIFIED BY 'ryuWyawEv'; + +or with a unix_socket plugin (INSTALL PLUGIN unix_socket SONAME 'auth_socket') + + CREATE USER 'munin'@'localhost' IDENTIFIED WITH unix_socket; + +Note: requires 'user munin' in the configuration. + +The minimum required privileges of the munin database user is: + + GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'munin'@'localhost'; + + +Warning and critical values can be set via the environment in the usual way. +For example: + + [mysql_replication] + env.slave_io_running_warning 0.5 + env.slave_sql_running_warning 0.5 + env.seconds_behind_master_warning 300 + env.seconds_behind_master_critical 600 + +=head1 DEPENDENCIES + +=over + +=item Cache::Cache + +The plugin uses shared memory to cache the statistics gathered from +MySQL. This ensures minimal impact on the MySQL server. + +=item DBD::mysql + +=back + +=head1 INTERPRETATION + +=head2 InnoDB + +The statistics from innodb are mainly collected from the command + + SHOW ENGINE INNODB STATUS + +A nice walk through is found at +L + +Undo logs: +L + +=head2 The graphs + +FIX point to relevant sections in the MySQL manual and other www +resources for each graph + +=over + +=item mysql_replication + +slave_io_running and slave_sql_running both translate the "Yes" values to 0 and +anything else to 1 for their respective fields in the "SHOW SLAVE STATUS" output. +This can be used to warn on slave failure if the warning and critical values +are set as seen in a previous section. + +=item wsrep_cluster_status + +"Primary" is translated 0 and "non-Primary" to 1. + +=back + +=head1 COPYRIGHT + + Copyright (C) 2014-2015 Daniel Black, Open Query + Copyright (C) 2008-2009 Kjell-Magne Øierud + +=head1 LICENSE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 dated June, 1991. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +=head1 VERSION + +git-master + a few munin modifications + +This plugin was downloaded from L + +=head1 MAGICK MARKERS + + #%# family=auto + #%# capabilities=suggest autoconf + +=cut + +use warnings; +use strict; +use utf8; + +use English qw( -no_match_vars ); +use File::Basename; +use Storable qw(nfreeze thaw); + +use Munin::Plugin; + +my $has_cache; +my $has_dbi; +my $has_math_bigint; + +BEGIN { + eval { require Cache::SharedMemoryCache; }; + $has_cache = $EVAL_ERROR ? 0 : 1; + eval { require DBI; DBI->import(); }; + $has_dbi = $EVAL_ERROR ? 0 : 1; + # Used to append "=> lib 'GMP'" here, but GMP caused segfault on some + # occasions. Removed as I don't think the tiny performance boost is + # worth the debugging effort. + eval { require Math::BigInt; Math::BigInt->import(); }; + $has_math_bigint = $EVAL_ERROR ? 0 : 1; +} + + +#--------------------------------------------------------------------- +# C O N F I G +#--------------------------------------------------------------------- + +my %config = ( + 'dsn' => $ENV{'mysqlconnection'} || 'DBI:mysql:information_schema', + 'user' => $ENV{'mysqluser'} || 'root', + 'password' => $ENV{'mysqlpassword'} || '', + 'cache_namespace' => $ENV{'cachenamespace'} || 'munin_mysql', +); + + +#--------------------------------------------------------------------- +# C A C H E +#--------------------------------------------------------------------- + +my %cache_options = ( + 'namespace' => $config{cache_namespace}, + 'default_expires_in' => 60, +); + +my $shared_memory_cache ; +if ($has_cache) +{ + $shared_memory_cache = Cache::SharedMemoryCache->new(\%cache_options) + or die("Couldn't instantiate SharedMemoryCache"); +} + +#--------------------------------------------------------------------- +# G R A P H D E F I N I T I O N S +#--------------------------------------------------------------------- + +# These are defaults to save typing in the graph definitions +my %defaults = ( + global_attrs => { + args => '--base 1000', + }, + data_source_attrs => { + min => '0', + type => 'DERIVE', + draw => 'AREASTACK', + }, +); + +# %graphs contains the graph definitions, it is indexed on the graph +# name. The information stored for each graph is used for both showing +# data source values and for printing the graph configuration. Each +# graph follows the following format: +# +# $graphs{NAME} => { +# config => { +# # The global attributes for this graph +# global_attrs => {} +# # Attributes common to all data sources in this graph +# data_source_attrs => {} +# }, +# data_sources => [ +# # NAME - The name of the data source (e.g. variable names +# # from SHOW STATUS) +# # DATA_SOURCE_ATTRS - key-value pairs with data source +# # attributes +# {name => 'NAME', (DATA_SOURCE_ATTRS)}, +# {...}, +# ], +# +# Note for 'cdef' fields: "%s" is replaced with the original fieldname +my %graphs = (); + +#--------------------------------------------------------------------- + + +$graphs{wsrep_cluster_status} = { + config => { + global_attrs => { + title => 'Galera Status', + vlabel => 'PRIMARY', + }, + data_source_attrs => { + draw => 'LINE1', + min => '0', + max => '1', + }, + }, + data_sources => [ + {name => 'wsrep_cluster_status', label => '0-Primary, 1-Non-Primary', + info => 'If the host is primary', + type => 'GAUGE', + critical => '1'}, + ], +}; + +$graphs{wsrep_cluster_size} = { + config => { + global_attrs => { + title => 'Galera cluster size', + vlabel => 'Hosts', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_cluster_size', label => 'Cluster size', + info => 'The number of hosts in the cluster.', + type => 'GAUGE'}, + ], +}; + + +# http://www.codership.com/wiki/doku.php?id=galera_node_fsm +$graphs{wsrep_local_state} = { + config => { + global_attrs => { + title => 'Galera node state', + vlabel => 'State (galera_node_fsm)', + args => '--lower-limit 0 --upper-limit 6', + }, + data_source_attrs => { + draw => 'LINE1', + min => '0', + max => '6', + }, + }, + data_sources => [ + {name => 'wsrep_local_state', label => '1-Joining, 2-Donor, 3-Joined, 4-Synced, 5-Donor, 6-Join after Donor ', + info => 'The state of the node in the cluster.', + type => 'GAUGE', + warning => '3.5:4.5'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{wsrep_transactions} = { + config => { + global_attrs => { + title => 'Galera transactions', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_last_committed', label => 'Committed transactions', + info => '# of committed transactions.', + type => 'COUNTER', + min => 0}, + {name => 'wsrep_local_commits', label => 'Locally Committed transactions', + info => '# of locally committed transactions.', + type => 'COUNTER', + min => 0}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{wsrep_writesets} = { + config => { + global_attrs => { + title => 'Galera writesets', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_replicated', label => 'Writesets sent', + info => '# of writesets sent to other nodes', + type => 'COUNTER', + min => '0', + graph => 'no'}, + {name => 'wsrep_received', label => 'Writesets received', + info => '# of writesets received from other nodes', + type => 'COUNTER', + min => '0', + negative => 'wsrep_replicated'}, + ], +}; + +#------------------------- + + +$graphs{wsrep_writesetbytes} = { + config => { + global_attrs => { + title => 'Galera writesets bytes/sec', + }, + data_source_attrs => { + }, + }, + data_sources => [ + {name => 'wsrep_received_bytes', label => 'Writesets bytes received', + info => '# of bytes in writesets received from other nodes', + type => 'DERIVE', + min => 0, + graph => 'no'}, + {name => 'wsrep_replicated_bytes', label => 'Writesets bytes sent', + info => '# of bytes in writesets sent to other nodes', + type => 'DERIVE', + draw => 'LINE1', + min => 0, + negative => 'wsrep_received_bytes'}, + {name => 'wsrep_repl_keys_bytes', label => 'Writeset key size sent', + info => '# of bytes in writesets of keys sent to other nodes', + type => 'DERIVE', + min => 0}, + {name => 'wsrep_repl_data_bytes', label => 'Writeset data size sent', + info => '# of bytes in writesets of data sent to other nodes', + type => 'DERIVE', + min => 0}, + {name => 'wsrep_repl_other_bytes', label => 'Writeset other size sent', + info => '# of bytes in writesets of other data sent to other nodes', + type => 'DERIVE', + min => 0}, + ], +}; + + +#------------------------- + +$graphs{wsrep_errors} = { + config => { + global_attrs => { + title => 'Galera transaction problems' + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_local_cert_failures', label => 'Certification failures', + type => 'DERIVE', + min => 0}, + {name => 'wsrep_local_bf_aborts', label => 'Aborted local transactions', + type => 'DERIVE', + min => 0}, + {name => 'wsrep_local_replays', label => 'Replays', + type => 'DERIVE', + min => 0}, + ], +}; + +#------------------------- + +$graphs{wsrep_queue} = { + config => { + global_attrs => { + title => 'Galera queues', + vlabel => 'queue length received (-) / sent (+) per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_local_recv_queue', label => 'Receive queue length', + type => 'GAUGE', + graph => 'no'}, + {name => 'wsrep_local_recv_queue_min', label => 'Receive queue length min', + type => 'GAUGE', + graph => 'no'}, + {name => 'wsrep_local_recv_queue_avg', label => 'Average receive queue length', + type => 'GAUGE', + graph => 'no'}, + {name => 'wsrep_local_recv_queue_max', label => 'Receive queue length max', + type => 'GAUGE', + graph => 'no'}, + {name => 'wsrep_local_send_queue', label => 'Send queue length', + type => 'GAUGE', + negative => 'wsrep_local_recv_queue'}, + {name => 'wsrep_local_send_queue_min', label => 'Send queue length min', + type => 'GAUGE', + negative => 'wsrep_local_recv_queue_min'}, + {name => 'wsrep_local_send_queue_avg', label => 'Average send queue length', + type => 'GAUGE', + negative => 'wsrep_local_recv_queue_avg'}, + {name => 'wsrep_local_send_queue_max', label => 'Send queue length max', + type => 'GAUGE', + negative => 'wsrep_local_recv_queue_max'}, + ], +}; + +#------------------------- + +$graphs{wsrep_concurrency} = { + config => { + global_attrs => { + title => 'Galera Performance - Apply to Commit', + vlabel => 'commit + / apply - ' + }, + data_source_attrs => { + draw => 'LINE1', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'wsrep_apply_window', label => 'apply window', + graph => 'no'}, + {name => 'wsrep_apply_oooe', label => 'apply out of order', + graph => 'no'}, + {name => 'wsrep_apply_oool', label => 'apply out of order (slowness)', + graph => 'no'}, + {name => 'wsrep_commit_window', label => 'commit window', + negative => 'wsrep_apply_window'}, + {name => 'wsrep_commit_oooe', label => 'commit out of order', + negative => 'wsrep_apply_oooe'}, + {name => 'wsrep_commit_oool', label => 'commit out of order (slowness)', + negative => 'wsrep_apply_oool'}, + ], +}; + +#------------------------- + +$graphs{wsrep_flow} = { + config => { + global_attrs => { + title => 'Galera flow control', + vlabel => 'events received (-) / sent (+) per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_flow_control_recv', label => 'Pause events received', + type => 'DERIVE', + min => 0, + graph => 'no'}, + {name => 'wsrep_flow_control_sent', label => 'Pause events sent', + type => 'DERIVE', + min => 0, + negative => 'wsrep_flow_control_recv'}, + ], + }; + + + +#------------------------- + +$graphs{wsrep_flow_paused} = { + config => { + global_attrs => { + title => 'Galera flow control paused ratio', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_flow_control_paused', label => 'Ratio flow control was paused', + type => 'GAUGE', + min => '0', + max => '1', + warning => 0.1, + critical => 0.9}, + ], + }; + +#------------------------- + +$graphs{wsrep_flow_paused_ns} = { + config => { + global_attrs => { + title => 'Galera flow control paused time', + vlabel => 'nanoseconds', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_flow_control_paused_ns', label => 'Time flow control was paused (ns)', + min => '0', + warning => 20000, + critical => 1000000}, + ], + }; + +#------------------------- + +$graphs{wsrep_distance} = { + config => { + global_attrs => { + title => 'Galera distance', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'wsrep_cert_deps_distance', label => 'cert_deps_distance', + type => 'GAUGE'}, + {name => 'wsrep_cert_index_size', label => 'wsrep_cert_index_size', + type => 'GAUGE'}, + {name => 'wsrep_slave_threads', label => 'wsrep_slave_threads', + type => 'GAUGE'}, + {name => 'wsrep_commit_window', label => 'commit_window', + type => 'GAUGE'}, + ], +}; + +#------------------------- +$graphs{bin_relay_log} = { + config => { + global_attrs => { + title => 'Binary/Relay Logs', + vlabel => 'Log activity', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'Binlog_cache_disk_use', label => 'Binlog Cache Disk Use'}, + {name => 'Binlog_cache_use', label => 'Binlog Cache Use'}, + {name => 'Binlog_stmt_cache_disk_use', label => 'Binlog Statement Cache Disk Use'}, + {name => 'Binlog_stmt_cache_use', label => 'Binlog Statement Cache Use'}, + {name => 'ma_binlog_size', label => 'Binary Log Space'}, + {name => 'relay_log_space', label => 'Relay Log Space'}, + ], +}; + +#------------------------- +$graphs{binlog_groupcommit} = { + config => { + global_attrs => { + title => 'Binary Log Group Commits', + vlabel => 'Commits/Groups', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'Binlog_commits', label => 'Binlog commits'}, + {name => 'Binlog_group_commits', label => 'Binlog Group Commits'}, + {name => 'Binlog_group_commit_trigger_count', label => 'Binlog Groups because of binlog_commit_wait_count'}, + {name => 'Binlog_group_commit_trigger_timeout', label => 'Binlog Groups because of binlog_commit_wait_usec'}, + {name => 'Binlog_group_commit_trigger_lock_wait', label => 'Binlog Groups because of transactions'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{commands} = { + config => { + global_attrs => { + title => 'Command Counters', + vlabel => 'Commands per ${graph_period}', + total => 'Questions', + }, + data_source_attrs => {}, + }, + data_sources => [ + {name => 'Com_delete', label => 'Delete'}, + {name => 'Com_insert', label => 'Insert'}, + {name => 'Com_insert_select', label => 'Insert select'}, + {name => 'Com_load', label => 'Load Data'}, + {name => 'Com_replace', label => 'Replace'}, + {name => 'Com_replace_select', label => 'Replace select'}, + {name => 'Com_select', label => 'Select'}, + {name => 'Com_update', label => 'Update'}, + {name => 'Com_update_multi', label => 'Update multi'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{connections} = { + config => { + global_attrs => { + title => 'Connections', + vlabel => 'Connections per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'max_connections', label => 'Max connections', + type => 'GAUGE', + draw => 'AREA', + colour => 'cdcfc4'}, + {name => 'Max_used_connections', label => 'Max used', + type => 'GAUGE', + draw => 'AREA', + colour => 'ffd660'}, + {name => 'Aborted_clients', label => 'Aborted clients'}, + {name => 'Aborted_connects', label => 'Aborted connects'}, + {name => 'Threads_connected', label => 'Threads connected', + type => 'GAUGE'}, + {name => 'Threads_running', label => 'Threads running', + type => 'GAUGE'}, + {name => 'Connections', label => 'New connections'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{files} = { + config => { + global_attrs => { + title => 'Files', + }, + data_source_attrs => { + type => 'GAUGE', + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'open_files_limit', label => 'File Limit', + draw => 'AREA', + colour => 'cdcfc4'}, + {name => 'Open_files', label => 'Open files', + type => 'DERIVE', + min => 0}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{tables} = { + config => { + global_attrs => { + title => 'Tables', + }, + data_source_attrs => { + type => 'GAUGE', + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'table_open_cache', label => 'Table cache', + draw => 'AREA', + colour => 'cdcfc4'}, + {name => 'innodb_open_files', label => 'Innodb Table Cache Limit', + draw => 'AREA', + colour => 'ffd660'}, + {name => 'Open_tables', label => 'Open tables'}, + {name => 'Slave_open_temp_tables', label => 'Open Slave Temp Tables'}, + {name => 'Opened_tables', label => 'Opened tables', + type => 'DERIVE', + min => 0}, + {name => 'Opened_views', label => 'Opened Views', + type => 'DERIVE', + min => 0}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{table_definitions} = { + config => { + global_attrs => { + title => 'Tables Definitions', + }, + data_source_attrs => { + type => 'GAUGE', + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'table_definition_cache', label => 'Cache Limit', + draw => 'AREA', + colour => 'cdcfc4'}, + {name => 'Open_table_definitions', label => 'Open'}, + {name => 'Opened_table_definitions', label => 'Opened', + type => 'DERIVE', + min => 0}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_bpool} = { + config => { + global_attrs => { + title => 'InnoDB Buffer Pool', + vlabel => 'Pages', + args => '--base 1024', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_bpool_size', label => 'Buffer pool size', + draw => 'AREA', + colour => 'ffd660'}, + {name => 'ib_bpool_dbpages', label => 'Database pages', + draw => 'AREA', + colour => 'cdcfc4'}, + {name => 'ib_bpool_free', label => 'Free pages'}, + {name => 'ib_bpool_modpages', label => 'Modified pages'}, + {name => 'ib_bpool_oldpages', label => 'Old pages'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_bpool_act} = { + config => { + global_attrs => { + title => 'InnoDB Buffer Pool Activity', + vlabel => 'Pages per ${graph_period}', + total => 'Total', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'ib_bpool_read', label => 'Read'}, + {name => 'ib_bpool_created', label => 'Created'}, + {name => 'ib_bpool_written', label => 'Written'}, + {name => 'ib_bpool_made_young', label => 'Made young'}, + {name => 'ib_bpool_made_not_young', label => 'Made not young'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_bpool_internal_breakdown} = { + config => { + global_attrs => { + title => 'InnoDB Buffer Pool Internal breakdown', + args => '--base 1024 --lower-limit 0', + vlabel => 'bytes', + }, + data_source_attrs => { + min => '0', + draw => 'AREASTACK', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_bpool_internal_adaptive_hash_size_const', label => 'Adaptive Hash const'}, + {name => 'ib_bpool_internal_adaptive_hash_size_var', label => 'Adaptive Hash var'}, + {name => 'ib_bpool_internal_page_hash_size_total', label => 'Page Hash'}, + {name => 'ib_bpool_internal_dictionary_cache_size_const', label => 'Dictionary const'}, + {name => 'ib_bpool_internal_dictionary_cache_size_var', label => 'Dictionary var'}, + {name => 'ib_bpool_internal_file_system_size_const', label => 'Filesystem const'}, + {name => 'ib_bpool_internal_file_system_size_var', label => 'Filesystem var'}, + {name => 'ib_bpool_internal_lock_system_size_const', label => 'Lock system const'}, + {name => 'ib_bpool_internal_lock_system_size_var', label => 'Lock system var'}, + {name => 'ib_bpool_internal_recovery_system_size_const', label => 'Recovery system const'}, + {name => 'ib_bpool_internal_recovery_system_size_var', label => 'Recovery system var'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_insert_buf} = { + config => { + global_attrs => { + title => 'InnoDB Insert Buffer', + vlabel => 'Activity per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'ib_ibuf_inserts', label => 'Merge Inserts'}, + {name => 'ib_ibuf_delete', label => 'Merge Deletes'}, + {name => 'ib_ibuf_merged_rec', label => 'Merged Records'}, + {name => 'ib_ibuf_merges', label => 'Merges'}, + {name => 'ib_ibuf_discard_inserts', label => 'Discard Inserts'}, + {name => 'ib_ibuf_discard_delete', label => 'Discard Deletes'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_adaptive_hash} = { + config => { + global_attrs => { + title => 'InnoDB Adaptive Hash Optimiser', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'Innodb_adaptive_hash_hash_searches', label => 'Hash Searches'}, + {name => 'Innodb_adaptive_hash_non_hash_searches', label => 'Nonhash Searches'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_io} = { + config => { + global_attrs => { + title => 'InnoDB IO', + vlabel => 'IO operations per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'ib_io_read', label => 'File reads'}, + {name => 'ib_io_write', label => 'File writes'}, + {name => 'ib_io_log', label => 'Log writes'}, + {name => 'ib_io_fsync', label => 'File syncs'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_io_pend} = { + config => { + global_attrs => { + title => 'InnoDB IO Pending', + vlabel => 'Pending operations', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'ib_iop_log', label => 'AIO Log'}, + {name => 'ib_iop_sync', label => 'AIO Sync'}, + {name => 'ib_iop_flush_bpool', label => 'Buf Pool Flush'}, + {name => 'ib_iop_flush_log', label => 'Log Flushes'}, + {name => 'ib_iop_ibuf_aio', label => 'Insert Buf AIO Read'}, + {name => 'ib_iop_aioread', label => 'Normal AIO Reads'}, + {name => 'ib_iop_aiowrite', label => 'Normal AIO Writes'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_log} = { + config => { + global_attrs => { + title => 'InnoDB Log', + vlabel => 'Log activity per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'innodb_log_buffer_size', label => 'Buffer Size', + type => 'GAUGE', + draw => 'AREA', + colour => 'fafd9e'}, + {name => 'ib_log_flush', label => 'KB Flushed'}, + {name => 'ib_log_written', label => 'KB Written'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_rows} = { + config => { + global_attrs => { + title => 'InnoDB Row Operations', + vlabel => 'Operations per ${graph_period}', + total => 'Total', + }, + data_source_attrs => {}, + }, + data_sources => [ + {name => 'Innodb_rows_deleted', label => 'Deletes'}, + {name => 'Innodb_rows_inserted', label => 'Inserts'}, + {name => 'Innodb_rows_read', label => 'Reads'}, + {name => 'Innodb_rows_updated', label => 'Updates'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_semaphores} = { + config => { + global_attrs => { + title => 'InnoDB Semaphores', + vlabel => 'Semaphores per ${graph_period}', + }, + data_source_attrs => { + draw => 'AREASTACK', + }, + }, + data_sources => [ + {name => 'ib_spin_rounds', label => 'Spin Rounds'}, + {name => 'ib_spin_waits', label => 'Spin Waits'}, + {name => 'ib_os_waits', label => 'OS Waits'}, + {name => 'ib_rw_shared_rounds', label => 'RW/S Rounds'}, + {name => 'ib_rw_shared_waits', label => 'RW/S Waits'}, + {name => 'ib_rw_shared_os_waits', label => 'RW/S OS Waits'}, + {name => 'ib_rw_excl_rounds', label => 'RW/X Rounds'}, + {name => 'ib_rw_excl_waits', label => 'RW/X Waits'}, + {name => 'ib_rw_excl_os_waits', label => 'RW/X OS Waits'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_tnx} = { + config => { + global_attrs => { + title => 'InnoDB Transactions', + vlabel => 'Transactions per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'ib_tnx', label => 'Transactions created'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_history_list_length} = { + config => { + global_attrs => { + title => 'InnoDB History List Length', + vlabel => 'Undo log units', + }, + data_source_attrs => { + draw => 'LINE1', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_tnx_hist', label => 'History List Length'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_srv_master_thread} = { + config => { + global_attrs => { + title => 'InnoDB Master Thread', + }, + data_source_attrs => { + type => 'DERIVE', + draw => 'AREASTACK', + }, + }, + data_sources => [ + {name => 'ib_srv_main_flush_loops', label => 'Flush Loop'}, + {name => 'ib_srv_main_background_loops', label => 'Background Loop'}, + {name => 'ib_srv_main_flushs_writes', label => 'Flushes/Writes', draw => 'LINE1'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_queries} = { + config => { + global_attrs => { + title => 'InnoDB Engine Queries and Transactions', + args => '--lower-limit 0', + }, + data_source_attrs => { + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_innodb_queries', label => 'Active'}, + {name => 'ib_innodb_transactions_active', label => 'Transactions'}, + {name => 'ib_innodb_query_queue_len', label => 'Queued'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_read_views} = { + config => { + global_attrs => { + title => 'InnoDB Read Views', + args => '--lower-limit 0', + }, + data_source_attrs => { + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_innodb_read_views', label => 'Views'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{innodb_descriptors} = { + config => { + global_attrs => { + title => 'InnoDB Descriptors', + args => '--lower-limit 0', + }, + data_source_attrs => { + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'ib_innodb_descriptors', label => 'Descriptors'}, + {name => 'ib_innodb_descriptors_max', label => 'Max', draw => 'AREA', colour => 'ffd660'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{performance} = { + config => { + global_attrs => { + title => 'Performance Schema Losses', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'Performance_schema_cond_classes_lost', label => 'Condition classes'}, + {name => 'Performance_schema_cond_instances_lost', label => 'Condition instances'}, + {name => 'Performance_schema_file_classes_lost', label => 'File classes'}, + {name => 'Performance_schema_file_handles_lost', label => 'File handles'}, + {name => 'Performance_schema_file_instances_lost', label => 'File instances'}, + {name => 'Performance_schema_locker_lost', label => 'Locker'}, + {name => 'Performance_schema_mutex_classes_lost', label => 'Mutex classes'}, + {name => 'Performance_schema_mutex_instances_lost', label => 'Mutex instances'}, + {name => 'Performance_schema_rwlock_classes_lost', label => 'Read/Write lock classes'}, + {name => 'Performance_schema_rwlock_instances_lost', label => 'Read/Write lock instances'}, + {name => 'Performance_schema_table_handles_lost', label => 'Table handles'}, + {name => 'Performance_schema_table_instances_lost', label => 'Table instances'}, + {name => 'Performance_schema_thread_classes_lost', label => 'Thread classes'}, + {name => 'Performance_schema_thread_instances_lost', label => 'Thread instances'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{myisam_indexes} = { + config => { + global_attrs => { + title => 'MyISAM Indexes', + vlabel => 'Requests per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Key_read_requests', label => 'Key read requests'}, + {name => 'Key_reads', label => 'Key reads'}, + {name => 'Key_write_requests', label => 'Key write requests'}, + {name => 'Key_writes', label => 'Key writes'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{network_traffic} = { + config => { + global_attrs => { + title => 'Network Traffic', + args => '--base 1024', + vlabel => 'Bytes received (-) / sent (+) per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Bytes_received', label => 'Bytes transferred', + graph => 'no'}, + {name => 'Bytes_sent', label => 'Bytes transferred', + negative => 'Bytes_received'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{qcache} = { + config => { + global_attrs => { + title => 'Query Cache', + vlabel => 'Commands per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'Qcache_queries_in_cache', label => 'Queries in cache', type => 'GAUGE'}, + {name => 'Qcache_hits', label => 'Cache hits'}, + {name => 'Subquery_cache_hit', label => 'Subquery Cache hits'}, + {name => 'Subquery_cache_miss', label => 'Subquery Cache misses'}, + {name => 'Qcache_inserts', label => 'Inserts'}, + {name => 'Qcache_not_cached', label => 'Not cached'}, + {name => 'Qcache_lowmem_prunes', label => 'Low-memory prunes'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{qcache_mem} = { + config => { + global_attrs => { + title => 'Query Cache Memory', + vlabel => 'Bytes', + args => '--base 1024 --lower-limit 0', + }, + data_source_attrs => { + draw => 'AREA', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'query_cache_size', label => 'Cache size'}, + {name => 'Qcache_free_memory', label => 'Free mem'}, + ], +}; + + +#--------------------------------------------------------------------- + +$graphs{max_mem} = { + config => { + global_attrs => { + title => 'Maximum memory that MySQL could use', + vlabel => 'Bytes', + args => '--base 1024 --lower-limit 0', + }, + data_source_attrs => { + draw => 'AREASTACK', + type => 'GAUGE', + }, + }, + data_sources => [ + {name => 'mysql_connection_memory', label => 'Connection Memory'}, + {name => 'mysql_base_memory', label => 'Base MySQL Memory'}, + ], +}; + + +#--------------------------------------------------------------------- + +$graphs{replication} = { + config => { + global_attrs => { + title => 'Replication', + vlabel => 'Activity', + }, + data_source_attrs => { + draw => 'LINE1', + }, + }, + data_sources => [ + {name => 'slave_io_running', label => 'Slave IO Running', + type => 'GAUGE', + draw => 'AREA'}, + {name => 'slave_sql_running', label => 'Slave SQL Running', + type => 'GAUGE', + draw => 'AREA'}, + {name => 'Slave_retried_transactions', label => 'Retried Transactions'}, + {name => 'Slave_open_temp_tables', label => 'Open Temp Tables'}, + {name => 'seconds_behind_master', label => 'Secs Behind Master', + type => 'GAUGE'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{select_types} = { + config => { + global_attrs => { + title => 'Select types', + vlabel => 'Commands per ${graph_period}', + total => 'Total', + }, + data_source_attrs => {}, + }, + data_sources => [ + {name => 'Select_full_join', label => 'Full join'}, + {name => 'Select_full_range_join', label => 'Full range'}, + {name => 'Select_range', label => 'Range'}, + {name => 'Select_range_check', label => 'Range check'}, + {name => 'Select_scan', label => 'Scan'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{slow} = { + config => { + global_attrs => { + title => 'Slow Queries', + vlabel => 'Slow queries per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Slow_queries', label => 'Slow queries'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{sorts} = { + config => { + global_attrs => { + title => 'Sorts', + vlabel => 'Sorts / ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Sort_rows', label => 'Rows sorted'}, + {name => 'Sort_range', label => 'Range'}, + {name => 'Sort_merge_passes', label => 'Merge passes'}, + {name => 'Sort_scan', label => 'Scan'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{table_locks} = { + config => { + global_attrs => { + title => 'Table locks', + vlabel => 'locks per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Table_locks_immediate', label => 'Table locks immed'}, + {name => 'Table_locks_waited', label => 'Table locks waited'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{tmp_tables} = { + config => { + global_attrs => { + title => 'Temporary objects', + vlabel => 'Objects per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + }, + }, + data_sources => [ + {name => 'Created_tmp_disk_tables', label => 'Temp disk tables'}, + {name => 'Created_tmp_tables', label => 'Temp tables'}, + {name => 'Created_tmp_files', label => 'Temp files'}, + ], +}; + + +#--------------------------------------------------------------------- + +$graphs{rows} = { + config => { + global_attrs => { + title => 'Rows', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Rows_read', label => 'Read'}, + {name => 'Rows_sent', label => 'Sent'}, + {name => 'Rows_tmp_read', label => 'Temp Read'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{handler_read} = { + config => { + global_attrs => { + title => 'Read Handler', + }, + data_source_attrs => { + draw => 'AREASTACK', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_read_first', label => 'Key First'}, + {name => 'Handler_read_key', label => 'Key Read'}, + {name => 'Handler_read_last', label => 'Key Last'}, + {name => 'Handler_read_prev', label => 'Key Prev'}, + {name => 'Handler_read_rnd', label => 'Row position'}, + {name => 'Handler_read_rnd_deleted', label => 'Row position delete'}, + {name => 'Handler_read_rnd_next', label => 'Row position next'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{handler_transaction} = { + config => { + global_attrs => { + title => 'Transactions Handler', + }, + data_source_attrs => { + draw => 'AREASTACK', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_commit', label => 'Commit'}, + {name => 'Handler_rollback', label => 'Rollback'}, + {name => 'Handler_savepoint', label => 'Savepoint'}, + {name => 'Handler_savepoint_rollback', label => 'Savepoint Rollback'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{handler_write} = { + config => { + global_attrs => { + title => 'Write/Update Handler', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_write', label => 'Writes'}, + {name => 'Handler_update', label => 'Updates'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{handler_tmp} = { + config => { + global_attrs => { + title => 'Temporary Write/Update Handler', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_tmp_write', label => 'Writes'}, + {name => 'Handler_tmp_update', label => 'Updates'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{execution} = { + config => { + global_attrs => { + title => 'Execution Events', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Executed_events', label => 'Events'}, + {name => 'Executed_triggers', label => 'Triggers'}, + ], + }; + +#--------------------------------------------------------------------- + +$graphs{icp} = { + config => { + global_attrs => { + title => 'Index Condition Pushdown', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_icp_attempts', label => 'Attempts'}, + {name => 'Handler_icp_match', label => 'Matches'}, + ], +}; + +#--------------------------------------------------------------------- + +$graphs{mrr} = { + config => { + global_attrs => { + title => 'Multi Range Read optimizations', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + data_sources => [ + {name => 'Handler_mrr_init', label => 'Uses'}, + {name => 'Handler_mrr_key_refills', label => 'Key refills'}, + {name => 'Handler_mrr_rowid_refills', label => 'Row refills'}, + ], +}; + +#--------------------------------------------------------------------- +# Plugin Graphs +# These are MySQL plugins of type INFORMATION SCHEMA +# +# These will be added to $graphs if available +#--------------------------------------------------------------------- + +my %graph_plugins = (); + +$graph_plugins{query_response_time} = { + count => { + config => { + global_attrs => { + title => 'Query Response Time Count', + vlabel => 'queries per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + # convert microseconds back to the SI unit + cdef => '%s,1000000,/', + }, + }, + # data_sources are populated by sub plugin_query_response_time + data_sources => [ + ], + }, + total => { + config => { + global_attrs => { + title => 'Query Response Time Total', + vlabel => 'cumulated query time per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + # data_sources are populated by sub plugin_query_response_time + data_sources => [ + ], + } +}; + +$graph_plugins{user_statistics} = { + connections => { + config => { + global_attrs => { + title => 'User Connections', + vlabel => 'connections per ${graph_period}', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + cols => { 'total_connections' => {}, 'concurrent_connections' => {}, 'denied_connections' => {}, 'lost_connections' => {}}, + data_sources => [ + ], + }, + usertime => { + config => { + global_attrs => { + title => 'User Time', + vlabel => 'seconds', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + cols => { 'connected_time' => {}, 'busy_time' => {}, 'cpu_time' => {} }, + data_sources => [ + ], + }, + bytes => { + config => { + global_attrs => { + title => 'User Bytes', + vlabel => 'bytes', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + cols => { 'bytes_received' => {}, 'bytes_sent' => {}, 'binlog_bytes_written' => {} }, + data_sources => [ + ], + }, + rows => { + config => { + global_attrs => { + title => 'User Rows', + vlabel => 'rows', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + cols => { 'rows_read' => {}, 'rows_sent' => {}, 'rows_deleted' => {}, 'rows_inserted' => {}, 'rows_updated' => {} }, + data_sources => [ + ], + }, + commands => { + config => { + global_attrs => { + title => 'Command breakdown by user', + vlabel => 'commands', + }, + data_source_attrs => { + draw => 'LINE2', + type => 'DERIVE', + }, + }, + cols => { 'select_commands' => {}, 'update_commands' => {}, 'other_commands' => {}, 'commit_transactions' => {}, 'rollback_transactions' => {} }, + data_sources => [ + ], + } + +}; +#--------------------------------------------------------------------- +# M A I N +#--------------------------------------------------------------------- + + +# +# Global hash holding the data collected from MySQL. +# +our $data; # Was 'my'. Changed to 'our' to facilitate testing. + + +sub main { + my $graph = basename($0); + $graph =~ s/^mysql[0-9]*_//g; # allow multiple instances + my $command = $ARGV[0] || 'show'; + + my %command_map = ( + 'autoconf' => \&autoconf, + 'config' => \&config, + 'show' => \&show, + 'suggest' => \&suggest, + ); + + die "Unknown command: $command" + unless exists $command_map{$command}; + + die "Missing dependency Cache::Cache" + unless $has_cache || $command eq 'autoconf'; + + die "Missing dependency DBI" + unless $has_dbi || $command eq 'autoconf'; + + die "Missing dependency Math::BigInt" + unless $has_math_bigint || $command eq 'autoconf'; + + return $command_map{$command}->($graph); +} + + +#--------------------------------------------------------------------- +# C O M M A N D H A N D L E R S +#--------------------------------------------------------------------- + +# Each command handler should return an appropriate exit code + + +# http://munin-monitoring.org/wiki/ConcisePlugins#autoconf +sub autoconf { + unless ($has_cache) { + print "no (Missing dependency Cache::Cache)\n"; + return 0; + } + unless ($has_dbi) { + print "no (Missing dependency DBI)\n"; + return 0; + } + unless ($has_math_bigint) { + print "no (Missing dependency Math::BigInt)\n"; + return 0; + } + + eval { + db_connect(); + }; + if ($@) { + my $err = $@; + $err =~ s{\s at \s \S+ \s line .*}{}xms; + print "no ($err)\n"; + return 0; + } + print "yes\n"; + return 0; +} + + +# http://munin-monitoring.org/wiki/ConcisePlugins#suggest +sub suggest { + + # What is the best way to decide which graphs is applicable to a + # given system? + # Answer: + # Use lack of variables to indicate that the capability doesn't exist + # Use variable values to indicate some graph isn't currently used. + # update_data() now does this. + + update_data(); + + + foreach my $graph (sort keys(%graphs)) { + next if $graph =~ /innodb_/ && $data->{_innodb_disabled}; + next if $graph =~ /wsrep_/ && $data->{_galera_disabled}; + print "$graph\n"; + } + + return 0; +} + + +sub config { + my $graph_name = shift; + + # In MySQL 5.1 (and probably earlier versions as well) status + # variables are unique when looking at the last 19 characters. + # + # SELECT RIGHT(variable_name, 19), COUNT(*) + # FROM information_schema.global_status + # GROUP BY RIGHT(variable_name, 19) + # HAVING COUNT(*) > 1; + # + # Empty set (0.06 sec) + # + # There is one duplicate when looking at server variables + # + # SELECT RIGHT(variable_name, 19), COUNT(*) + # FROM information_schema.global_variables + # GROUP BY RIGHT(variable_name, 19) + # HAVING COUNT(*) > 1; + # + # +--------------------------+----------+ + # | RIGHT(variable_name, 19) | COUNT(*) | + # +--------------------------+----------+ + # | OW_PRIORITY_UPDATES | 2 | + # +--------------------------+----------+ + # 1 row in set (0.05 sec) + # + # show global variables like '%OW_PRIORITY_UPDATES'; + # + # +--------------------------+-------+ + # | Variable_name | Value | + # +--------------------------+-------+ + # | low_priority_updates | OFF | + # | sql_low_priority_updates | OFF | + # +--------------------------+-------+ + # 2 rows in set (0.00 sec) + # + # Not a problem since we don't graph these + + update_data(); + + die 'Unknown graph ' . ($graph_name ? $graph_name : '') + unless $graphs{$graph_name}; + + my $graph = $graphs{$graph_name}; + + my %conf = (%{$defaults{global_attrs}}, %{$graph->{config}{global_attrs}}); + while (my ($k, $v) = each %conf) { + print "graph_$k $v\n"; + } + print "graph_category db\n"; + + for my $ds (@{$graph->{data_sources}}) { + my %ds_spec = ( + %{$defaults{data_source_attrs}}, + %{$graph->{config}{data_source_attrs}}, + %$ds, + ); + while (my ($k, $v) = each %ds_spec) { + # 'name' is only used internally in this script, not + # understood by munin. + next if ($k eq 'name'); + + # support simple pattern substitution in cdef ("%s" -> fieldname) + my $fieldname = clean_fieldname($ds->{name}); + $v =~ s/%s/$fieldname/g if (($k eq "cdef") and ($v =~ /%s/)); + printf("%s.%s %s\n", $fieldname, $k, $v); + } + print_thresholds(clean_fieldname($ds->{name})); + } + + return 0; +} + +sub show { + my $graph_name = shift; + + update_data(); + + die 'Unknown graph ' . ($graph_name ? $graph_name : '') + unless $graphs{$graph_name}; + + my $graph = $graphs{$graph_name}; + + die "Can't show data for '$graph_name' because InnoDB is disabled." + if $graph_name =~ /innodb_/ && $data->{_innodb_disabled}; + + die "Can't show data for '$graph_name' because not a Galera MySQL version." + if $graph_name =~ /wsrep_/ && $data->{_galera_disabled}; + + for my $ds (@{$graph->{data_sources}}) { + printf "%s.value %s\n", + clean_fieldname($ds->{name}), + defined $data->{$ds->{name}} ? $data->{$ds->{name}} : 'U'; + } + + return 0; +} + + + +#--------------------------------------------------------------------- +# U T I L I T Y S U B S +#--------------------------------------------------------------------- + + +sub db_connect { + my $dsn = "$config{dsn};mysql_connect_timeout=5"; + + return DBI->connect($dsn, $config{user}, $config{password}, { + RaiseError => 1, + PrintError => 0, + FetchHashKeyName => 'NAME_lc', + }); +} + + +sub update_data { + $data = $shared_memory_cache->get('data'); + my $graphs_stored = $shared_memory_cache->get('graphs'); + %graphs = %{thaw($graphs_stored)} if $graphs_stored; + return if $data; + + $data = {}; + + my $dbh = db_connect(); + + update_variables($dbh); + update_plugins($dbh); + update_innodb($dbh); + update_master($dbh); + delete $graphs{replication} if update_slave($dbh)==1; + + delete $graphs{bin_relay_log} if not defined $data->{relay_log_space}; + + delete $graphs{execution} if not defined $data->{Executed_events} + && not defined $data->{Executed_triggers}; + + delete $graphs{icp} if not defined $data->{Handler_icp_attempts} + && not defined $data->{Handler_icp_matches}; + + delete $graphs{innodb_adaptive_hash} + if not defined $data->{Innodb_adaptive_hash_hash_searches} + && not defined $data->{Innodb_adaptive_hash_non_hash_searches}; + + delete $graphs{innodb_bpool_internal_breakdown} + if not defined $data->{ib_bpool_internal_adaptive_hash_size_const}; + + delete $graphs{innodb_descriptors} + if not defined $data->{ib_innodb_descriptors}; + + delete $graphs{mrr} if not defined $data->{Handler_mrr_init}; + + delete $graphs{rows} if not defined $data->{Rows_sent}; + + delete $graphs{handler_temp} if not defined $data->{Handler_tmp_write}; + + $shared_memory_cache->set('data', $data); + $shared_memory_cache->set('graphs', nfreeze(\%graphs)); +} + + +sub update_plugins { + my ($dbh) = @_; + + my %plugin_map = ( + 'query_response_time' => \&plugin_query_response_time, + ); + + sub add_graphs { + my ($f, $sec, $dbh, %g) = @_; + if ($f->($dbh) == 0) { + while (my ($k, $v) = each %g) { + $graphs{$sec . '_' . $k} = $v; + } + } + } + + my $sth = $dbh->prepare("SHOW PLUGINS"); + $sth->execute(); + while (my $row = $sth->fetchrow_hashref()) { + next if $row->{'type'} ne 'INFORMATION SCHEMA'; + my $sec = lc $row->{'name'}; + next if not exists $plugin_map{$sec}; + add_graphs($plugin_map{$sec}, $sec, $dbh, %{$graph_plugins{$sec}}); + } + $sth->finish(); + + my %is_map = ( + 'user_statistics' => \&is_user_statistics, + ); + + $sth = $dbh->prepare("SHOW TABLES IN INFORMATION_SCHEMA"); + $sth->execute(); + while (my $row = $sth->fetchrow_hashref()) { + my $sec = lc $row->{'tables_in_information_schema'}; + next if not exists $is_map{$sec}; + add_graphs($is_map{$sec}, $sec, $dbh, %{$graph_plugins{$sec}}); + } + $sth->finish(); +} + +sub update_variables { + my ($dbh) = @_; + my @queries = ( + 'SHOW GLOBAL STATUS', + 'SHOW GLOBAL VARIABLES', + ); + + my %variable_name_map = ( + table_cache => 'table_open_cache', # table_open_cache was + # previously known as + # table_cache in MySQL + # 5.1.2 and earlier. + ); + my %wsrep_cluster_status_map = ( + 'Primary' => 0, + 'non-Primary' => 1, + ); + + for my $query (@queries) { + $data->{$query} = {}; + + my $sth = $dbh->prepare($query); + $sth->execute(); + while (my $row = $sth->fetch) { + my $var = $variable_name_map{$row->[0]} || $row->[0]; + $data->{$var} = $row->[1]; + } + $sth->finish(); + } + + $data->{'mysql_base_memory'} = $data->{'key_buffer_size'} + + ( $data->{'query_cache_size'} || 0 ) + + $data->{'innodb_buffer_pool_size'} + + ( $data->{'innodb_additional_mem_pool_size'} || 0 ) + + $data->{'innodb_log_buffer_size'} + + ( $data->{'tokudb_cache_size'} || 0 ); + + my $tmp_table_size = $data->{'tmp_table_size'}; + my $max_heap_table_size = $data->{'max_heap_table_size'}; + $data->{'mysql_connection_memory'} = $data->{'read_buffer_size'} + + $data->{'read_rnd_buffer_size'} + + $data->{'sort_buffer_size'} + + $data->{'join_buffer_size'} + + $data->{'binlog_cache_size'} + + $data->{'thread_stack'} + + ( $tmp_table_size >= $max_heap_table_size ? $tmp_table_size : $max_heap_table_size ) + + ( $data->{'tokudb_read_buf_size'} || 0 ); + + # wsrep_thread_count was separated from max_connections for mariadb-5.5.38 https://mariadb.atlassian.net/browse/MDEV-6206 + $data->{'mysql_connection_memory'} *= $data->{'max_connections'} + ( $data->{'wsrep_thread_count'} || 0 ); + + if ($data->{wsrep_cluster_status}) { + my $var = $wsrep_cluster_status_map{$data->{wsrep_cluster_status}}; + $data->{wsrep_cluster_status} = $var; + } + $data->{_galera_disabled} = 1 unless ($data->{wsrep_provider_name}); +} + + +sub update_innodb { + my ($dbh) = @_; + + my $sth = $dbh->prepare('SHOW /*!50000 ENGINE*/ INNODB STATUS'); + eval { + $sth->execute(); + }; + if ($@) { + if ($@ =~ /Unknown (storage|table) engine 'INNODB'|Cannot call SHOW INNODB STATUS because skip-innodb is defined/i) { + $data->{_innodb_disabled} = 1; + return; + } + die $@; + } + my $row = $sth->fetchrow_hashref(); + my $status = $row->{'status'}; + $sth->finish(); + + parse_innodb_status($status); +} + + +sub update_master { + my ($dbh) = @_; + + my $sth = $dbh->prepare('SHOW MASTER LOGS'); + eval { + $sth->execute(); + }; + if ($@) { + # SHOW MASTER LOGS failed because binlog is not enabled + return if $@ =~ /You are not using binary logging/; + die $@; + } + + while (my $row = $sth->fetch) { + $data->{ma_binlog_size} += $row->[1]; + } + + $sth->finish(); +} + + +sub update_slave { + my ($dbh) = @_; + + my $sth = $dbh->prepare('SHOW SLAVE STATUS'); + $sth->execute(); + my $row = $sth->fetchrow_hashref(); + return 1 unless $row; + while (my ($k, $v) = each %$row) { + $data->{$k} = $v; + } + $sth->finish(); + + # We choose master_host here as a stopped slave + # may not indicate that we have reset all slave capability + # however the minimium requirement is a master_host + return 1 if not defined $data->{master_host}; + + # undef when slave is stopped, or when MySQL fails to calculate + # the lag (which happens depresingly often). (mk-heartbeat fixes + # this problem.) + $data->{seconds_behind_master} ||= 0; + + # Track these two fields so we can trigger warnings if the slave stops + # running + $data->{slave_sql_running} = ($data->{slave_sql_running} eq 'Yes') + ? 0 : 1; + $data->{slave_io_running} = ($data->{slave_io_running} eq 'Yes') + ? 0 : 1; + return 0; +} + + +#--------------------------------------------------------------------- +# Information SCHEMA tables represent data to be processed +#--------------------------------------------------------------------- + + +sub plugin_query_response_time { + my ($dbh) = @_; + + return 1 if not defined $data->{query_response_time_stats}; + return 1 if $data->{query_response_time_stats} eq 'OFF'; + + my $sth = $dbh->prepare("SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME"); + $sth->execute(); + while (my $row = $sth->fetchrow_hashref()) { + my $time = $row->{'time'}; + $data->{'query_response_time_count_' . $time} = $row->{'count'}; + push @{$graph_plugins{query_response_time}->{count}->{data_sources}}, {name => 'query_response_time_count_' . $time, label => $time }; + next if $row->{'total'} eq 'TOO LONG'; + # use microseconds (we use the integer-based DERIVE storage) + $data->{'query_response_time_total_' . $time} = $row->{'total'} * 1e6; + push @{$graph_plugins{query_response_time}->{total}->{data_sources}}, {name => 'query_response_time_total_' . $time, label => $time }; + } + $sth->finish(); + + return 0; +} + +sub is_user_statistics { + my ($dbh) = @_; + + return 1 if not defined $data->{userstat}; + return 1 if $data->{userstat} eq 'OFF'; + + my $sth = $dbh->prepare("SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS"); + $sth->execute(); + while (my $row = $sth->fetchrow_hashref()) { + my $user = $row->{'user'}; + my $var; + while (my ($g, $v) = each %{$graph_plugins{user_statistics}}) { + while (my ($userstat,$conf) = each %{$v->{cols}}) { + $var = 'user_stats_' . $user . '_' . $userstat; + $data->{$var} = int $row->{$userstat}; + my $ds = { %$conf }; + $ds->{name} = $var; + $ds->{label} = $user . ' ' . $userstat; + push @{$graph_plugins{user_statistics}->{$g}->{data_sources}}, $ds; + } + } + } + $sth->finish(); + return 0; +} + +# +# In 'SHOW ENGINE INNODB STATUS' 64 bit integers are not formatted as +# plain integers. They are either: +# +# - split in two and needs to be shifted together, +# - or hexadecimal +# +sub innodb_bigint { + my ($x, $y) = @_; + + return defined $y + ? Math::BigInt->new($x)->blsft(32) + $y + : Math::BigInt->new($x); +} + +#--------------------------------------------------------------------- +# P A R S E 'SHOW ENGINE INNODB STATUS' O U T P U T +#--------------------------------------------------------------------- + + +# A nice walk through +# http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/ + +# The parsing is split in one subrutine per section. Each subroutine +# should parse a block with the following structure +# +# block body ... +# more lines .... +# ---------- + +sub parse_innodb_status { + local $_ = shift; + + # Add a dummy section to the end in case the innodb status output + # has been truncated (Happens for status > 64K characters) + $_ .= "\n----------\nDUMMY\n----------\n"; + + my %section_map = ( + + 'BUFFER POOL AND MEMORY' => \&parse_buffer_pool_and_memory, + 'INDIVIDUAL BUFFER POOL INFO' => \&parse_individual_buffer_pool, + 'FILE I/O' => \&parse_file_io, + 'INSERT BUFFER AND ADAPTIVE HASH INDEX' + => \&parse_insert_buffer_and_adaptive_hash_index, + 'LATEST DETECTED DEADLOCK' => \&skip, + 'LATEST FOREIGN KEY ERROR' => \&skip, + 'LOG' => \&parse_log, + 'ROW OPERATIONS' => \&parse_row_operations, + 'SEMAPHORES' => \&parse_semaphores, + 'TRANSACTIONS' => \&parse_transactions, + 'BACKGROUND THREAD' => \&parse_background_thread, + ); + + skip_heading(); + parse_header_seconds(); + for (;;) { + m/\G(.*)\n/gc; + my $sec = $1; + + last if $sec eq 'END OF INNODB MONITOR OUTPUT'; + if ($sec eq 'DUMMY') { + handle_incomplete_innodb_status(); + last; + } + + if (exists $section_map{$sec}) { + $section_map{$sec}->(); + } else { + #warn "Unknown section: $1"; + skip(); + } + } +} + + +# This regular expression handles the different formatting of 64-bit +# integers in different versions of the innodb engine. Either two +# decimal 32-bit integers separated by a space, or a single +# hexadecimal 64-bit integer. +my $innodb_bigint_rx = qr{([[a-fA-F\d]+)(?: (\d+))?}; + + +sub match_new_section { + return m/\G + -+\n # --------------------------- + (?= [A-Z\/ ]+\n # SECTION NAME + [=-]+\n)/gcx; # --------------------------- ('=' on end of output) +} + + +sub skip_line { return m/\G.*\n/gc; } + + +sub skip_heading { + # Heading is 3 lines + for my $foo (1...3) { + skip_line or die('Parse error'); + } +} + + +sub parse_section { + my ($parser) = @_; + + #warn substr($_, pos(), 10); + for (;;) { + return if match_new_section; + next if $parser->(); + skip_line(); + } +} + + +sub skip { parse_section(sub {}); } + + +sub parse_header_seconds { + parse_section( + sub { + m/\GPer second averages calculated from the last (\d+) seconds\n/gc && do { + $data->{innodb_engine_status_seconds} = $1; + return 1; + }; + } + ); +} + + +sub parse_background_thread { + parse_section( + sub { + m/\Gsrv_master_thread loops: \d+ 1_second, \d+ sleeps, \d+ 10_second, (\d+) background, (\d+) flush\n/gc && do { + $data->{ib_srv_main_flush_loops} = $1; + $data->{ib_srv_main_background_loops} = $2; + return 1; + }; + m/\Gsrv_master_thread log flush and writes: (\d+)\n/gc && do { + $data->{ib_srv_main_flushs_writes} = $1; + return 1; + }; + } + ); +} + +sub parse_row_operations { + parse_section( + sub { + m/\G(\d+) queries inside InnoDB, (\d+) queries in queue\n/gc && do { + $data->{ib_innodb_queries} = $1; + $data->{ib_innodb_query_queue_len} = $2; + return 1; + }; + m/\G(\d+) read views open inside InnoDB\n/gc && do { + $data->{ib_innodb_read_views} = $1; + return 1; + }; + m/\G(\d+) transactions active inside InnoDB\n/gc && do { + $data->{ib_innodb_transactions_active} = $1; + return 1; + }; + m/\G(\d+) out of (\d+) descriptors used\n/gc && do { + $data->{ib_innodb_descriptors} = $1; + $data->{ib_innodb_descriptors_max} = $2; + return 1; + }; + # no need for this - its exposed as status variables + # m/\GNumber of rows inserted (\d+), updated (\d+), deleted (\d+), read (\d+)\n/gc && do { + # $data->{ib_innodb_rows_inserted} = $1; + # $data->{ib_innodb_rows_updated} = $2; + # $data->{ib_innodb_rows_deleted} = $3; + # $data->{ib_innodb_rows_read} = $4; + # return 1; + # }; + } + ); +} + +sub parse_semaphores { + parse_section( + sub { + m/\GMutex spin waits (\d+), rounds (\d+), OS waits (\d+)\n/gc && do { + $data->{ib_spin_waits} = $1; + $data->{ib_spin_rounds} = $2; + $data->{ib_os_waits} = $3; + return 1; + }; + m/\GRW-shared spins (\d+), rounds (\d+), OS waits (\d+)\n/gc && do { + $data->{ib_rw_shared_waits} = $1; + $data->{ib_rw_shared_rounds} = $2; + $data->{ib_rw_shared_os_waits} = $3; + return 1; + }; + m/\GRW-excl spins (\d+), rounds (\d+), OS waits (\d+)\n/gc && do { + $data->{ib_rw_excl_waits} = $1; + $data->{ib_rw_excl_rounds} = $2; + $data->{ib_rw_excl_os_waits} = $3; + return 1; + }; + } + ); +} + + +sub parse_transactions { + parse_section( + sub { + m/\GTrx id counter $innodb_bigint_rx\n/gc && do { + $data->{ib_tnx} = innodb_bigint($1, $2); + return 1; + }; + m/\GPurge done for trx's n:o < $innodb_bigint_rx undo n:o < $innodb_bigint_rx\n/gc && do { + if (defined $3) { + # old format + $data->{ib_tnx_prg} = innodb_bigint($1, $2); + # FIX add to data? innodb_bigint($3, $4); + } + else { + # new format + $data->{ib_tnx_prg} = innodb_bigint($1); + # FIX add to data? innodb_bigint($2); + } + return 1; + }; + m/\GHistory list length (\d+)\n/gc && do { + $data->{ib_tnx_hist} = $1; + return 1; + }; + } + ); + +} + + +sub parse_file_io { + parse_section( + sub { + m/\GPending normal aio reads: (\d+)(?: \[(?:\d+, )*\d+\] )?, aio writes: (\d+)(?: \[(?:\d+, )*\d+\] )?,\n\s*ibuf aio reads: (\d+), log i\/o's: (\d+), sync i\/o's: (\d+)\n/gc && do { + $data->{ib_iop_aioread} = $1; + $data->{ib_iop_aiowrite} = $2; + $data->{ib_iop_ibuf_aio} = $3; + $data->{ib_iop_log} = $4; + $data->{ib_iop_sync} = $5; + return 1; + }; + m/\GPending flushes \(fsync\) log: (\d+); buffer pool: (\d+)\n/gc && do { + $data->{ib_iop_flush_log} = $1; + $data->{ib_iop_flush_bpool} = $2; + return 1; + }; + m/\G(\d+) OS file reads, (\d+) OS file writes, (\d+) OS fsyncs\n/gc && do { + $data->{ib_io_read} = $1; + $data->{ib_io_write} = $2; + $data->{ib_io_fsync} = $3; + return 1; + }; + } + ); +} + + +sub parse_insert_buffer_and_adaptive_hash_index { + parse_section( + sub { + # MySQL < 5.5 + m/\G(\d+) inserts, (\d+) merged recs, (\d+) merges\n/gc && do { + $data->{ib_ibuf_inserts} = $1; + $data->{ib_ibuf_merged_rec} = $2; + $data->{ib_ibuf_merges} = $3; + return 1; + }; + # MySQL >= 5.5 + m/\Gmerged operations:\n insert (\d+), delete mark (\d+), delete (\d+)\ndiscarded operations:\n insert (\d+), delete mark (\d+), delete (\d+)\n/gc && do { + $data->{ib_ibuf_inserts} = $1; + $data->{ib_ibuf_delete_mark} = $2; + $data->{ib_ibuf_delete} = $3; + $data->{ib_ibuf_discard_inserts} = $4; + $data->{ib_ibuf_discard_delete_mark} = $5; + $data->{ib_ibuf_discard_delete} = $6; + $data->{ib_ibuf_merged_rec} = $data->{ib_ibuf_inserts} + $data->{ib_ibuf_discard_inserts}; + return 1; + }; + + m/\GIbuf: size (\d+), free list len (\d+), seg size (\d+),(?: (\d+) merges)?\n/gc && do { + $data->{ib_ibuf_size} = $1; + $data->{ib_ibuf_free_len} = $2; + $data->{ib_ibuf_seg_size} = $3; + $data->{ib_ibuf_merges} = $4 if defined $4; # MySQL >= 5.5 + return 1; + }; + } + ); +} + + +sub parse_log { + parse_section( + sub { + m/\GLog sequence number $innodb_bigint_rx\n/gc && do { + $data->{ib_log_written} = innodb_bigint($1, $2); + return 1; + }; + m/\GLog flushed up to\s+$innodb_bigint_rx\n/gc && do { + $data->{ib_log_flush} = innodb_bigint($1, $2); + return 1; + }; + m/\G(\d+) log i\/o's done.*\n/gc && do { + $data->{ib_io_log} = $1; + return 1; + }; + } + ); +} + + +sub parse_buffer_pool_and_memory { + parse_section( + sub { + m/\GBuffer pool size\s+(\d+)\n/gc && do { + $data->{ib_bpool_size} = $1; + return 1; + }; + m/\GBuffer pool size, bytes\s+(\d+)\n/gc && do { + $data->{ib_bpool_size_bytes} = $1; + return 1; + }; + m/\GFree buffers\s+(\d+)\n/gc && do { + $data->{ib_bpool_free} = $1; + return 1; + }; + m/\GDatabase pages\s+(\d+)\n/gc && do { + $data->{ib_bpool_dbpages} = $1; + return 1; + }; + m/\GModified db pages\s+(\d+)\n/gc && do { + $data->{ib_bpool_modpages} = $1; + return 1; + }; + m/\GOld database pages\s+(\d+)\n/gc && do { + $data->{ib_bpool_oldpages} = $1; + return 1; + }; + m/\GPages made young (\d+), not young (\d+)\n/gc && do { + $data->{ib_bpool_made_young} = $1; + $data->{ib_bpool_made_not_young} = $2; + return 1; + }; + m/\GPages read (\d+), created (\d+), written (\d+)\n/gc && do { + $data->{ib_bpool_read} = $1; + $data->{ib_bpool_created} = $2; + $data->{ib_bpool_written} = $3; + return 1; + }; + # mariadb-5.5 + m/\GInternal hash tables \(constant factor \+ variable factor\)\n\s*Adaptive hash index\s*(\d+)\s*\((\d+) \+ (\d+)\) *\n\s+Page hash +(\d+) +\(buffer pool \d+ only\) *\n\s+Dictionary cache\s*(\d+)\s+\((\d+) \+ (\d+)\) *\n\s+File system\s+(\d+)\s+\((\d+) \+ (\d+)\) *\n\s+Lock system\s+(\d+)\s+\((\d+) \+ (\d+)\) *\n\s+Recovery system\s*(\d+)\s+\((\d+) \+ (\d+)\) *\n/gc + && do { + $data->{ib_bpool_internal_adaptive_hash_size_total} = $1; + $data->{ib_bpool_internal_adaptive_hash_size_const} = $2; + $data->{ib_bpool_internal_adaptive_hash_size_var} = $3; + $data->{ib_bpool_internal_page_hash_size_total} = $4; + $data->{ib_bpool_internal_dictionary_cache_size_total} = $5; + $data->{ib_bpool_internal_dictionary_cache_size_const} = $6; + $data->{ib_bpool_internal_dictionary_cache_size_var} = $7; + $data->{ib_bpool_internal_file_system_size_total} = $8; + $data->{ib_bpool_internal_file_system_size_const} = $9; + $data->{ib_bpool_internal_file_system_size_var} = $10; + $data->{ib_bpool_internal_lock_system_size_total} = $11; + $data->{ib_bpool_internal_lock_system_size_const} = $12; + $data->{ib_bpool_internal_lock_system_size_var} = $13; + $data->{ib_bpool_internal_recovery_system_size_total} = $14; + $data->{ib_bpool_internal_recovery_system_size_const} = $15; + $data->{ib_bpool_internal_recovery_system_size_var} = $16; + return 1; + }; + + } + ); +} + +sub parse_individual_buffer_pool { + parse_section( + sub { + m/\G---BUFFER POOL (\d+)\n/gc && do { + my $pool = $1; + $data->{ib_bpool_individual_pool_count} = $pool + 1; + m/\GBuffer pool size\s+(\d+)\n/gc && do { + $data->{"ib_bpool_individual_pool_${pool}_size"} = $1; + }; + m/\GBuffer pool size, bytes\s+(\d+)\n/gc && do { + $data->{"ib_bpool_individual_pool_${pool}_size_bytes"} = $1; + }; + m/\GFree buffers\s+(\d+)\nDatabase pages\s+(\d+)\nOld database pages\s+(\d+)\nModified db pages\s+(\d+)\nPending reads\s+(\d+)\nPending writes: LRU\s+(\d+), flush list\s+(\d+), single page\s+(\d+)\n/gc && do { + $data->{"ib_bpool_individual_pool_${pool}_free"} = $1; + $data->{"ib_bpool_individual_pool_${pool}_dbpages"} = $2; + $data->{"ib_bpool_individual_pool_${pool}_oldpages"} = $3; + $data->{"ib_bpool_individual_pool_${pool}_modpages"} = $4; + $data->{"ib_bpool_individual_pool_${pool}_pending_reads"} = $5; + $data->{"ib_bpool_individual_pool_${pool}_pending_writes_lru"} = $6; + $data->{"ib_bpool_individual_pool_${pool}_pending_writes_flush"} = $7; + $data->{"ib_bpool_individual_pool_${pool}_pending_writes_single"} = $8; + }; + skip_line(); + m/\GPages read (\d+), created (\d+), written (\d+)\n/gc && do { + $data->{"ib_bpool_individual_pool_${pool}_read"} = $1; + $data->{"ib_bpool_individual_pool_${pool}_created"} = $2; + $data->{"ib_bpool_individual_pool_${pool}_written"} = $3; + }; + return 1; + }; + } + ); +} + +sub handle_incomplete_innodb_status { + + warn "Output from SHOW ENGINE INNODB STATUS was truncated. " + . "This happens if the output of STATUS exceeds 64KB. " + . "Several of the InnoDB graphs might be affected by this."; + + # FIX Is it possible to find some of the missing values from SHOW + # STATUS? +} + + +exit main() unless caller; + + +1; diff --git a/nginx_cgi_graphs.conf b/nginx_cgi_graphs.conf new file mode 100644 index 0000000..666cc90 --- /dev/null +++ b/nginx_cgi_graphs.conf @@ -0,0 +1,40 @@ +# Example configuration for nginx with cgi generated graphs. +# +# To use this example config file you need to enable cgi graphs in Munin. Add +# following three lines to /etc/munin/conf.d/local.conf (without # character): +# +# graph_strategy cgi +# html_strategy cgi +# cgiurl_graph /munin/graph +# +# Then copy this file to /etc/nginx/conf.d/ directory and restart nginx. +# Services munin-cgi-html and munin-cgi-graph must also be started: +# +# systemctl enable --now munin-cgi-html.socket munin-cgi-graph.socket +# +# Access Munin at http://localhost/munin/ + + +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + + location /munin/static/ { + alias /etc/munin/static/; + } + + location /munin/graph/ { + include fastcgi_params; + fastcgi_split_path_info ^(/munin/graph)(.*); + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass unix:/var/run/munin/munin-cgi-graph.sock; + } + + location /munin/ { + include fastcgi_params; + fastcgi_split_path_info ^(/munin)(.*); + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_pass unix:/var/run/munin/munin-cgi-html.sock; + } +} diff --git a/nginx_munin.conf b/nginx_munin.conf deleted file mode 100644 index 51dbb42..0000000 --- a/nginx_munin.conf +++ /dev/null @@ -1,49 +0,0 @@ -server { - # Example configuration! Change this to suit your needs. - # Access munin at http://localhost/munin/ - # NOTE - Do not remove this file, otherwise munin package upgrade - # recreates this. - - listen 80; - server_name localhost; - - location / { - root /usr/share/nginx/html; - index index.html index.htm; - } - - # redirect server error pages to the static page /40x.html - # - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - # redirect server error pages to the static page /50x.html - # - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - - location ^~ /munin-cgi/munin-cgi-graph/ { - access_log off; - fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*); - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_pass unix:/var/run/munin/fcgi-graph.sock; - include fastcgi_params; - } - - location /munin/static/ { - alias /etc/munin/static/; - } - - location /munin/ { - fastcgi_split_path_info ^(/munin)(.*); - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_pass unix:/var/run/munin/fcgi-html.sock; - include fastcgi_params; - } - -} - diff --git a/sources b/sources index 62d92ae..bc776f3 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -SHA512 (munin-2.0.33.tar.gz) = aa6df8555dfd09585619376a4e9f20c2c6092e70076041ff3dcf987f6eab3caf2880ce32432f71f7b0493808d9e5dbc11e352aa636c39f22ad355409342feb70 +SHA512 (munin-2.0.76.tar.gz) = 37ad31fa8c7585e4a79ce5b62e6ac83c6f12fe0cbb1c28a257f7c71f99c6b05cc837c7557870a28211c253eb85d981a4b17aed2f6028881d5bdef27c01e445a2 +SHA512 (munin-2.0.76.tar.gz.asc) = b34d6c62f73a1bc381e21e95c03e386fe26e1d32eebc396b82fea69326694db3370bdfc8f2cfcaf37d7c9d4bed27f68e17bebd729a5eac8505ddd97bf677241b