Warning: I do not like Nagios. The fact is I do not like frameworks. They only impose structure, usually too much structure and policies and mostly only that, with very little features. You loose true flexibility, which comes only from Turing-complete programming languages. So you better use libraries and not frameworks. Frameworks are for non-programmers or mediocre programmers. Whenever you need to do something not supported by the framework, you will end up fighting it. No framework designer can foretell all users needs and no framework can be as programmable and generic as a programming language. Anyway, here it is how to setup this monitoring framework, if you really have to. If you are not a programmer you may find it useful. But if you are a programmer and have time, you better use sysstat to collect data and cook up you own monitoring solution.
# yaourt -S nagios nagios-plugins
# htpasswd -c /etc/nagios/htpasswd.users nagiosadmin
# cp /etc/nagios/cgi.cfg.sample /etc/nagios/cgi.cfg
# cp /etc/nagios/resource.cfg.sample /etc/nagios/resource.cfg
# cp /etc/nagios/nagios.cfg.sample /etc/nagios/nagios.cfg
# cp /etc/nagios/objects/commands.cfg.sample /etc/nagios/objects/commands.cfg
# cp /etc/nagios/objects/contacts.cfg.sample /etc/nagios/objects/contacts.cfg
# cp /etc/nagios/objects/localhost.cfg.sample /etc/nagios/objects/localhost.cfg
# cp /etc/nagios/objects/templates.cfg.sample /etc/nagios/objects/templates.cfg
# cp /etc/nagios/objects/timeperiods.cfg.sample /etc/nagios/objects/timeperiods.cfg
# cat >>/etc/httpd/conf/httpd.conf
# cp /etc/webapps/nagios/apache.example.conf /etc/httpd/conf/extra/nagios.conf
# usermod -G nagios -a http
# pacman -Sy apache php-apache gd
# sed -ri '/^(open_basedir = )/ s,$,:/etc/webapps:/usr/share/nagios,' /etc/php/php.ini
Add LoadModule php5_module modules/libphp5.so to /etc/httpd/conf/httpd.conf
# systemctl start httpd
# systemctl status nagios
Go to http://localhost/nagios
login as nagiosadmin
Edit /etc/nagios/objects/contacts.cfg and change 30@localhost with your email address. Log file is /var/nagios/nagios.log
How to create a plugin
I want to create a plugin file named check_something. Any plugin should return the following exit codes:
OK—0—service works properly
WARNING—1—service is in warning state
CRITICAL—exit code 2—service is in critical state
UNKNOWN—exit code 3—service is in unknown state
If an error/exception happens, you better return UNKNOWN, because this is usually the best thing to suggest to nagios in this case. Returning WARNING on error/exception is not appropriate. E.g. if the plugin user chooses to disable notifications for WARNINGS, he will not know that the plugin is actually not working.
Before exiting you should print a line with the format:
SOMETHING OK/WARNING/CRITICAL/UNKNOWN: ...
Standard plugins are installed into /usr/share/nagios/libexec/. You can put yours there too, but I have decided to use a separate directory /usr/local/share/nagios/libexec/ In /etc/nagios/objects/commands.cfg you have to choose a command_name (unique nickname) for your plugin and define the full path of the executable:
This way you register the plugin with nagios. Then to add this check to a host, e.g. localhost, edit file /etc/nagios/objects/localhost.cfg and add there a new definition of a service, e.g.:
service_description My Plugin
Here the value of check_command must match the command_name defined above. A command is just a command: you can even differently named commands that call the same plugin of another command but with different options. Or you can define a command with some parameters. Use the placeholders $ARG1$, $ARG2$, ... in the command_line directive above and check_something!arg1!arg2!... is the syntax to pass parameters.
Plugins can be implemented in any language. For most tasks bash is appropriate, especially if there is no much processing to do, since it makes easy to interface with all unix commands. Here is a template for a Nagios plugin written using bash:
# Plugin description.
## Processing parameter code.
# Define and initialize vars storing parameters
usage: $(basename $0) [-w warnlvl] [-c critlvl] [file]
-w warnlvl description [value1]
-c critlvl description [value2]
file description [value3]
while getopts "h?a:b:c" opt; do
case "$opt" in
# Example check for a numeric parameter
if [[ $OPTARG != *[!0-9]* ]]; then
[ "$1" = "--" ] && shift
# Process $1 as the file name
if [ -z "$1" ]; then
# Gather an integer lvl describing the state of something...
if [ $lvl -gt $critlvl]; then
echo "CHECKNAME CRITICAL: description $lvl > $critlvl"
elif [ $lvl -gt $warnlvl]; then
echo "CHECKNAME WARNING: description $lvl > $warnlvl"
echo "CHECKNAME OK: description $lvl"