As of version 2.0 you have the ability to embed JNRPE inside your own application. It's a very simple operation that will allow you to expose your application so that Nagios can query such data through check_nrpe commands.
The easiest way to compile an application using jnrpe-lib is through the use of maven.
If you don't want to use maven, you have to manually download the dependencies.
Create the following directory structure:
+- src/ +- main/ +- java/ +- pom.xml
and put your sources under the 'java' directory.
Create a file called pom.xml in the same directory as 'src'. This are the jnrpe-lib data:
Create the pom.xml file according to the maven documentation.
run
mvn package
If you don't use maven, than you will have to download jnrpe-lib and all its dependecies manually.
You can download jnrpe-lib and its dependencies (deps.tar.gz) here
Through the tutorial we will refer to a very simple application that computes two random number between 1 and 100. Next we will add the ability to check through Nagios the number values and return a warning or critical if the random number falls inside a given range../check_nrpe -n -H 127.0.0.1 -c runTest -a 'random1!33:66!67:'
Follows the example application:
public class Example { private int m_iRandom1 = 0; private int m_iRandom2 = 0; private Random m_random = new Random(); /** * This method updates the variables with the next random number */ public void updateVariables() { m_iRandom1 = m_random.nextInt(100); // We want to values to be between 0 and 100 m_iRandom2 = m_random.nextInt(100); } /** * The main method */ public static void main(String[] args) throws Exception { Example example = new Example(); example.updateVariables(); // Change variable values every 5 seconds while(true) { Thread.sleep(5000); example.updateVariables(); } } }
As first step we must create a JNRPE plugin that is able to monitor our object. Every JNRPE plugin must implement the IPluginInterface interface:
public class ExamplePlugin implements IPluginInterface { private final Example m_instanceToCheck; public ExamplePlugin(Example ex) { m_instanceToCheck = ex; } @Override public ReturnValue execute(ICommandLine cl) { String sVariable = cl.getOptionValue("get"); // (1) if (sVariable.equalsIgnoreCase("random1")) return new ReturnValue("RANDOM1: " + m_instanceToCheck.getRandom1()); // (2) if (sVariable.equalsIgnoreCase("random2")) return new ReturnValue("RANDOM2: " + m_instanceToCheck.getRandom2()); return new ReturnValue(IJNRPEConstants.STATE_UNKNOWN, sVariable + " is unknown"); } }
This first version of the plugin always returns an OK state and, as text, the variable name and it's value.
The code line identified by (1) means that we want the value of the 'get' option: that means that the plugin must be able to receive an option named 'get' and that that option must accept an argument (the value).
This is very important because we must describe all the option our plugin is able to support to JNRPE.
The line identified by (2) is very simple: simply returns an OK return value.
To describe the plugin to JNRPE we have to instantiate a PluginDefinition object:
IPluginInterface tp = new ExamplePlugin(example); PluginDefinition pluginDef = new PluginDefinition("TestPlugin", "Simple Test Plugin description", tp) // PluginName : TestPlugin, // (1) .addOption(new PluginOption() // (2) .setOption("g") // The plugin accept the short form parameter 'g' // (3) .setLongOpt("get") // The long form parameter // (4) .setArgName("variable") // The paramater has an argument called 'variable' // (5) .setArgsOptional(false) // The parameter argument is mandatory // (6) .setRequired(true) // The parameter is mandatory // (7) );
Lets analyze the code:
Now that we have created the plugin, we have to register it inside the JNRPE plugin repository.
PluginRepository pluginRepository = new PluginRepository(); // Creates the repository pluginRepository.addPluginDefinition(pluginDef); // Adds our plugin to the repository
Ok: the plugin is ready and JNRPE is aware of its existence. Since a plugin can be used to execute different tasks, now we have to say to JNRPE how to use the plugin. We will accomplish that creating a 'command' based on this plugin.
As with plugins, all commands are described through a 'command definition' object. In the following example we will define a command based on the 'TestPlugin' that will pass the 'get' parameter with the argument received by check_nrpe.
CommandDefinition commandDef = new CommandDefinition("runTest", "TestPlugin") // CommandName : runTest, plugin : TestPlugin .addArgument( new CommandOption("get", "$ARG1$")); // The command will take a parameter called get that asks for an argument // The argument will the argument received from check_nrpe
Again, as with plugins, now we have to register the command inside the command repository:
CommandRepository commandRepository = new CommandRepository(); // Creates the command repository commandRepository.addCommandDefinition(commandDef); // register the command inside the repository
We are almost done: now we have to instantiate JNRPE and start listening for requests.
JNRPE engine = new JNRPE(pluginRepository, commandRepository); // JNRPE must know both plugin and command repository engine.addAcceptedHost("127.0.0.1"); // Will accept requests from localhost engine.listen("127.0.0.1", 5666); // Will listen on 127.0.0.1 on port 5666
Follows the whole main method.
public static void main(String[] args) throws InterruptedException { Example example = new Example(); example.updateVariables(); // Instantiate the plugin IPluginInterface tp = new ExamplePlugin(example); // Describe the plugin PluginDefinition pluginDef = new PluginDefinition("TestPlugin", "Simple Test Plugin description", tp) // PluginName : TestPlugin, .addOption(new PluginOption() .setOption("g") // The plugin accept the short form parameter 'g' .setLongOpt("get") // The long form parameter .setArgName("variable") // The paramater has an argument called 'variable' .setArgsOptional(false) // The parameter argument is mandatory .setRequired(true) // The parameter is mandatory ); PluginRepository pluginRepository = new PluginRepository(); // Creates the repository pluginRepository.addPluginDefinition(pluginDef); // Adds our plugin to the repository // Describes the command CommandDefinition commandDef = new CommandDefinition("runTest", "TestPlugin") // CommandName : runTest, plugin : TestPlugin .addArgument(new CommandOption("get", "$ARG1$")); // The command will take a parameter called get that asks for an argument // The argument will be replaced with what will be received by check_nrpe CommandRepository commandRepository = new CommandRepository(); // Creates the command repository commandRepository.addCommandDefinition(commandDef); // register the command inside the repository JNRPE engine = new JNRPE(pluginRepository, commandRepository); // JNRPE must know both plugin and command repository engine.addAcceptedHost("127.0.0.1"); // Will accept requests from localhost engine.listen("127.0.0.1", 5666); // Will listen on 127.0.0.1 on port 5666 // This is just to update the variable values of the example and is // not mandatory at all while(true) { Thread.sleep(5000); example.updateVariables(); } }
Run the java application, than try the following command:
check_nrpe -n -H 127.0.0.1 -c runTest -a 'random1'
You just executed your first JNRPE embedded plugin!
The plugin we've created in the previous paragraph always returns OK. In this chapter we will change it so that it will be able to return WARNING or CRITICAL depending on the value of the random variables.
To perform such checks, we will add a '-w|--warning' and a '-c|--critical' parameter to our plugin. Both the -w and -c parameter will have an argument describing the waning/critical thresholds.
Checking thresholds is very easy through the use of the ThresholdUtil class.
Here is the changed plugin class.
public class ExamplePlugin implements IPluginInterface { private final Example m_instanceToCheck; public ExamplePlugin(Example ex) { m_instanceToCheck = ex; } @Override public ReturnValue execute(ICommandLine cl) { String sVariable = cl.getOptionValue("get"); int iValue; if (sVariable.equalsIgnoreCase("random1")) iValue = m_instanceToCheck.getRandom1(); else if (sVariable.equalsIgnoreCase("random2")) iValue = m_instanceToCheck.getRandom2(); else return new ReturnValue(IJNRPEConstants.STATE_UNKNOWN, sVariable + " is unknown"); String sCriticalThreshold = cl.getOptionValue("critical"); String sWarningThreshold = cl.getOptionValue("warning"); if (ThresholdUtil.isValueInRange(sCriticalThreshold, iValue)) return new ReturnValue("CRITICAL - " + sVariable + " : " + iValue); if (ThresholdUtil.isValueInRange(sWarningThreshold, iValue)) return new ReturnValue("WARNING - " + sVariable + " : " +iValue); return new ReturnValue("OK - " + sVariable + " : " +iValue); } }
Now that we have changed the plugin class, we have to change the plugin definition too:
PluginDefinition pluginDef = new PluginDefinition("TestPlugin", "Simple Test Plugin", tp) .addOption(new PluginOption() .setOption("g") .setLongOpt("get") .setArgName("variable") .setArgsOptional(false) .setRequired(true)) .addOption(new PluginOption() .setOption("w") .setLongOpt("warning") .setArgName("value") .setArgsOptional(false) .setRequired(false)) .addOption(new PluginOption() .setOption("c") .setLongOpt("critical") .setArgName("value") .setArgsOptional(false) .setRequired(false) );
Finally, we have to change the command definition
CommandDefinition commandDef = new CommandDefinition("runTest", "TestPlugin") .addArgument(new CommandOption("get", "$ARG1$")) .addArgument(new CommandOption("warning", "$ARG2$")) .addArgument(new CommandOption("critical", "$ARG3$") );
Now we can invoke the plugin through the command:
./check_nrpe -n -H 127.0.0.1 -c runTest -a 'random1!33:66!67:'