BSFMonitor This monitor runs a Bean Scripting Framework BSF-compatible script to determine the status of a service. Users can write scripts to perform highly custom service checks. This monitor is not optimised for scale. It’s intended for a small number of custom checks or prototyping of monitors. BSFMonitor vs SystemExecuteMonitor The BSFMonitor avoids the overhead of fork(2) that is used by the SystemExecuteMonitor. BSFMonitor also grants access to a selection of Horizon internal methods and classes that can be used in the script. Monitor Facts Class Name org.opennms.netmgt.poller.monitors.BSFMonitor Remote Enabled false Configuration and Use Table 1. Monitor specific parameters for the BSFMonitor Parameter Description Required Default value file-name Path to the script file. required - bsf-engine The BSF Engine to run the script in different languages like Bean Shell: bsh.util.BeanShellBSFEngine Groovy: org.codehaus.groovy.bsf.GroovyEngine Jython: org.apache.bsf.engines.jython.JythonEngine required - run-type one of eval or exec optional eval lang-class The BSF language class, like groovy or beanshell. optional file-name extension is interpreted by default file-extensions comma-separated list optional - This monitor implements the Common Configuration Parameters. Table 2. Beans which can be used in the script Variable Type Description map Map<String, Object> The map contains all various parameters passed to the monitor from the service definition it the poller-configuration.xml file. ip_addr String The IP address that is currently being polled. node_id int The Node ID of the node the ip_addr belongs to. node_label String The Node Label of the node the ip_addr and service belongs to. svc_name String The name of the service that is being polled. bsf_monitor BSFMonitor The instance of the BSFMonitor object calling the script. Useful for logging via its log(String sev, String fmt, Object... args) method. results HashMap<String, String> The script is expected to put its results into this object. The status indication should be set into the entry with key status. If the status is not OK, a key reason should contain a description of the problem. times LinkedHashMap<String, Number> The script is expected to put one or more response times into this object. Additionally every parameter added to the service definition in poller-configuration.xml is available as a String object in the script. The key attribute of the parameter represents the name of the String object and the value attribute represents the value of the String object. Please keep in mind, that these parameters are also accessible via the map bean. Avoid non-character names for parameters to avoid problems in the script languages. Response Codes The script has to provide a status code that represents the status of the associated service. The following status codes are defined: Table 3. Status codes Code Description OK Service is available UNK Service status unknown UNR Service is unresponsive NOK Service is unavailable Response time tracking By default the BSFMonitor tracks the whole time the script file consumes as the response time. If the response time should be persisted the response time add the following parameters: RRD response time tracking for this service in poller-configuration.xml <!-- where in the filesystem response times are stored --> <parameter key="rrd-repository" value="/opt/opennms/share/rrd/response" /> <!-- name of the rrd file --> <parameter key="rrd-base-name" value="minimalbshbase" /> <!-- name of the data source in the rrd file --> <!-- by default "response-time" is used as ds-name --> <parameter key="ds-name" value="myResponseTime" /> It is also possible to return one or many response times directly from the script. To add custom response times or override the default one, add entries to the times object. The entries are keyed with a String that names the datasource and have as values a number that represents the response time. To override the default response time datasource add an entry into times named response-time. Timeout and Retry The BSFMonitor does not perform any timeout or retry processing on its own. If retry and or timeout behaviour is required, it has to be implemented in the script itself. Requirements for the script (run-types) Depending on the run-type the script has to provide its results in different ways. For minimal scripts with very simple logic run-type eval is the simple option. Scripts running in eval mode have to return a String matching one of the status codes. If your script is more than a one-liner, run-type exec is essentially required. Scripts running in exec mode need not return anything, but they have to add a status entry with a status code to the results object. Additionally, the results object can also carry a "reason":"message" entry that is used in non OK states. Commonly used language settings The BSF supports many languages, the following table provides the required setup for commonly used languages. Table 4. BSF language setups Language lang-class bsf-engine required library BeanShell beanshell bsh.util.BeanShellBSFEngine supported by default Groovy groovy org.codehaus.groovy.bsf.GroovyEngine groovy-all-[version].jar Jython jython org.apache.bsf.engines.jython.JythonEngine jython-[version].jar Example Bean Shell BeanShell example poller-configuration.xml <service name="MinimalBeanShell" interval="300000" user-defined="true" status="on"> <parameter key="file-name" value="/tmp/MinimalBeanShell.bsh"/> <parameter key="bsf-engine" value="bsh.util.BeanShellBSFEngine"/> </service> <monitor service="MinimalBeanShell" class-name="org.opennms.netmgt.poller.monitors.BSFMonitor" /> BeanShell example MinimalBeanShell.bsh script file bsf_monitor.log("ERROR", "Starting MinimalBeanShell.bsf", null); File testFile = new File("/tmp/TestFile"); if (testFile.exists()) { return "OK"; } else { results.put("reason", "file does not exist"); return "NOK"; } Example Groovy To use the Groovy language an additional library is required. Copy a compatible groovy-all.jar into to opennms/lib folder and restart Horizon. That makes Groovy available for the BSFMonitor. Groovy example poller-configuration.xml with default run-type set to eval <service name="MinimalGroovy" interval="300000" user-defined="true" status="on"> <parameter key="file-name" value="/tmp/MinimalGroovy.groovy"/> <parameter key="bsf-engine" value="org.codehaus.groovy.bsf.GroovyEngine"/> </service> <monitor service="MinimalGroovy" class-name="org.opennms.netmgt.poller.monitors.BSFMonitor" /> Groovy example MinimalGroovy.groovy script file for run-type eval bsf_monitor.log("ERROR", "Starting MinimalGroovy.groovy", null); File testFile = new File("/tmp/TestFile"); if (testFile.exists()) { return "OK"; } else { results.put("reason", "file does not exist"); return "NOK"; } Groovy example poller-configuration.xml with run-type set to exec <service name="MinimalGroovy" interval="300000" user-defined="true" status="on"> <parameter key="file-name" value="/tmp/MinimalGroovy.groovy"/> <parameter key="bsf-engine" value="org.codehaus.groovy.bsf.GroovyEngine"/> <parameter key="run-type" value="exec"/> </service> <monitor service="MinimalGroovy" class-name="org.opennms.netmgt.poller.monitors.BSFMonitor" /> Groovy example MinimalGroovy.groovy script file for run-type set to exec bsf_monitor.log("ERROR", "Starting MinimalGroovy", null); def testFile = new File("/tmp/TestFile"); if (testFile.exists()) { results.put("status", "OK") } else { results.put("reason", "file does not exist"); results.put("status", "NOK"); } Example Jython To use the Jython (Java implementation of Python) language an additional library is required. Copy a compatible jython-x.y.z.jar into the opennms/lib folder and restart Horizon. That makes Jython available for the BSFMonitor. Jython example poller-configuration.xml with run-type exec <service name="MinimalJython" interval="300000" user-defined="true" status="on"> <parameter key="file-name" value="/tmp/MinimalJython.py"/> <parameter key="bsf-engine" value="org.apache.bsf.engines.jython.JythonEngine"/> <parameter key="run-type" value="exec"/> </service> <monitor service="MinimalJython" class-name="org.opennms.netmgt.poller.monitors.BSFMonitor" /> Jython example MinimalJython.py script file for run-type set to exec from java.io import File bsf_monitor.log("ERROR", "Starting MinimalJython.py", None); if (File("/tmp/TestFile").exists()): results.put("status", "OK") else: results.put("reason", "file does not exist") results.put("status", "NOK") We have to use run-type exec here because Jython chokes on the import keyword in eval mode. As proof that this is really Python, notice the substitution of Python’s None value for Java’s null in the log call. Advanced examples The following example references all beans that are exposed to the script, including a custom parameter. Groovy example poller-configuration.xml <service name="MinimalGroovy" interval="30000" user-defined="true" status="on"> <parameter key="file-name" value="/tmp/MinimalGroovy.groovy"/> <parameter key="bsf-engine" value="org.codehaus.groovy.bsf.GroovyEngine"/> <!-- custom parameters (passed to the script) --> <parameter key="myParameter" value="Hello Groovy" /> <!-- optional for response time tracking --> <parameter key="rrd-repository" value="/opt/opennms/share/rrd/response" /> <parameter key="rrd-base-name" value="minimalgroovybase" /> <parameter key="ds-name" value="minimalgroovyds" /> </service> <monitor service="MinimalGroovy" class-name="org.opennms.netmgt.poller.monitors.BSFMonitor" /> Groovy example Bean referencing script file bsf_monitor.log("ERROR", "Starting MinimalGroovy", null); //list of all available objects from the BSFMonitor Map<String, Object> map = map; bsf_monitor.log("ERROR", "---- map ----", null); bsf_monitor.log("ERROR", map.toString(), null); String ip_addr = ip_addr; bsf_monitor.log("ERROR", "---- ip_addr ----", null); bsf_monitor.log("ERROR", ip_addr, null); int node_id = node_id; bsf_monitor.log("ERROR", "---- node_id ----", null); bsf_monitor.log("ERROR", node_id.toString(), null); String node_label = node_label; bsf_monitor.log("ERROR", "---- node_label ----", null); bsf_monitor.log("ERROR", node_label, null); String svc_name = svc_name; bsf_monitor.log("ERROR", "---- svc_name ----", null); bsf_monitor.log("ERROR", svc_name, null); org.opennms.netmgt.poller.monitors.BSFMonitor bsf_monitor = bsf_monitor; bsf_monitor.log("ERROR", "---- bsf_monitor ----", null); bsf_monitor.log("ERROR", bsf_monitor.toString(), null); HashMap<String, String> results = results; bsf_monitor.log("ERROR", "---- results ----", null); bsf_monitor.log("ERROR", results.toString(), null); LinkedHashMap<String, Number> times = times; bsf_monitor.log("ERROR", "---- times ----", null); bsf_monitor.log("ERROR", times.toString(), null); // reading a parameter from the service definition String myParameter = myParameter; bsf_monitor.log("ERROR", "---- myParameter ----", null); bsf_monitor.log("ERROR", myParameter, null); // minimal example def testFile = new File("/tmp/TestFile"); if (testFile.exists()) { bsf_monitor.log("ERROR", "Done MinimalGroovy ---- OK ----", null); return "OK"; } else { results.put("reason", "file does not exist"); bsf_monitor.log("ERROR", "Done MinimalGroovy ---- NOK ----", null); return "NOK"; } BgpSessionMonitor CiscoIpSlaMonitor