#3. Programming Techniques
#3.1. Calling Methods Using REST
REpresentational State Transfer (REST) is a method of marshaling data types and calling functions using HTTP. Zope supports a number of different Remote Procedure Call (RPC) mechanisms, including REST.
This section describes some more advanced Zenoss concepts that we have encountered as the product has rolled out. Some may be appropriate for your environment. Usually they require at least a little coding experience, but they are really not that hard.
#3.1.1. How to Call Methods Using REST
Zenoss' Web interface will let you run any method of any object by using a simple URL. Callas are in the following format:
USERNAME:PASSWORD@MY_ZENOSS_HOST:8080/PATH_TO_OBJECT/METHOD_NAME?ARG=VAL
where:
USERNAME is the user with rights to view this information.
PASSWORD is the user's password.
MY_ZENOSS_HOST is the hostname or IP address of your Zenoss instance
PATH_TO_OBJECT is the full path of the object you want to access
METHOD_NAME is the object's method you want to run
ARG is the method's parameter name
VAL is the method's parameter value
The following example provides the most recent load average of a Linux server:
Note these things about this URL:
/zport/dmd/Devices/Server/Linux/devices/angle is the full path to the object you want to access.
getRRDValue is the method in the Device object you want to run.
dsname is a parameter to the getRRDValue method.
laLoadInt5_laLoadInt5 is the value of dsname, which is the name of the data source we are interested in
Watching the URLs as you browse the Web interface can give you a place to start searching.
#3.1.2. Sending an Event
Events can be sent to Zenoss through the web interface as well as through using zensendevent, but also through a programmatic interface.
#3.1.2.1. Using a REST Call
Sending an event through a rest call can be done by a simple web get. In this example we will use wget to send an event. If you use wget don't for get to escape the "&" or wrap the URL in single quotes.
[zenos@zenoss $] wget 'http://admin:zenoss@MYHOST:8080/zport/dmd/ZenEventManager/manage_addEvent?device=MYDEVICE&component=MYCOMPONENT&summary=MYSUMMARY&severity=4&eventclass=EVENTCLASS'
#3.1.2.2. Using XML-RPC
To send an event to Zenoss using XML-RPC you will first need to create a dictionary (in Perl a hash) that will represent the event. Zenoss will need at a minimum the following fields:
Event fields
- device
the name of the device from which this event originates
- component
the sub-component of the device (for instance eth0, http, etc)
- summary
the text message of the event
- severity
an integer between 0 and 5 with higher numbers being higher severity. Zero is clear.
You can send an event to Zenoss via an interactive session with the Python interpreter as follows:
>>> from xmlrpclib import ServerProxy >>> myurl= 'http://admin:zenoss@MYHOST:8080/zport/dmd/ZenEventManager' >>> serv = ServerProxy( myurl ) >>> evt = {'device':'mydevice', 'component':'eth0', ... 'summary':'eth0 is down','severity':4, 'eventClass':'/Net'} >>> serv.sendEvent(evt)
See below for examples in other languages.
#3.1.2.3. Example Usage in Other Languages
Please note that we are a Python shop and may not be able to answer specific questions about XML-RPC clients written in other languages.
#3.1.2.3.1. Perl
Send an event via Perl using RPC::XML::Client
require RPC::XML; require RPC::XML::Client; $serv = RPC::XML::Client->new('http://YOURZENOSS:8081/'); %evt = ('device' => 'mydevice2', 'component' => 'eth1', 'summary' => 'eth1 is down', 'severity' => 4); $args = RPC::XML::struct->new(%evt); $serv->simple_request('sendEvent', $args);
#3.1.2.3.2. Ruby
This is an example of an Interactive Ruby (IRB) session (the returns have been omitted for the sake of clarity). Note, however, that the Ruby standard library is under active development in general, and specifically, the XML-RPC lib in Ruby is not stable. As of Feb 2007, there is a great deal of on-going discussion regarding XML-RPC in Ruby by Ruby developers and contributors. The following is known to work in previous versions of Ruby:
require "xmlrpc/client" url='user:pass@http://YOURZENOSS:8080/zport/dmd/DeviceLoader') server = XMLRPC::Client.new2( url ) evt = {'device' => 'mydevice3', 'component' => 'eth2', 'summary' => 'eth2 is down', 'severity' => 4} server.call('sendEvent', evt)
#3.1.2.3.3. PHP
<?php include("xmlrpc.inc"); function ifInOutBps($host, $port, $user, $pass, $device, $interface) { $ifInOctets = 'ifInOctets_ifInOctets'; $ifOutOctets = 'ifOutOctets_ifOutOctets'; # base url $url = '/zport/dmd/Devices'; # message $msg = new xmlrpcmsg( $device.'.os.interfaces.'.$interface.'.getRRDValues', array()); $xifInOctets = new xmlrpcVal($ifInOctets); $xifOutOctets = new xmlrpcVal($ifOutOctets); $xifOctets = new xmlrpcVal(array($xifInOctets, $xifOutOctets), 'array'); $msg->addParam($xifOctets); # client $clt = new xmlrpc_client($url, $host, $port); # $clt->setCredentials($user, $pass); # get response $rsp = $clt->send($msg); # any error? if ($rsp->faultCode()) { die('ifInOutBps - Send error: '.$rsp->faultString().' '); } # convert to data structure $dst = xmlrpc_decode($rsp->serialize()); return(array('in'=>$dst[$ifInOctets]*8, 'out'=>$dst[$ifOutOctets]*8)); } ?>
#3.1.2.3.4. Java
This example uses the Apache XML-RPC library and Java 6 to send an event to the Zenoss server.
Required jars
on the classpath (all available from the Apache download):
xmlrpc-client-3.1.jar
ws-commons-util-1.0.2.jar
xmlrpc-common-3.1.jar
import java.net.URL; import java.util.HashMap; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; public class JavaRPCExample { public static void main(String[] args) throws Exception { XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); url= "http://MYHOST:8080/zport/dmd/ZenEventManager" config.setServerURL(new URL(url)); config.setBasicUserName("admin"); config.setBasicPassword("zenoss"); XmlRpcClient client = new XmlRpcClient(); client.setConfig(config); HashMap<String,Object> params = new HashMap<String,Object>(); params.put("device", "mydevice"); params.put("component", "eth0"); params.put("summary", "eth0 is down"); params.put("severity", 4); params.put("eventClass", "/Net"); client.execute("sendEvent", new Object[]{params}); } }
#3.2. Miscellaneous Notes
#3.2.1. pkg_resources
Should one need to use pkg_resources
, it would normally be imported like this:
import pkg_resources
To avoid the mysterious warning
_xmlplus UserWarning
use the following import
line:
import Products.ZenUtils.PkgResources
#3.2.2. urllib2
Workarounds
There is a bug in the standard Python urllib2
library that prevents HTTPS requests through a proxy from working. This affects ZenWebTx and any other Python code that might attempt to make HTTPS calls. Zenoss installs a Python egg named httpsproxy_urllib2-1.0
which provides modified versions of the Python httplib
and urllib2
modules. These replacement modules are used anytime Zenoss code imports httplib
or urllib2
. More information regarding this module is available at PyPi
Directions for configuring your environment to use an HTTP and HTTPS proxy are available in Zenoss Extended Monitoring in the chapter on ZenWebTX.