Zenoss: Creating Custom Reports

May 2011


Zenoss Core 3.x Network and System Monitoring

Zenoss Core 3.x Network and System Monitoring

Implement Zenoss core and fit it into your security management environment using this easy-to-understand tutorial guide.

        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:

  1. Select Add Custom Device Report from the Add Report button (at the bottom of the Report Classes sidebar.
  2. 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.
  3. 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:

Zenoss: Creating Custom Reports

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:





Descriptive name for the report. The name doesn't display on the report.



The title displays on the report.

Uptime Report


Specify the device class to query. The default is /, which will include all devices.



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.




Sort Sense


Apply the specific sort order to the value in Sort Column. Can either be ascending or descending.







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.





Column Names


Define the human-friendly names that correspond to each value you entered in Columns.


Enter one value per line.



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:

Zenoss: Creating Custom Reports

This command provides several methods that begin with the letter "u" and uptimeStr is one of the options. Let's finish out the command:


The result of the command is the uptime value for the device, as seen in the following screenshot:

Zenoss: Creating Custom Reports

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")

This results in an Unknown message, which is what we want to see:

Zenoss: Creating Custom Reports

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:

Zenoss: Creating Custom Reports

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:

Zenoss: Creating Custom Reports

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:

Zenoss: Creating Custom Reports

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.


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:

You've been reading an excerpt of:

Zenoss Core 3.x Network and System Monitoring

Explore Title