Munin is a networked resource monitoring tool that can help analyze resource trends and “what just happened to hurt our performance?” problems. It uses a master/node architecture where the master polls nodes for data and generates RRD graphs.
| File/Directory | Path | Purpose |
|---|---|---|
| Master config | /etc/munin/munin.conf |
Main Munin master configuration |
| Node config | /etc/munin/munin-node.conf |
Munin node agent configuration |
| Plugin config dir | /etc/munin/plugins/ |
Plugin-specific configurations |
| Plugin contrib | /usr/share/munin/plugins/ |
Available plugins |
| Plugin enabled | /etc/munin/plugins/ |
Symlinked active plugins |
| RRD data | /var/lib/munin/ |
RRD database files |
| HTML output | /var/cache/munin/www/ |
Generated graphs and HTML |
| Log files | /var/log/munin/ |
Munin log files |
| Cron jobs | /etc/cron.d/munin |
Scheduled tasks |
| CGI scripts | /usr/lib/munin/cgi/ |
Dynamic graph generation |
# /etc/munin/munin.conf
###############################################################################
# GLOBAL SETTINGS
###############################################################################
# Location of RRD files
dbdir /var/lib/munin
# Location of generated HTML and graphs
htmldir /var/cache/munin/www
# Location of CGI scripts for dynamic graphing
cgidir /usr/lib/munin/cgi
# Log file location
logdir /var/log/munin
# Run directory for PID files
rundir /var/run/munin
# User for cron jobs
muninuser munin
# Language for graphs (default: en)
language en
# Graph size (small, medium, large)
graph_size medium
# Graph arguments
graph_args --base 1000 -l 0
# Graph scale (linear, log)
graph_scale no
# Image format (png, svg)
image_format png
# Enable HTML zoom feature
html_zoom yes
# Enable dynamic graphing via CGI
cgiurl_graph /cgi-bin/munin-cgi-graph
# CGI URL for overview
cgiurl_overview /cgi-bin/munin-cgi-overview
# Number of days to keep data
retention_days 365
###############################################################################
# EMAIL ALERTS
###############################################################################
# Contact email for alerts
contacts admin
contact admin
command mail -s "Munin notification ${var:host}" admin@example.com
sender munin@example.com
always_send yes
textmail yes
# Additional contact
contact ops-team
command mail -s "Munin alert ${var:host}" ops-team@example.com
sender munin@example.com
# Only send on critical alerts
warning no
critical yes
###############################################################################
# NODE DEFINITIONS
###############################################################################
# Local node (Munin server itself)
[munin-server.example.com]
address 127.0.0.1
use_node_name yes
group local
# Remote nodes
[webserver01.example.com]
address 192.168.1.10
use_node_name yes
group webservers
[webserver02.example.com]
address 192.168.1.11
use_node_name yes
group webservers
[dbserver01.example.com]
address 192.168.1.20
use_node_name yes
group databases
[dbserver02.example.com]
address 192.168.1.21
use_node_name yes
group databases
[mailserver01.example.com]
address 192.168.1.30
use_node_name yes
group mailservers
# Node with custom port
[custom-node.example.com]
address 192.168.1.40
port 2449
use_node_name yes
group custom
# Node with SSH tunnel (for secure monitoring)
[secure-node.example.com]
address 127.0.0.1
port 2450
use_node_name yes
group secure
# SSH tunnel: ssh -L 2450:secure-node:2449 user@munin-server
###############################################################################
# TREE STRUCTURE
###############################################################################
# Define tree structure for navigation
tree structure
title Munin Monitoring
[local]
title Local Servers
[webservers]
title Web Servers
[databases]
title Database Servers
[mailservers]
title Mail Servers
[custom]
title Custom Services
[secure]
title Secure Nodes
###############################################################################
# PLUGIN DEFAULTS AND OVERRIDES
###############################################################################
# Default update interval (seconds)
update_rate 300
# Timeout for plugin execution (seconds)
timeout 60
# Plugin-specific configuration
[webserver01.example.com]
# Override plugin settings
update_rate 60 # More frequent updates for web servers
# Enable specific plugins
apache_accesses.warning 1000
apache_accesses.critical 5000
[dbserver01.example.com]
# MySQL-specific thresholds
mysql_queries.warning 1000
mysql_queries.critical 5000
mysql_slowqueries.warning 10
mysql_slowqueries.critical 50
###############################################################################
# INCLUDE FILES
###############################################################################
# Include additional configuration files
include /etc/munin/munin-conf.d/*.conf
# /etc/munin/munin-node.conf
###############################################################################
# NETWORK SETTINGS
###############################################################################
# Hostname of this node
host_name munin-node.example.com
# Address to bind to (0.0.0.0 for all interfaces)
host *
# Port to listen on
port 2449
# Address allowed to connect (CIDR notation)
allow ^127\.0\.0\.1$
allow ^192\.168\.1\.[0-9]+$
allow ^10\.0\.0\.[0-9]+$
# SSL/TLS configuration
ssl 1
ssl_cert_file /etc/munin/ssl/munin-node.crt
ssl_key_file /etc/munin/ssl/munin-node.key
ssl_ca_cert_file /etc/munin/ssl/ca.crt
###############################################################################
# LOGGING
###############################################################################
# Log file location
log_file /var/log/munin/munin-node.log
# Log level (error, warning, info, debug)
log_level info
###############################################################################
# PLUGIN SETTINGS
###############################################################################
# Plugin directory
plugin_dir /usr/share/munin/plugins
# Plugin configuration directory
plugin_conf_dir /etc/munin/plugins
# Timeout for plugin execution (seconds)
timeout 60
# Paranoia mode (security)
paranoia_mode true
# User for running plugins
user munin
# Group for running plugins
group munin
###############################################################################
# CAPABILITIES
###############################################################################
# Allow node to report its capabilities
capabilities
###############################################################################
# CUSTOM PLUGIN CONFIGURATION
###############################################################################
# Environment variables for plugins
env.mysqluser monitoring
env.mysqlpass SecurePassword123!
env.mysqlhost localhost
# Override plugin behavior
[mysql_*]
env.mysqluser root
env.mysqlpass RootPassword123!
[apache_*]
env.logpath /var/log/apache2
[nginx_*]
env.logpath /var/log/nginx
###############################################################################
# RATE LIMITING
###############################################################################
# Maximum connections per minute
max_connections 10
# Connection rate limiting
rate_limit 60
# /etc/munin/plugins/mysql_connections
# MySQL connection monitoring plugin configuration
[mysql_connections]
env.mysqluser monitoring
env.mysqlpass SecurePassword123!
env.mysqlhost localhost
env.mysqlport 3306
warning 80
critical 95
# /etc/munin/plugins/disk_usage
# Disk usage plugin configuration
[disk_usage]
env.warning 80
env.critical 90
# Specific mount points
env.mounts / /var /home /data
# /etc/munin/plugins/cpu_usage
# CPU usage plugin configuration
[cpu_usage]
env.warning 80
env.critical 95
# Track specific CPU cores
env.cores all
#!/bin/bash
# /usr/share/munin/plugins/custom_app_status
# Custom application status plugin
case "$1" in
config)
echo 'graph_title Application Status'
echo 'graph_category custom'
echo 'graph_info This graph shows the status of our custom application'
echo 'graph_vlabel status'
echo 'graph_scale no'
echo 'graph_args --base 1000 -l 0'
echo 'app_status.label Application Status'
echo 'app_status.info Current application status (1=running, 0=stopped)'
echo 'app_status.draw LINE2'
echo 'app_status.colour COLOUR1'
echo 'response_time.label Response Time (ms)'
echo 'response_time.info Application response time in milliseconds'
echo 'response_time.draw LINE2'
echo 'response_time.colour COLOUR2'
exit 0;;
esac
# Get application status
if pgrep -x "myapp" > /dev/null; then
APP_STATUS=1
else
APP_STATUS=0
fi
# Get response time (example)
RESPONSE_TIME=$(curl -s -o /dev/null -w "%{time_total}" http://localhost:8080/health 2>/dev/null | awk '{print int($1 * 1000)}')
RESPONSE_TIME=${RESPONSE_TIME:-0}
echo "app_status.value $APP_STATUS"
echo "response_time.value $RESPONSE_TIME"
# Enable plugins by creating symlinks
cd /etc/munin/plugins/
# Enable standard plugins
ln -s /usr/share/munin/plugins/if_eth0 if_eth0
ln -s /usr/share/munin/plugins/cpu cpu
ln -s /usr/share/munin/plugins/load load
ln -s /usr/share/munin/plugins/memory memory
ln -s /usr/share/munin/plugins/df df
ln -s /usr/share/munin/plugins/uptime uptime
ln -s /usr/share/munin/plugins/users users
ln -s /usr/share/munin/plugins/openssh openssh
ln -s /usr/share/munin/plugins/mysql mysql_
ln -s /usr/share/munin/plugins/apache_accesses apache_accesses
ln -s /usr/share/munin/plugins/nginx_request nginx_request
# Enable custom plugin
ln -s /usr/share/munin/plugins/custom_app_status custom_app_status
# Verify plugins
munin-node-configure --shell --remove-also 2>/dev/null | sh
# /etc/munin/munin-conf.d/webservers.conf
[webserver01.example.com]
address 192.168.1.10
use_node_name yes
group webservers
# Apache monitoring
apache_accesses.warning 1000
apache_accesses.critical 5000
# Nginx monitoring
nginx_request.warning 500
nginx_request.critical 2000
# PHP-FPM monitoring
php_fpm_processes.warning 80
php_fpm_processes.critical 95
[webserver02.example.com]
address 192.168.1.11
use_node_name yes
group webservers
# /etc/munin/munin-conf.d/databases.conf
[dbserver01.example.com]
address 192.168.1.20
use_node_name yes
group databases
# MySQL monitoring
mysql_queries.warning 1000
mysql_queries.critical 5000
mysql_slowqueries.warning 10
mysql_slowqueries.critical 50
mysql_threads.warning 100
mysql_threads.critical 200
mysql_innodb_buffer_pool.warning 80
mysql_innodb_buffer_pool.critical 95
# PostgreSQL monitoring (if applicable)
postgresql_connections.warning 80
postgresql_connections.critical 95
[dbserver02.example.com]
address 192.168.1.21
use_node_name yes
group databases
# /etc/munin/munin-conf.d/mailserver.conf
[mailserver01.example.com]
address 192.168.1.30
use_node_name yes
group mailservers
# Postfix monitoring
postfix_mailvolume.warning 1000
postfix_mailvolume.critical 5000
postfix_mailqueue.warning 100
postfix_mailqueue.critical 500
# Dovecot monitoring
dovecot_connections.warning 500
dovecot_connections.critical 1000
# /etc/munin/munin.conf
# Define contacts
contacts admin ops-team
contact admin
command mail -s "Munin alert: ${var:host} - ${var:graph_title}" admin@example.com
sender munin@example.com
always_send yes
textmail yes
htmlmail no
contact ops-team
command mail -s "Munin critical: ${var:host}" ops-team@example.com
sender munin@example.com
warning no
critical yes
textmail yes
# Define alert conditions for specific graphs
[webserver01.example.com]
apache_accesses.contact admin
apache_accesses.warning 1000
apache_accesses.critical 5000
#!/bin/bash
# /usr/local/bin/munin-slack-alert.sh
WEBHOOK_URL="https://hooks.slack.com/services/XXX/YYY/ZZZ"
CHANNEL="#monitoring-alerts"
# Parse Munin environment variables
HOST="${var:host}"
GRAPH="${var:graph_title}"
SERVICE="${var:service}"
WARNING="${var:warning}"
CRITICAL="${var:critical}"
VALUE="${var:value}"
# Determine severity
if [ -n "$CRITICAL" ]; then
COLOR="danger"
SEVERITY="CRITICAL"
else
COLOR="warning"
SEVERITY="WARNING"
fi
# Create payload
PAYLOAD=$(cat <<EOF
{
"channel": "$CHANNEL",
"username": "Munin",
"icon_emoji": ":chart_with_upwards_trend:",
"attachments": [
{
"color": "$COLOR",
"title": "Munin Alert: $SEVERITY",
"fields": [
{"title": "Host", "value": "$HOST", "short": true},
{"title": "Graph", "value": "$GRAPH", "short": true},
{"title": "Service", "value": "$SERVICE", "short": true},
{"title": "Value", "value": "$VALUE", "short": true},
{"title": "Warning Threshold", "value": "$WARNING", "short": true},
{"title": "Critical Threshold", "value": "$CRITICAL", "short": true}
]
}
]
}
EOF
)
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$WEBHOOK_URL"
# Test Munin master configuration
sudo munin-check
# Test node configuration
sudo munin-node-configure --suggest
# Check plugin availability
munin-node-configure --shell --remove-also 2>/dev/null
# Validate plugin execution
sudo -u munin /usr/share/munin/plugins/cpu
# Check RRD directory permissions
ls -la /var/lib/munin/
# Restart Munin master
sudo systemctl restart munin
# Restart Munin node
sudo systemctl restart munin-node
# Check service status
sudo systemctl status munin
sudo systemctl status munin-node
# View logs
sudo tail -f /var/log/munin/munin-update.log
sudo tail -f /var/log/munin/munin-node.log
sudo tail -f /var/log/munin/munin-cgi-html.log
# Force graph update
sudo munin-update
# Run with verbose output
sudo munin-update --debug
# Generate HTML
sudo munin-html
# Generate graphs via CGI
sudo munin-cgi-graph
# Check cron job
sudo cat /etc/cron.d/munin
# Test node connection from master
telnet 192.168.1.10 2449
# Or use nc
nc -v 192.168.1.10 2449
# Test plugin listing
echo "list" | nc 192.168.1.10 2449
# Test specific plugin
echo "fetch cpu" | nc 192.168.1.10 2449
# List available plugins
munin-node-configure --suggest
# Test plugin execution
sudo -u munin /usr/share/munin/plugins/cpu
# Check plugin output format
munin-run cpu
# Debug plugin
munin-debug cpu
# Check RRD files
ls -la /var/lib/munin/
# Check generated HTML
ls -la /var/cache/munin/www/
# View latest graph
ls -lt /var/cache/munin/www/static/
# Test CGI
curl http://localhost/cgi-bin/munin-cgi-graph
# Master update log
tail -f /var/log/munin/munin-update.log
# Node log
tail -f /var/log/munin/munin-node.log
# CGI log
tail -f /var/log/munin/munin-cgi-html.log
# Search for errors
grep -i error /var/log/munin/*.log
Running Munin in regulated environments? We assist with:
Secure your deployment: office@linux-server-admin.com | Contact Page