Since this is something I think I've bumped into at least eight times in the past decade, I thought I'd document, comprehensively, how I get Munin to monitor Apache and/or Nginx using the apache_*
and nginx_*
Munin plugins that come with Munin itself.
Besides the obvious action of symlinking the plugins into Munin's plugins folder, you should—to avoid any surprises—forcibly configure the env.url
for all Apache and Nginx servers. As an example, in your munin-node configuration (on RedHat/CentOS, in /etc/munin/plugin-conf.d
, add a file named something like apache
or nginx
):
# For Nginx:
[nginx*]
env.url http://localhost/nginx_status
# For Apache:
[apache*]
env.url http://localhost/server-status?auto
Now, something that often trips me up—especially since I maintain a variety of servers and containers, with some running ancient forms of CentOS, while others are running more recent builds of Debian, Fedora, or Ubuntu—is that localhost
doesn't always mean what you'd think it means.
Sometimes curl http://localhost/server-status?auto
will work, but munin-run apache_accesses --debug
will turn up an annoying:
# Environment url = http://localhost/server-status?auto
# About to run '/etc/munin/plugins/apache_accesses'
accesses80.value U
That U
means it's not picking up the value. So the most reliable way to get things working, in my experience, is to explicitly add a 'localhost' server (Nginx) or VirtualHost (Apache), allowing access only from localhost to the respective status endpoint.
So, for Apache, add a virtualhost like:
<VirtualHost *:80>
ServerName localhost
</VirtualHost>
And then also make sure you configure the ExtendedStatus endpoint, like so:
<IfModule mod_status.c>
ExtendedStatus On
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1 localhost ::1 ip6-localhost
</Location>
</IfModule>
On RedHat derivatives, those Apache config files should be placed in /etc/httpd/conf.d/[vhost filename here].conf
and /etc/httpd/conf.modules.d/15-status.conf
, respectively. On Debian derivatives, in /etc/apache2/sites-enabled/[vhost filename here].conf
and /etc/apache2/mods-enabled/status.conf
, respectively.
For Nginx, you just need to add an extra server {}
configuration to your Nginx hosts, like so:
server
{
listen 127.0.0.1;
server_name localhost;
location /nginx_status {
stub_status on; # activate stub_status module
access_log off;
allow 127.0.0.1; # localhost
allow ::1; # localhost
deny all;
}
}
After adding these configs, make sure you restart the webserver (e.g. systemctl restart httpd
(or apache2
), or systemctl restart nginx
).
Test that you can connect using curl first:
# Apache
$ curl http://localhost/server-status?auto
# Nginx
$ curl http://localhost/nginx_status
Then make sure munin-node
will be able to pick up the values as well:
# Apache
$ munin-run apache_accesses --debug
...
# Environment url = http://localhost/server-status?auto
# About to run '/etc/munin/plugins/apache_accesses'
accesses80.value 15
# Nginx
$ munin-run nginx_request --debug
...
# Environment url = http://localhost/nginx_status
# About to run '/etc/munin/plugins/nginx_request'
request.value 2809
To automate much of this setup and configuration process, I use the following Ansible roles:
Comments
Great Article, Thanks for sharing your experience!
How about other ports ?.. It's not picking up with SSL ports
As I understood munin treats it as apache server regardless on how many ports are there. correct me if I'm wrong
And if I have multiple virtual hosts, should I consider the stats for all vhost ?
Thanks in advance