Your message has been sent.
This article has been saved to your account.
Go to my account
This article has been emailed to your Kindle.
Send this article
Complete the form below to send this article, Zenoss: Creating Custom Reports, to a friend (or to yourself). We will never share your details (or your friend's) with anyone. For more information, read our Privacy Policy.
For system administrators, network engineers, and security analysts, it is essential to keep a track of network traffic. Zenoss Core is an enterprise-level systems and network monitoring solution that can be as complex as you need it to be. While just about anyone can install it, turn it on, and monitor "something", Zenoss Core has a complicated interface packed with features. The interface has been drastically improved over version 2.
In this article by Michael Badger, author of Zenoss Core 3.x Network and System Monitoring, we're going to query the Zenoss Core data model to create custom reports. And we'll do it from the graphical interface provided by the Custom Device Report interface. Our topic includes:
- Custom Device Reports and how to use zendmd to explore the data model
Let's start with a simple custom device report.
| Read more about this book |
(For more resources related to the subject, see here.)
Creating Custom Device Reports
When you view the Reports page in Zenoss Core, you should notice an empty report class called Custom Device Reports. The custom device report provides an interface that lets us query Zenoss Core for devices. Each device that matches the query is listed as a row on the report.
Let's get started with a simple report to show uptime values for all devices, and then we'll talk through the options.
With the Custom Device Reports organizer selected:
- Select Add Custom Device Report from the Add Report button (at the bottom of the Report Classes sidebar.
- In the Create Custom Device Report dialog, type a name for your report in the ID field. I'm going to use Uptime. When you click on Submit, the edit screen is displayed.
- Enter the following values for the Uptime report, as seen in the following screenshot. Leave all other fields set to their default values.
- Title: Uptime
- Sort Column: Name
- Columns: uptimeStr, getId
- To view the report, click the Save button, and then click on the View Report link (in the sidebar).
The following screenshot shows the edit screen of our report:

The next screenshot shows what our report looks like when we view it:
(Move the mouse over the image to enlarge it.)

As you see, we created a simple report that lists each device along with its uptime value. In this report, we use the Column field to do the heavy lifting. We specified the device attributes of uptimeStr and getId, which give us a human readable value of the device's uptime and the name of the device, respectively.
A good place to find device attributes is in Appendix B, Device Attributes which lists common attributes you can use with TALES expressions.
Our report shows columns for Name and Uptime, which are the values we specified in the Column Names field. For each attribute specified in the Columns field, we can define a corresponding friendly Column Name. List the column names in the same sequence as the columns.
Now that we've seen how easy it is to get started with a simple report, we'll preface our more involved examples by reviewing the available report fields.
Custom Device Report fields
The following table shows the available fields on the custom device reports:
|
Field |
Description |
Example |
|
Name |
Descriptive name for the report. The name doesn't display on the report. |
Uptime |
|
Title |
The title displays on the report. |
Uptime Report |
|
Path |
Specify the device class to query. The default is /, which will include all devices. |
/Server/Linux |
|
Query |
Use the query field to filter and select data. Accepts a python or TALES expression.
Leave blank to select all devices. |
here.hw.cpus.countObjects() > 0
here.sysUpTime() > -1 here.comments != "" |
|
Sort Column |
Specify the column that the report is sorted on. Can either be the Column or Column Name value. |
Name
getId |
|
Sort Sense
|
Apply the specific sort order to the value in Sort Column. Can either be ascending or descending. |
asc
desc
|
|
Columns
|
Specify the data to display for each device returned in the query. This can take a device attribute or a python expression. Python expressions must be prefaced with python:. Enter one value per line. |
UptimeStr
python:dev.hw.totalMemoryString()
|
|
Column Names
|
Define the human-friendly names that correspond to each value you entered in Columns.
Enter one value per line. |
Uptime
Total Memory |
There is minimal error checking done on the data you enter. If you enter a query with an invalid syntax, the View Report option will tell you about the error.
If you enter more column names than you specify columns, the interface will turn all the column names red when you save the report.
Let's refine our uptime report a bit more, so we can figure out exactly how we can build meaningful queries.
| Read more about this book |
(For more resources related to the subject, see here.)
Building Custom Device Report queries
Our current version of the uptime report returns the uptime value for each device. Because we didn't specify a query, the report includes all devices and shows us values for devices that aren't reporting an uptime. That's what all the "Unknown" values are on the report.
To improve our report, let's exclude those devices from our report. The query that will exclude devices with an unknown system uptime is:
here.uptimeStr() != "Unknown"
Let's examine the query from left to right. The here portion evaluates the expression on the currently selected device. The custom device reports will retrieve all devices that are included in the specified Path.
The here.uptimeStr() != "Unknown" query returns the system uptime value for the selected device and checks to see if it is not equal to "Unknown". If the statement evaluates to true, then the device is included in the report.
But how do you know which query to use when building a report? To help us build queries, we turn to the interactive shell zendmd.
Using zendmd to test report queries
As the zenoss user, run zendmd. Let's start with a device that we know is reporting uptime. In my test network, that device name is Coyote. We'll run through the command and then we'll talk about what happened.
From zendmd, run the following commands:
d = find("Coyote")
Hopefully, you remembered to use a device on your network. otherwise, your assignment will fail. You can check to see what's assigned to the variable d with the command:
print d
If that command returns the value None, you need to retry your find command using a correct device name. Don't forget to wrap the device name you want to find in quotes.
Now we need to figure out which object holds the uptime value. Zendmd has a built-in auto-complete feature. So, if you type this command, you will see all the available methods that you can run against the device:
d.<tab> <tab> <y>
Pressing the Tab key twice is the way to get zendmd to auto-complete the command. In this scenario, it will ask if you want to display all 605 possibilities. Pressing y for yes will page through the results.
Unless you're bored, you may not want to page through hundreds of pages of possible objects. It's probably more fruitful to guess at the first letter of the object you need. In our uptime report, we use the uptimeStr attribute to display the system uptime value. So, give it a try:
d.u<tab> <tab>
The output is as follows:

This command provides several methods that begin with the letter "u" and uptimeStr is one of the options. Let's finish out the command:
d.uptimeStr()
The result of the command is the uptime value for the device, as seen in the following screenshot:

So far so good, but we're actually looking for the opposite condition. Let's see what an unknown uptime value looks like. In my network, the device Fox is not reporting system uptime, so I can start the process over again:
d = find("Fox")
d.uptimeStr()
This results in an Unknown message, which is what we want to see:

At this point we have what we need to write our query for the custom device report or at least test it out. Edit the uptime report and enter this new value in the Query field: here.uptimeStr() != "Unknown".
Save and view the report. It works. All the devices that have an unknown system uptime value are excluded from the report.
What if we mistype the query and enter this instead: here.uptimeStr != "Unknown". Go ahead and give it a try.
The query brings back all devices, which means it's wrong. If you pop back into zendmd and run d.uptimeStr, you'll notice that you get an entirely different result than we did before. The lesson here is simple. The parentheses matter, so when in doubt, test the output of your functions with and without the parentheses.
Incidentally, this would be an equivalent query to exclude all unknown values: here.sysUpTime() > -1.
The sysUpTime function returns the uptime value in an integer format and -1 is equal to Unknown. The uptimeStr function translates the sysUpTime value to a friendly format. In other words, there may often be more than one way to get your data and a little exploration may lead to enlightenment.
What if you wanted to create a report that listed all devices with a serial number? What would that query look like? Try this:
here.hw.serialNumber != ""
Let's explore this command using auto-complete in zendmd. Type d.hw <tab><tab>. The following screenshot shows the result:

Notice that the there is an open parenthesis after hw. This is our cue in zendmd that we may be able to access other objects, so we replace the opening parenthesis with a dot and type the following command:
d.hw.s <tab><tab>
The output is as follows:

We see that serialNumber is one of our options. The other place we can find useful device data is in the os object, such as this report query:
here.os.filesystems.countObjects() > 0
This query will return all devices with a known file system, as seen in the Components section of the device overview. If we take that knowledge back to zendmd, we can interact with the os object to discover the data that might be available to us:

As the screenshot shows, the countObjects function is available from zendmd.
Are you wondering how we knew to look in the os and hw objects? To answer that question, let's turn back to the Zenoss Core web interface and briefly explore Zope, the framework that drives Zenoss Core.
Summary
This article provided an in-depth look at Zenoss Core's custom device report functionality, including the use of zendmd to explore the Zenoss data model.
Further resources on this subject:
- Installing Zenoss [article]
- Triggers in Zabbix 1.8 [article]
- An Overview of the Tcl Shell [article]
- Squid Proxy Server: Tips and Tricks [article]
- Zenoss Core 3.x: Device Setup and Administration [article]
- Cacti: Using Graphs to Monitor Networks and Devices [article]
About the Author :
Michael Badger
Micheal Badger is a technical communicator with a history of helping others to use their computer software and technology. For fun, Michael reads computer books and blogs about technology. When he finally decides to disconnect, he spends his spare time fishing, growing pigs, raising honeybees, and tending the family.
Michael also wrote Zenoss Core Network and System Monitoring, a step-by-step guide to configuring the open source IT monitoring software application.



Post new comment