Nagios Plugins

Development Guidelines

Reference guide for Nagios plugin developers to ensure standardization across C, shell, Perl, Python, and other plugin types.

Preface

The purpose of these guidelines is to provide a reference for plugin developers and encourage standardization of different kinds of plugins: C, shell, Perl, Python, etc.

Copyright (C) 2000– Nagios Plugins Team. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Development Platform Requirements

Nagios Plugins are developed to the GNU standard, so any OS supported by GNU should run the plugins. While the requirements for compiling the Nagios Plugins release are basic, developing from the Git repository requires additional software:

  • GNU make 3.79
  • GNU automake 1.9.2
  • GNU autoconf 2.59
  • GNU m4 1.4.2
  • GNU libtool 1.5

To compile from Git, after cloning the repository, run:

cd tools/setup
./configure
make
make install

Plugin Output for Nagios

Always print something to STDOUT that tells if the service is working or why it's failing. Keep output short—ideally less than 80 characters. The entire output should fit in a pager message.

As Nagios does not capture stderr output, you should only output to STDOUT and not print to STDERR.

Verbose Output

Use the -v flag for verbose output. Allow multiple -v options for additional verbosity, up to a maximum of 3:

Verbosity Level Type of Output
0 Single line, minimal output. Summary
1 Single line, additional information (eg list processes that fail)
2 Multi line, configuration debug output (eg ps command used)
3 Lots of detail for plugin problem diagnosis

Plugin Return Codes

Return codes are based on the POSIX spec of returning a positive value:

Numeric Value Service Status Status Description
0 OK The plugin was able to check the service and it appeared to be functioning properly
1 Warning The plugin was able to check the service, but it appeared to be above some "warning" threshold or did not appear to be working properly
2 Critical The plugin detected that either the service was not running or it was above some "critical" threshold
3 Unknown Invalid command line arguments were supplied to the plugin or low-level failures internal to the plugin that prevent it from performing the specified operation

Threshold and Ranges

A range is defined as a start and end point (inclusive) on a numeric scale. A threshold is a range with an alert level (warning or critical).

Generalized format for ranges: [@]start:end

Notes:

  1. start ≤ end
  2. start and ":" is not required if start=0
  3. if range is "start:" and end is not specified, assume end is infinity
  4. to specify negative infinity, use "~"
  5. alert is raised if metric is outside start and end range (inclusive)
  6. if range starts with "@", then alert if inside this range (inclusive)

Example Ranges

Range Definition Generate an Alert if x...
10 < 0 or > 10, (outside the range of {0 .. 10})
10: < 10, (outside {10 .. ∞})
~:10 > 10, (outside the range of {-∞ .. 10})
10:20 < 10 or > 20, (outside the range of {10 .. 20})
@10:20 ≥ 10 and ≤ 20, (inside the range of {10 .. 20})

Command Line Examples

Command Line Meaning
check_stuff -w10 -c20 Critical if "stuff" is over 20, else warn if over 10
check_stuff -w~:10 -c~:20 Same as above. Negative "stuff" is OK
check_stuff -w10: -c20 Critical if "stuff" is over 20, else warn if "stuff" is below 10
check_stuff -c1: Critical if "stuff" is less than 1
check_stuff -c@10:20 OK if stuff is less than 10 or higher than 20, otherwise critical

Performance Data

Nagios 3+ will concatenate the parts following a "|" in the first line output by the plugin into a string it passes to whatever performance data processing it has configured.

Expected format:

'label'=value[UOM];[warn];[crit];[min];[max]

Notes:

  1. Space separated list of label/value pairs
  2. Label can contain any characters except equals sign or single quote (')
  3. Single quotes for the label are optional (required if spaces are in the label)
  4. Label length is arbitrary, but ideally first 19 characters are unique
  5. warn, crit, min or max may be null
  6. min and max are not required if UOM=%
  7. value, min and max in class [-0-9.]. Must all be the same UOM
  8. UOM (unit of measurement): no unit (numbers), s (seconds), % (percentage), B (bytes), c (continuous counter)

System Commands and Auxiliary Files

Don't Execute System Commands Without Full Path

Don't use exec(), popen(), etc. to execute external commands without explicitly using the full path. This makes the plugin vulnerable to hijacking by a trojan horse earlier in the search path.

Use spopen() for External Commands

If you have to execute external commands from within your plugin and you're writing it in C, use the spopen() function. The code for spopen() and spclose() is included with the core plugin distribution.

Avoid Temporary Files

If temp files are needed, ensure the plugin fails cleanly if the file can't be written and delete the temp file when processing is complete.

Don't Follow Symlinks

If your plugin opens any files, take steps to ensure you are not following a symlink to another location on the system.

Validate All Input

Use routines in utils.c or utils.pm and write more as needed.

Perl Plugins

Perl plugins are coded more defensively because of embedded Perl. When configured for embedded Perl Nagios (ePN), stricter use of Perl features is required:

  1. Do not use BEGIN and END blocks—they're called only once when Nagios starts/shuts down
  2. Provide full path to utils.pm:
    use lib "/usr/local/nagios/libexec";
    use utils qw(...);
  3. Perl scripts should be called with "-w"
  4. All Perl plugins must compile cleanly under "use strict"
  5. Explicitly initialize each variable in use
  6. Do not use >DATA< handles
  7. Do not use global variables in named subroutines
  8. Explicitly close files when writing (output streams are never closed as plugin never calls exit)
  9. Monitor runtime using alarm, noting some modules manage timers
  10. Import %ERRORS from utils.pm and use exit $ERRORS{'OK'}

Runtime Timeouts

Plugins have a very limited runtime—typically 10 seconds. It's important for plugins to maintain internal code to exit if runtime exceeds a threshold.

All plugins should timeout gracefully, not just networking plugins. For instance, df may lock if you have auto-mounted drives and your network fails.

Use DEFAULT_SOCKET_TIMEOUT

All network plugins should use DEFAULT_SOCKET_TIMEOUT to timeout.

Add Alarms to Network Plugins

If you write a plugin which communicates with another networked host, set an alarm() in your code that prevents the plugin from hanging due to abnormal socket closures.

Plugin Options

A well written plugin should have --help to get verbose help. Code and output should respect the 80x25 size of a standard terminal.

Option Processing

For C plugins, use the C standard getopt library. For Perl, use Getopt::Long module. Positional arguments are strongly discouraged.

Reserved Options

-V  version (--version)
-h  help (--help)
-t  timeout (--timeout)
-w  warning threshold (--warning)
-c  critical threshold (--critical)
-H  hostname (--hostname)
-v  verbose (--verbose)

Standard Options

-C  SNMP community (--community)
-a  authentication password (--authentication)
-l  login name (--logname)
-p  port or password (--port or --passwd/--password)
-u  url or username (--url or --username)

Multiple Thresholds

For plugins with more than one type of threshold:

  1. Use long options like --critical-time
  2. Use repeated options: check_load -w 10 -w 6 -w 4 -c 16 -c 10 -c 10
  3. Use comma-separated values: check_load -w 10,6,4 -c 16,10,10
  4. Express ranges with colons: check_procs -C httpd -w 1:20 -c 1:30
  5. Express lists with commas: -p 1000,1010,1050:1060,2000

Test Cases

Tests are the best way of knowing if plugins work as expected. Please create and update test cases where possible.

To run tests from the top level directory: make test

Test Cases for Plugins

These use Perl's Test::More. To run a one-time test:

cd plugins && perl t/check_disk.t

For a summary test:

cd plugins && prove t/check_disk.t

Testing C Library Functions

We use the libtap library, which gives Perl's TAP (Test Anything Protocol) output. When you run Nagios Plugins' configure, it will look for the tap library and automatically setup tests.

Coding Guidelines

See GNU Coding Standards for general guidelines.

C Coding

  • Declare variables at the beginning of code blocks for portability
  • Use /* */ for comments, not //
  • Avoid type "bool" and values "true"/"false"—use "int" and "TRUE"/"FALSE"

Crediting Sources

If you've copied a routine from another source, ensure the license allows it. Add a comment referencing the ACKNOWLEDGEMENTS file. For contributed code, add contributors to the THANKS.in file instead of source code.

Commit Messages

If the change is due to a contribution, quote the contributor's name and SourceForge Tracker number if applicable. Update the THANKS.in file and NEWS file for changes useful for noting in the next release.

Translations

For Developers

  1. Check po/nagios-plugins.pot file for similar strings before creating new ones
  2. Break help texts into individual options for reuse between plugins
  3. Avoid line feeds unless working on a block of text
  4. Short help is not translated
  5. Long help has options in English but text translated
  6. Keep "Copyright" in English
  7. Keep copyright holder names in original text
  8. Debugging output doesn't need translation

For Translators

To create an up-to-date list of translatable strings, run:

tools/gen_locale.sh

Submission of New Plugins and Patches

Patches

For bug patches, supply a unified or context diff against your version. For new features, supply a diff against the Git "master" branch.

Submit changes and pull requests via the Nagios-Plugins project on GitHub.

Submission of a patch implies the submitter acknowledges they are the author (or have permission) and agree the code can be released under the GPL. Copyright reverts to the Nagios Plugin Development Team. Credit is given through a THANKS file.

Contributed Plugins

Plugins in the contrib/ directory are not installed by default and not officially supported by the team. These should be owned and maintained by the original contributor, preferably hosted on Nagios Exchange.

New Plugins

To share your plugins with others, add them to Nagios Exchange, the official 3rd party plugin repository.

Minimum requirements for inclusion in official distribution:

  1. Include copyright and license information in all files. Copyright must be solely granted to the Nagios Plugin Development Team
  2. Support standard command options (--help, --version, --timeout, --warning, --critical)
  3. Not redundant with existing plugins
  4. Audited and declared ready by a developer
  5. Follow code format guidelines and use functions from utils
  6. Include patches to configure.in if required

Nagios, the Nagios logo, and Nagios graphics are the servicemarks, trademarks, or registered trademarks owned by Nagios Enterprises. All other servicemarks and trademarks are the property of their respective owner. Copyright © 2009-2018 Nagios Enterprises, LLC.

On This Page