Zenoss Developer's Guide Developers 08 102010 3.0 V01
Zenoss_Developers_Guide_08-102010-3.0-v01
Zenoss_Developers_Guide_08-102010-3.0-v01
User Manual:
Open the PDF directly: View PDF .
Page Count: 146
Zenoss Developer's Guide
Copyright © 2010 Zenoss, Inc., 275 West St. Suite 204, Annapolis, MD 21401, U.S.A. All rights reserved.
This work is licensed under a Creative Commons Attribution Share Alike 3.0 License. To view a copy of this license, visit http://
creativecommons.org/licenses/by-sa/3.0/; or send a letter to Creative Commons, 171 2nd Street, Suite 300, San Francisco, California, 94105,
USA.
The Zenoss logo is a registered trademark of Zenoss, Inc. Zenoss and Open Enterprise Management are trademarks of Zenoss, Inc. in the
U.S. and other countries.
Flash is a registered trademark of Adobe Systems Incorporated.
Java is a registered trademark of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Linux is a registered trademark of Linus Torvalds.
Oracle and the Oracle logo are registered trademarks of the Oracle Corporation.
SNMP Informant is a trademark of Garth K. Williams (Informant Systems, Inc.).
Sybase is a registered trademark of Sybase, Inc.
Tomcat is a trademark of the Apache Software Foundation.
Windows is a registered trademark of Microsoft Corporation in the United States and other countries.
All other companies and products mentioned are trademarks and property of their respective owners.
Part Number: 08-102010-3.0-v01
1. Introduction ............................................................................................................................................. 1
1.1. Overview ...................................................................................................................................... 1
1.1.1. Key Tenets ........................................................................................................................ 1
1.2. Architecture and Technologies ....................................................................................................... 2
1.2.1. User Layer ......................................................................................................................... 3
1.2.2. Data Layer ......................................................................................................................... 3
1.2.3. Process Layer .................................................................................................................... 4
1.2.4. Collection Layer ................................................................................................................. 4
2. Getting Started ........................................................................................................................................ 5
2.1. Working with the Source Code ...................................................................................................... 5
2.1.1. Getting the Source Code .................................................................................................... 5
2.1.1.1. Getting Subversion for the Appliance ........................................................................ 5
2.1.2. Keeping Code Updated ...................................................................................................... 6
2.1.3. Getting Patches ................................................................................................................. 6
2.1.4. Style Guidelines ................................................................................................................. 6
2.1.4.1. Docstrings ............................................................................................................... 6
2.1.5. Generating Diffs for new Fixes ............................................................................................ 8
2.1.6. Submitting a Fix ................................................................................................................. 8
2.2. Development Toolchain Requirements ........................................................................................... 8
2.2.1. Appliance ........................................................................................................................... 8
2.3. Programming Techniques ............................................................................................................ 10
2.3.1. Calling Methods Using REST ............................................................................................ 10
2.3.1.1. How to Call Methods Using REST .......................................................................... 10
2.3.1.2. Sending an Event .................................................................................................. 11
2.3.2. Miscellaneous Notes ......................................................................................................... 13
2.3.2.1. pkg_resources ....................................................................................................... 13
2.3.2.2. urllib2 Workarounds ............................................................................................ 13
2.4. zendmd: Command-line Access to the Device Management Database (DMD) ................................. 14
2.5. Programming Documentation ....................................................................................................... 16
2.5.1. Python ............................................................................................................................. 16
2.5.2. Zenoss API ...................................................................................................................... 16
2.5.3. Other Resources .............................................................................................................. 16
2.5.4. Contributing to the Documentation .................................................................................... 16
3. ZenPacks .............................................................................................................................................. 17
3.1. Overview .................................................................................................................................... 17
3.2. Creating a ZenPack .................................................................................................................... 17
3.2.1. ZenPack Names ............................................................................................................... 17
3.2.2. Specifying Dependencies .................................................................................................. 18
3.2.3. Locating ZenPack Source Outside of Zenoss ..................................................................... 18
3.2.4. Community ZenPack Subversion Access ........................................................................... 18
3.3. ZenPack Structure and Contents ................................................................................................. 18
3.4. Developing the ZenPack ............................................................................................................. 21
3.4.1. Base ZenPack Class ........................................................................................................ 21
3.4.2. Storing Objects in the ZODB ............................................................................................. 21
3.4.3. Providing DataSource classes ........................................................................................... 21
3.4.4. Monitoring Template Checklist .......................................................................................... 22
3.4.4.1. Data Sources ........................................................................................................ 22
3.4.4.2. Data Points ........................................................................................................... 22
3.4.4.3. Thresholds ............................................................................................................ 23
3.4.4.4. Graph Definitions ................................................................................................... 23
3.4.4.5. Graph Points ......................................................................................................... 23
3.4.5. Providing Performance Collector Plugins ........................................................................... 23
3.4.6. Referencing Collector Plugins in ZenPacks ........................................................................ 23
3.4.7. Providing Daemons .......................................................................................................... 24
iii
Zenoss Developer's Guide
4.
5.
6.
7.
8.
9.
3.4.8. setuptools and the zenpacksupport ...................................................................................
3.5. Building and Distributing ZenPacks ..............................................................................................
3.5.1. Migrating between versions ...............................................................................................
3.5.2. Converting older ZenPacks to ZenPack eggs .....................................................................
3.6. Development Mode .....................................................................................................................
3.6.1. Source ZenPacks .............................................................................................................
3.6.2. Converting .egg Files to Development Mode ......................................................................
3.7. Where to Get More Information ...................................................................................................
Zenoss Data Stores ...............................................................................................................................
4.1. Zope Object Database (ZODB) ....................................................................................................
4.2. MySQL Event database ...............................................................................................................
4.2.1. Connecting to the Database ..............................................................................................
4.2.2. MySQL in 60 Seconds ......................................................................................................
4.3. Python Pickle Files ......................................................................................................................
4.4. Round-Robin Database ...............................................................................................................
Events ...................................................................................................................................................
5.1. Understanding an Event Entry .....................................................................................................
5.1.1. Event Design ...................................................................................................................
5.2. Sending an Event .......................................................................................................................
5.3. Adding an Event Class ................................................................................................................
5.3.1. Add to ZenEventClasses ..................................................................................................
5.3.2. Add the class to the import XML .......................................................................................
5.3.3. Write a migrate script .......................................................................................................
Configuration Property Management .......................................................................................................
6.1. Adding a Configuration Property ..................................................................................................
6.1.1. Adding a Configuration Property to an Event .....................................................................
6.1.2. Adding a Configuration Property to a Device ......................................................................
6.2. Migrating the Configuration Property Code ...................................................................................
Creating New Jobs ................................................................................................................................
7.1. Job Requirements .......................................................................................................................
7.2. Running a Job ............................................................................................................................
7.3. Life Cycle of a Job ......................................................................................................................
7.4. Shell Command Jobs ..................................................................................................................
7.5. Logging ......................................................................................................................................
Device Management ..............................................................................................................................
8.1. Adding Devices Programatically ...................................................................................................
8.1.1. Using a REST call ............................................................................................................
8.1.2. Example: Using an XML-RPC Call from Python .................................................................
8.1.3. XML-RPC Attributes .........................................................................................................
8.2. Editing Device Information ...........................................................................................................
8.2.1. Using a REST call ............................................................................................................
8.2.2. Using an XML-RPC Call from Python ................................................................................
8.3. Deleting A Device .......................................................................................................................
8.3.1. Using a REST call ............................................................................................................
8.3.2. Using an XML-RPC Call from Python ................................................................................
8.4. Checking If A Device Exists ........................................................................................................
8.4.1. Using a REST call ............................................................................................................
8.4.2. Using an XML-RPC Call from Python ................................................................................
8.5. Exporting a Device List ...............................................................................................................
Extending the Model ..............................................................................................................................
9.1. Add a ZenModel Relationship ......................................................................................................
9.1.1. One-to-One (1:1) Relationships .........................................................................................
9.2. One-to-Many (1:N) Relationships .................................................................................................
9.3. Many-to-Many (M:N) Relationships ...............................................................................................
iv
24
24
25
25
25
25
25
26
27
27
29
29
29
30
31
33
33
33
33
34
34
34
35
36
36
36
36
36
38
38
38
38
39
39
40
40
40
40
40
41
41
41
42
42
42
42
42
42
43
44
44
44
45
46
Zenoss Developer's Guide
9.3.1. One-to-Many (1:N) Container Relationships .......................................................................
9.4. Zenoss XML Schema ..................................................................................................................
9.4.1. object ...............................................................................................................................
9.4.1.1. Example ................................................................................................................
9.4.1.2. Attributes ...............................................................................................................
9.4.1.3. Children ................................................................................................................
9.4.2. objects .............................................................................................................................
9.4.2.1. Example ................................................................................................................
9.4.2.2. Children ................................................................................................................
9.4.3. property ...........................................................................................................................
9.4.3.1. Example ................................................................................................................
9.4.3.2. Attributes ...............................................................................................................
9.4.4. tomany .............................................................................................................................
9.4.4.1. Example ................................................................................................................
9.4.4.2. Attributes ...............................................................................................................
9.4.4.3. Children ................................................................................................................
9.4.5. tomanycont ......................................................................................................................
9.4.5.1. Example ................................................................................................................
9.4.5.2. Attributes ...............................................................................................................
9.4.5.3. Children ................................................................................................................
9.4.6. toone ...............................................................................................................................
9.4.6.1. Example ................................................................................................................
9.4.6.2. Attributes ...............................................................................................................
9.4.7. link ..................................................................................................................................
9.4.7.1. Example ................................................................................................................
9.4.7.2. Attributes ...............................................................................................................
9.5. Zenoss Permissions ....................................................................................................................
9.5.1. Adding New Permissions ..................................................................................................
9.5.2. Assigning Permissions to a Method ...................................................................................
9.5.3. Checking Links .................................................................................................................
10. Zenoss Daemons .................................................................................................................................
10.1. Twisted Network Programming Overview ....................................................................................
10.1.1. Understanding NJobs, Driver and DeferredList .................................................................
10.1.1.1. DeferredList .........................................................................................................
10.1.1.2. NJobs .................................................................................................................
10.1.1.3. Driver ..................................................................................................................
10.1.1.4. A Simple Example ...............................................................................................
10.2. Zenoss Daemon Overview .........................................................................................................
10.3. zenhub: Daemon to ZODB management ....................................................................................
10.3.1. Daemon to ZODB management ......................................................................................
10.3.2. Heartbeats and other Events ...........................................................................................
10.3.3. Pluggable Daemon Services ...........................................................................................
10.4. ZenRender and Graphs .............................................................................................................
10.5. Developing a Daemon ...............................................................................................................
10.5.1. Command-line Options ...................................................................................................
10.5.2. Add the Daemon Control Script .......................................................................................
10.5.3. Set Up ZenHub Communications ....................................................................................
10.5.3.1. Registering Services with the Hub ........................................................................
11. Add a Performance Daemon ................................................................................................................
11.1. Overview ...................................................................................................................................
11.2. DataMaps .................................................................................................................................
11.3. Performance Collection ..............................................................................................................
11.3.1. Connecting Collectors and Services ................................................................................
11.4. Creating a New Collector ...........................................................................................................
v
47
48
50
50
50
50
51
51
51
51
51
52
52
52
52
52
52
52
53
53
53
53
53
53
53
53
53
54
54
54
55
55
55
55
56
56
57
59
60
60
61
61
61
62
62
62
63
63
64
64
64
66
66
66
Zenoss Developer's Guide
11.4.1. Constructor ....................................................................................................................
11.4.2. Getting a List of Devices .................................................................................................
11.4.2.1. Thresholds ..........................................................................................................
11.4.3. fetchConfig() ................................................................................................................
11.4.4. Collector's ZenHub Service .............................................................................................
11.4.5. Miscellaneous Functions .................................................................................................
11.4.6. Collect the Performance Data .........................................................................................
12. Adding a Device Type ..........................................................................................................................
12.1. Overview ...................................................................................................................................
12.2. Add the MIB .............................................................................................................................
12.3. Add a Device Organizer ............................................................................................................
12.4. Create a Modeler ......................................................................................................................
12.4.1. Verify the SNMP connectivity and OIDs ...........................................................................
12.4.2. Common SNMP Issues ...................................................................................................
12.4.3. Modeler Code ................................................................................................................
12.4.4. Testing the Modeler ........................................................................................................
12.5. Create a Performance Collector .................................................................................................
12.5.1. Performance Data Collector Code ...................................................................................
12.5.2. Writing Your Own Command Parser ................................................................................
12.6. Create the Template .................................................................................................................
12.6.1. Create the DataSource ...................................................................................................
12.6.2. Create a Threshold .........................................................................................................
12.6.3. Create a Graph ..............................................................................................................
12.7. Map Events ..............................................................................................................................
12.8. Adding SSH Monitoring Tests ....................................................................................................
12.8.1. Overview ........................................................................................................................
12.8.2. Modeling Plugin Test Data ..............................................................................................
12.8.2.1. Test Data for an ObjectMap ..................................................................................
12.8.2.2. Test Data for a RelationshipMap ..........................................................................
12.8.2.3. Test Data for a List of Data Maps .........................................................................
12.8.3. Data Point Parser Test Data ...........................................................................................
12.8.3.1. Test Data for Device-Level Parsers .......................................................................
12.8.3.2. Test Data for Component Parsers .........................................................................
12.8.4. Running the Tests ..........................................................................................................
13. Extending the User Interface ................................................................................................................
13.1. About Zenoss UI Technologies ..................................................................................................
13.1.1. HyperText Markup Language (HTML) ..............................................................................
13.1.2. Cascading Style Sheets (CSS) ........................................................................................
13.1.3. Zope 2, ZPT and TAL .....................................................................................................
13.1.4. ZPT and Macro Expansion for TAL (METAL) ...................................................................
13.1.5. JavaScript / AJAX ...........................................................................................................
13.1.6. JavaScript Library: Ext JS ...............................................................................................
13.2. Customizing the Navigation Bar .................................................................................................
13.2.1. Example: Simple HTML Page .........................................................................................
13.2.2. Example: Simple TAL and METAL Page ..........................................................................
13.3. Customizing the Logo ................................................................................................................
13.4. Zope 2 Page Templates, TAL and METAL and Zenoss ...............................................................
13.4.1. Tips ...............................................................................................................................
13.5. Zope 3 Views Explained ............................................................................................................
13.5.1. The Zope 2 Way ............................................................................................................
13.5.2. The Zope 3 Way ............................................................................................................
13.6. Other Customizations ................................................................................................................
13.6.1. Adding Tabs ...................................................................................................................
13.6.2. Adding a Dialog ..............................................................................................................
vi
66
67
68
69
70
70
71
74
74
74
74
75
76
76
76
79
79
79
80
82
82
82
82
82
83
83
83
83
84
84
84
84
85
85
86
86
86
86
86
87
87
87
87
88
88
89
89
91
92
92
93
95
95
97
Zenoss Developer's Guide
13.6.3. Adding a New Menu or Menu Item .................................................................................. 99
13.6.4. Creating a Table Using ZenTableManager ..................................................................... 100
13.6.5. Creating an Editable Table ............................................................................................ 102
13.6.6. How to Save Properties via an Edit Screen .................................................................... 102
13.7. Creating a Dashboard Portlet ................................................................................................... 104
13.7.1. Create a ZenPack ........................................................................................................ 104
13.7.2. Write the Python Back-End Code .................................................................................. 105
13.7.3. Write the JavaScript Portlet ........................................................................................... 106
13.7.4. Register the Portlet ....................................................................................................... 111
13.8. Debugging Tips ....................................................................................................................... 112
14. ZenPack Conversion Tasks for Version 3.0 ......................................................................................... 113
14.1. About ZenPack Conversion ...................................................................................................... 113
14.1.1. What Has Changed? .................................................................................................... 113
14.1.1.1. Redesigned Pages ............................................................................................. 113
14.1.2. Updating Page Templates ............................................................................................. 114
14.1.3. Updating Page-Level Dialogs ........................................................................................ 114
14.1.4. Updating Data Sources ................................................................................................. 115
14.1.4.1. Modify the MANIFEST.in File .............................................................................. 115
14.1.4.2. Create an Interface for the Data Source .............................................................. 115
14.1.4.3. Create an info Object ......................................................................................... 116
14.1.4.4. Write an Adapter ................................................................................................ 117
14.1.5. Updating Thresholds ..................................................................................................... 117
14.1.6. Custom "Add Device" Widget ........................................................................................ 117
14.1.7. Custom Columns on the Component Grid (Device Summary) .......................................... 118
15. Reports .............................................................................................................................................. 120
15.1. Adding a Report ...................................................................................................................... 120
15.2. Plugins .................................................................................................................................... 121
15.3. Adding Export Buttons to Reports ............................................................................................ 121
16. Migrating Zenoss Code ...................................................................................................................... 123
16.1. Introduction and Steps ............................................................................................................. 123
16.2. How It Works .......................................................................................................................... 123
16.3. What You Write ....................................................................................................................... 123
16.3.1. Implement cutover() ...................................................................................................... 124
16.3.2. Supporting Code ........................................................................................................... 124
16.3.3. Testing and Deployment ............................................................................................... 124
17. Testing .............................................................................................................................................. 125
17.1. Zenoss Unit Tests ................................................................................................................... 125
17.1.1. Introduction .................................................................................................................. 125
17.1.2. doctest Testing ............................................................................................................. 125
17.1.3. Zenoss' Test Runner ..................................................................................................... 126
17.1.3.1. An Example Unit Test ........................................................................................ 127
17.1.4. Integrating With Buildbot ............................................................................................... 130
17.1.5. JavaScript Test Framework ........................................................................................... 130
17.2. Functional User Interface Testing ............................................................................................. 130
17.2.1. Introduction .................................................................................................................. 130
17.2.2. Installing and Running .................................................................................................. 130
17.2.2.1. Installing and Configuring Mac OS X ................................................................... 130
17.3. Where to Get More Information ................................................................................................ 131
A. Event Database Dictionary ................................................................................................................... 132
B. TALES Expressions ............................................................................................................................. 133
B.1. Examples ................................................................................................................................. 133
B.1.1. ping ............................................................................................................................... 133
B.1.2. DNS forward lookup ....................................................................................................... 133
B.1.3. DNS reverse lookup ....................................................................................................... 133
vii
Zenoss Developer's Guide
B.1.4. snmpwalk ......................................................................................................................
B.2. TALES Device Attributes ...........................................................................................................
B.3. TALES Event Attributes .............................................................................................................
Glossary ..................................................................................................................................................
viii
133
133
134
136
Chapter 1. Introduction
1.1. Overview
The Zenoss system provides full stack coverage of networks, servers, applications, services, and virtualization.
Functionally, it provides complete operational awareness by combining discover and inventory, availability and performance monitoring, event management, and reporting.
At its highest level, the system comprises these major areas:
•
Discovery and configuration
•
Performance and availability
•
Fault and event management
•
Alerting and remediation
•
Reporting
Zenoss unifies these areas into a single system with a modern, interactive Web user interface.
Figure 1.1. High-Level view
1.1.1. Key Tenets
Zenoss was designed with these important ideas at its core:
•
Modeling
The system's model enables it to understand the environment in which it operates. Through sophisticated and
detailed analysis, Zenoss determines how to monitor and manage complex IT environments. The core of the
1
Introduction
standard model describes basic information about each device's operating system and hardware. The model is
object-based, and is easily extended through object inheritance.
•
Discovery
With a sophisticated model, manual input and maintenance of data is challenging. To address this challenge,
Zenoss uses discovery to populate the model. During discovery, the system accesses each monitored device in
your infrastructure and interrogates it in detail, acquiring information about its components, network integration,
and dependencies.
•
Normalization
Because Zenoss collects information from different platforms and through different protocols, the amount and
format of available information varies. For example, file system information gathered from a Linux server differs
from similar information gathered from a Windows server. Zenoss standardizes the data gathered so that you
can perform valid comparisons of metrics gathered by different methods and for different systems.
•
Agentless Data Collection
To gather information, Zenoss relies on agent-less data collection. By communicating with a device through one
of several protocols (including SNMP, SSH, Telnet, and WMI), it minimizes the impact on monitored systems.
•
Full IT Infrastructure
Unlike other tools, the system's inclusive approach unifies all areas of the IT infrastructure--network, servers,
and applications--to eliminate your need to access multiple tools.
•
Configuration Inheritance
Zenoss extends the concept of inheritance in object-oriented languages to configuration. All core configuration
parameters (configuration properties) and monitoring directions (monitoring templates) use inheritance to describe how a device should be monitored. Inheritance allows you to describe, at a high level, how devices should
be monitored. It also supports ongoing refinements to the configuration. (For detailed information on inheritance
and templates, refer to the chapter titled "Properties and Templates.")
•
Cross-Platform Monitoring
Zenoss monitors the performance and availability of heterogeneous operating systems (including Windows,
Linux, and Unix), SNMP-enabled network devices (such as Cisco), and a variety of software applications (such
as WebLogic and VMware).
•
Scale
You can deploy the system on a single server to manage hundreds of devices. The Enterprise version allows
you to manage large, distributed systems by using horizontal scaling of its collectors.
•
Extensibility
The system's extension mechanism, ZenPacks, allow for rapid addition and modification to customize your
environment.
1.2. Architecture and Technologies
The following diagram illustrates the system architecture.
2
Introduction
Figure 1.2. Architecture
Zenoss is a tiered system with four major parts:
•
•
•
•
User layer
Data layer
Processing layer
Collection layer
1.2.1. User Layer
Built around the Zope Web application environment, the user layer is manifested as a Web portal. It uses several
JavaScript libraries, Mochi Kit, YUI, and extJS to provide a rich application experience.
Through the user interface, you access and manage key components and features. From here, you can:
•
Watch the status of your enterprise, using the Dashboard
•
Work with devices, networks, and systems
•
Monitor and respond to events
•
Manage users
•
Create and run reports
The user layer Interacts with the data layer and translates the information for display in the user interface.
1.2.2. Data Layer
Configuration and collection information is stored in the data layer, in three separate databases:
•
ZenRRD - Utilizing RRDtool, stores time-series performance data. Because RRD files are stored locally to each
collector, no bottlenecks result from writing to a single database as new collectors are added.
•
ZenModel - Serves as the core configuration model, which comprises devices, their components, groups, and
locations. It holds device data in the ZEO back-end object database.
•
ZenEvents - Stores event data in a MySQL database.
3
Introduction
1.2.3. Process Layer
The process layer manages communications between the collection and data layers. It also runs back-end, periodic
jobs, as well as jobs initiated by the user (ZenActions and ZenJobs).The process layer utilizes Twisted PB (a bidirectional RPC system) for communications.
1.2.4. Collection Layer
The collection layer comprises services that collect and feed data to the data layer. These services are provided by
numerous daemons that perform modeling, monitoring, and event management functions.
The modeling system uses SNMP, SSH, and WMI to collect information from remote machines. The raw information
is fed into a plugin system (modeling plugins) that normalizes the data into a format that matches the core model.
Monitoring daemons track the availability and performance of the IT infrastructure. Using multiple protocols, they
store performance information locally in RRD files, thus allowing the collectors to be spread out among many collector machines. Status and availability information, such as ping failures and threshold breaches, are returned
through ZenHub to the event system.
For more information about system daemons, see the appendix in the Zenoss Administration guide titled "Daemon
Commands and Options."
4
Chapter 2. Getting Started
2.1. Working with the Source Code
2.1.1. Getting the Source Code
If all that you would like to do is browse through the source code, then go to the Trac/Subversion page at:
http://dev.zenoss.com/trac/browser
The version control system used by Zenoss is Subversion. Subversion has excellent documentation in the form of
an O'Reilly book. For the moment, we will just provide the minimum number of commands to get started.
The absolute latest version of Zenoss can be accessed directly through the Subversion repository. This code should
not be used for production purposes as there are changes actively being made which may not have been thoroughly
tested.
From a command line prompt, go to a directory where you want the source code delivered. Here's a sample command to get the source code:
$ svn co http://dev.zenoss.org/svn/trunk/Products
This will create a directory called Products in the current directory and check out the source code. This repository
is readable anonymously, so no credentials are required.
To see which other portions of the code are available, such as ZenPacks or support utilities, you can look by using
the following Subversion command:
$ svn ls http://dev.zenoss.org/svn/trunk
Other tools are available that can be used to view or check out the source code for different platforms. See the
Subversion Web site for more details.
2.1.1.1. Getting Subversion for the Appliance
The rPath appliance does not ship with the svn binaries, but you can still obtain them.
Procedure 2.1. Installing Subversion on Appliances
1.
Edit the /etc/conaryrc file:
•
For the Community version, look for the line that looks like this:
installLabelPath zenoss-project.zenoss.loc@zenoss:core-2.3
Change the above line to this (note that this should be all one line and has been modified to make it look
better in print):
installLabelPath zenoss-project.zenoss.loc@zenoss:core-2.3
conary.rpath.com@rpl:1
•
For the Enterprise version, look for the line that looks like this:
installLabelPath zenoss-project.zenoss.loc@zenoss:enterprise-2.3
Change the above line to this (note that this should be all one line and has been modified to make it look
better in print):
installLabelPath zenoss-project.zenoss.loc@zenoss:enterprise-2.3
conary.rpath.com@rpl:1
5
Getting Started
2.
Now you should be able to obtain the subversion package by using the conary update command:
[root@localhost ~] conary update --resolve subversion
For more information about rPath commands, see their documentation wiki. There are also a set of blog entries
Conary Uncorked has been put together by a dedicated rPath user that introduces some of the conary commands
much more gently.
2.1.2. Keeping Code Updated
The following command, issued from the base directory where you checked out the Zenoss code, will update all
code from that directory and all subdirectories and bring it up to date with what is current in the Subversion repository
(and therefore apply all of the current patches to the code you checked out previously):
$ svn update
If you have modified any code in this directory, these changes will be merged with the latest code updates. If there
are differences that Subversion cannot automatically resolve, Subversion will tell you that there is a problem by
showing the updated file is in conflict (for example, showing a 'C' beside the file when you run svn status).
You can tell if you have modified any of the files in the checked-out directory by typing the following:
$ svn status
If you are interested in modifying only one file, you can specify that one file:
$ svn udpate filename
2.1.3. Getting Patches
For issue tracking, bug reports and linking patches to bug reports, Zenoss uses Trac to manage issues. The Zenoss
Trac server is found at this location:
http://dev.zenoss.com/trac/report
You can click Search at the top right of the page and enter a search term to look for keywords in the tickets. This
will then present you with the ability to search for changesets (for example, Subversion revisions), trouble tickets,
or the Wiki.
Alternatively, from the start page you can click on the Custom Query which will allow you to view the results from
your customized query.
Once you have found a patch that applies to your system, use the zenpatch command to apply the patch. (As
mentioned previously, if you use the svn update commands, you will already be at the latest patched level.)
$ zenpatch revision_number
2.1.4. Style Guidelines
These following guidelines are targeted at Python files. HTML files, Zope Page Template (ZPT) files, shell scripts,
etc should adhere to these as much as is reasonable and conventional in those languages. Currently, we follow
Guido's Style Guide for Python Code which is detailed in PEP 8 (Python Enhancement Proposals).
Any style conventions that stray from PEP-8 should be annotated in this document.
2.1.4.1. Docstrings
Every method and function definition within Zenoss should include a docstring. The docstring is usually composed
of two parts: the explanatory text and the doctest code. The explanation usually includes a description of all or most
of the following aspects of the function:
6
Getting Started
•
The function's purpose
•
The context in which the function is usually called
•
What parameters it expects
•
What it returns
•
Any side effects of the function
This explanatory text should scale in size with the complexity and significance of the function.
The second part of the docstring is the doctest section. This is composed of zendmd commands and expected
output from those commands. The commands are run as part of the testing process and output is compared to the
output lines. This code serves two primary purposes. First it is a working example of how the function should be
called and what it returns. Second it serves as a basic test to ensure the function is not horribly broken. This is not
intended as a replacement for unit tests. Thorough testing of boundary cases and unusual situations still belongs in
unit tests whereas the doctests are much simpler and more instructional in nature.
Docstrings begin on the line immediately following the function definition and are indented one level from the definition. The first and last lines of the docstring are three double quotes and a newline. One blank line separates
the description from the epydoc section. epydoc can take specially formatted text in the docstrings and use them
to create API documentation. The Zenoss API documentation is located on the Zenoss Web site and is updated
every release.
Another blank line separates the epydoc section from the doctest section. The code for the function begins on the
line immediately following the docstring. For example:
def TruncateStrings(longStrings, maxLength):
"""
Foo truncates all the strings in a list to a maximum length.
longStrings is any iterable object which returns zero or more
strings. maxLength is the length to which each element from
longStrings should be truncated.
@param longStrings: an iterable object which returns zero or more strings
@type longStrings: Python iterable
@param maxLength: max length of each element in longStrings
@type maxLength: int
@return: longStrings in the same order but possibly truncated
@rtype: list
@todo: Add more epydoc attributes!
>>> from Products.SomeModule import TruncateStrings
>>> TruncateStrings(['abcd', 'efg', 'hi', ''], 3)
['abc', 'efg', 'hi', '']
>>> TruncateStrings([], 5)
[]
"""
return [s[:maxLength] for s in longStrings]
The easiest way to create the doctest portion is from within zendmd. Except for the indentation, the docstring should
exactly match commands and output from a zendmd session.
Use the available epydoc fields where they are applicable. Some of the useful common fields are:
Commonly-used epydoc fields
@param param_name
Describe the parameter
@type data_type
Data type of the parameter
@return
Describe the return value
7
Getting Started
@rtype
Data type of the return value
@permission
Zope permission that the method requires
@todo
Todo for this method
Note
Within the description section of the docstring, you may use the string DEPRECATED on its own line to denote that
the method is deprecated.
2.1.5. Generating Diffs for new Fixes
Once you have determined how to fix something, or have found a way to add a feature, modify the source code in
your checkout directory. Once that is complete, generate a diff starting from the base of the checkout directory.
To generate a diff of all files in the current directory and all subdirectories:
$ svn diff > mychanges.diff
To produce a diff for just a single file:
$ svn diff source_file > mychanges.diff
2.1.6. Submitting a Fix
Zenoss accepts user contributions using the following procedure:
1.
Complete the form to allow Zenoss to accept your code.
2.
Create a ticket in our ticketing system.
3.
Add the keyword contribute to the ticket.
4.
Attach your patch (in diff format) or code to the ticket.
Note
All contributions will be accepted under the terms of the Zenoss Contribution Agreement.
2.2. Development Toolchain Requirements
There are a number of other tools that are required to build Zenoss from source (a toolchain). Among them are a
C compiler, the make command, and other associated tools.
2.2.1. Appliance
The Zenoss appliance is based on the rPath Linux 1 (rp11) distribution.
Troves (like the gcc toolchain) that are not available on the Zenoss update repository server are generally available
from install labels, such as:
conary.rpath.com@rpl:1
The trove candy store is rBuilder Online. Zenoss recommends that you obtain an account there. It provides good
search capabilities for packages of interest, and offers forums to assist with appliance-specific questions.
For a gcc toolchain, try this as the root user:
# conary update --resolve autoconf automake make which \
8
Getting Started
--install-label="conary.rpath.com@rpl:1"
# conary update --resolve gcc=conary.rpath.com@rpl:1 \
--install-label="conary.rpath.com@rpl:devel"
The binutils trove should already be on the box.
An actual install sequence looked like the ouput below. If the --info switch is used, it is possible to see if everything
is going to resolve nicely. And if you are really paranoid, use the --test flag which runs through the update but does
not commit the result.
# conary update autoconf automake make which --resolve --info \
--install-label="conary.rpath.com@rpl:1"
Install autoconf(:data :doc :runtime)=2.59-7-0.1
Install automake(:data :doc :runtime)=1.9.6-3-0.1
Install m4(:runtime)=1.4.3-4-0.1
Install make(:doc :locale :runtime)=3.80-7.2-1
Install which(:doc :runtime)=2.16-3-0.1
# conary update autoconf automake make which --resolve \
--install-label="conary.rpath.com@rpl:1"
Including extra troves to resolve dependencies:
m4:runtime=1.4.3-4-0.1
Applying update job:
Install autoconf(:data :doc :runtime)=2.59-7-0.1
Install automake(:data :doc :runtime)=1.9.6-3-0.1
Install m4(:runtime)=1.4.3-4-0.1
Install make(:doc :locale :runtime)=3.80-7.2-1
Install which(:doc :runtime)=2.16-3-0.1
# conary update --info --resolve gcc=conary.rpath.com@rpl:1 \
--install-label="conary.rpath.com@rpl:devel"
Install gcc(:devel :devellib :doc :lib :locale :runtime)=3.4.4-9.4-1
Install libgcc(:devellib)=4.1.2-11-1[~!gcc.core]
#
conary update --resolve gcc=conary.rpath.com@rpl:1 \
--install-label="conary.rpath.com@rpl:devel"
Including extra troves to resolve dependencies:
libgcc:devellib=4.1.2-11-1
Applying update job:
Install gcc(:devel :devellib :doc :lib :locale :runtime)=3.4.4-9.4-1
Install libgcc(:devellib)=4.1.2-11-1[~!gcc.core]
Generally try to find something on the rpl:1 branch name and do not mix rpl:2 stuff with the rpl:1 stuff. In some
cases, you may have to resort to pulling a trove from the rpl:devel branch if it cannot find it elsewhere. That's what
happened above when trying to resolve the libgcc dependency for the gcc trove. Adding the extra --install-label
option was necessary so that libgcc could be found. How could you know it was on rpl:devel? Go to rBuilder Online
and search for that package and it should tell you.
If you want to see where the files for a trove are installed:
# conary q trove_name --lsl
[code]# conary
...
lrwxrwxrwx
1
-rwxr-xr-x
1
-rwxr-xr-x
1
...
q gcc --lsl
root
root
root
root
root
root
3 2004-07-07 17:04:44 UTC /usr/bin/cc -> gcc
81452 2006-06-19 18:02:30 UTC /usr/bin/gcc
16134 2005-10-15 07:22:42 UTC /usr/bin/gccbug
Lastly, conary makes it relatively easy to run-away if you're not happy with a trove you've installed. Use conary
rblist to see what packages have been committed to the conary stack.
# conary rblist | more
9
Getting Started
r.3:
installed: gcc(:devel :devellib :doc :lib :locale :runtime)
conary.rpath.com@rpl:1/3.4.4-9.4-1
installed: libgcc(:devellib) conary.rpath.com@rpl:devel/4.1.2-11-1
r.2:
installed: autoconf(:data :doc :runtime) conary.rpath.com@rpl:1/2.59-7-0.1
installed: automake(:data :doc :runtime) conary.rpath.com@rpl:1/1.9.6-3-0.1
installed: m4(:runtime) conary.rpath.com@rpl:1/1.4.3-4-0.1
r.1:
updated: info-raa-web(:user) products.rpath.com@rpath:raa-2/1-1.1-2 ->
1-1.3-2
...
Here is how you would remove the gcc trove that was just installed:
# conary rb r.3
Applying update job:
Erase
gcc(:devel :devellib :doc :lib :locale :runtime)=3.4.4-9.4-1
Erase
libgcc(:devellib)=4.1.2-11-1[~!gcc.core]
# conary q gcc
gcc was not found
Be careful which troves you remove!
2.3. Programming Techniques
2.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.
2.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. Calls 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:
10
Getting Started
http://USERNAME:PASSWORD@MY_ZENOSS_HOST:8080/zport/dmd/
Devices/Server/Linux/devices/angel/getRRDValue?dsname=laLoadInt5_laLoadInt5
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.
2.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.
2.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 --auth-no-challenge 'http://admin:zenoss@MYHOST:8080/zport/dmd/ZenEventManager/manage_addEvent?
device=MYDEVICE&component=MYCOMPONENT&summary=MYSUMMARY&severity=4&eventclass=EVENTCLASS'
2.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 example, eth0 or http)
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.
2.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.
2.3.1.2.3.1. Perl
Send an event via Perl using RPC::XML::Client
11
Getting Started
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);
2.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)
2.3.1.2.3.3. PHP
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));
}
?>
12
Getting Started
2.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 params = new HashMap();
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});
}
}
2.3.2. Miscellaneous Notes
2.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
2.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
13
Getting Started
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
Monitoringin the chapter on ZenWebTX.
2.4. zendmd: Command-line Access to the Device Management
Database (DMD)
Zenoss uses the Zope database (ZODB) to store its information. Since the ZODB is an object-oriented database,
this is not organized by tables, rows and columns, but by objects. The object that Zenoss uses to store the basic
model of your network is in the Device Management Database (DMD) object.
You can access the DMD through an interactive, programmable interpreter: zendmd. zendmd is the Python interpreter, with a handle to the database stored in the default namespace, and a few handy functions.
To start zendmd and see how the interpreter works, use the following commands:
$ zendmd
>>> 1 + 2
3
>>> len('hello there')
11
>>> for i in range(5):
...
print i
0
1
2
3
4
These are all basic Python interpreter features. zendmd adds in a reference to the root of the object tree which is
known as dmd. You can see this root name in the URLs used to refer to objects when using Zenoss from the browser.
There is a built-in function that can be used to find devices.
$ zendmd
>>> print dmd
>>> find('localhost.localdomain')
The find() function also takes wildcards:
>>> find('local*')
You can perform scripting at the command prompt. For example, we can count the number of interfaces on our
device:
>>> d = find('local*')
len(d.os.interfaces())
5
You can inspect the objects:
>>> d.getManageIp()
'127.0.0.1'
14
Getting Started
for i in d.os.interfaces():
... for a in i.ipaddresses():
... print a.name(), a.getIpAddress()
eth0 192.168.1.148/24
You can perform low-level checks such as re-indexing all the objects:
>>> reindex()
Or check/repair relationships on all devices:
>>> for d in dmd.Devices.getSubDevices():
...
d.checkRelations(repair=True)
...
Finally, after making changes you can commit them to the database:
>>> commit()
or synch against the database and restore the old state to your interpreter, reverting any changes:
>>> synch()
Zendmd can be used to automate repetitive tasks. For example, you can enter in a large list of devices. First, create
a text file containing the names of those devices:
$ cat >lotsOfDevices.txt
device1
myhost.mydomain.com
host2.mydomain.com
^D
Of course, the data could come from an inventory list or other database. Then, you can use the dmd to process
the file:
$ zendmd
for line in file('lotsOfDevices.txt'):
... d = dmd.Devices.Server.Linux.createInstance(line.strip())
... commit()
... d.collectDevice()
You can feed zendmd commands on stdin:
$ zendmd < AddDevices.py
You can also import scripts:
$ zendmd
import MyScripts
MyScripts.loadDevices(dmd)
If you want to create a stand-alone command, reading the $ZENHOME/ZenModel/zendmd.py file is a good start.
The full list of zendmd names is described below.
zendmd Name
Description
dmd
Device Management Database, the root persistent object
app
The Zope Application, the root of the database
zport
Zenoss Portal, the portal that contains Zenoss
find()
Look up devices by name, and by address; supports wildcards
15
Getting Started
zendmd Name
Description
devices
Equivalent to dmd.Devices
sync()
Revert the objects in zendmd back to the state in the ZODB
commit()
Push object changes to the persistent store
abort()
Undo any object changes and refresh from persistent storage
me
a reference to the machine running zendmd, if it can be found
reindex()
recreates the indexes against the objects
login()
sets the security context of the given user
logout()
removes any security context
Table 2.1. zendmd Names and Descriptions
2.5. Programming Documentation
2.5.1. Python
If you are new to Python here are a few resources to get you started:
•
The official Python documentation contains a tutorial and the reference guide for the standard libraries that ship
with Python. Zenoss currently uses Python 2.6.
•
Dive Into Python is an excellent book if you are familiar with other programming languages and contains lots
of great examples.
2.5.2. Zenoss API
As mentioned previously, more detailed information is gathered using the epydoc documentation system, and the
results are in the Application Programming Interface (API) documentation.
2.5.3. Other Resources
Discussion regarding development of Zenoss takes place on the Zenoss forums, at:
http://community.zenoss.org/community/forums
2.5.4. Contributing to the Documentation
If you find errors or omissions in the documentation, you can submit a ticket (see Section 2.1.6, “Submitting a Fix”)
or send an e-mail to docs@zenoss.com.
16
Chapter 3. ZenPacks
3.1. Overview
A ZenPack is a package that adds new functionality to Zenoss. For basic information on ZenPacks see the chapter
titled "ZenPacks" in Zenoss Administration. The following information pertains to the creation of more complex
ZenPacks that contain skins, Python classes, and daemons.
ZenPacks are packaged as Python eggs, which are the standard mechanism for packaging and distributing code.
Note
The zenpack command should be used for installation and removal of ZenPacks, not the easy_install command
that is frequently used with non-ZenPack Python eggs.
The use of dotted names for ZenPacks (see Section 3.2.1, “ZenPack Names” below) was also introduced in this
version. Zenoss 2.2 and later supports installation and use of pre-2.2 ZenPacks, but all new ZenPacks are created
in the new format. This document relates to ZenPacks created in the new style. For documentation on ZenPacks
predating Zenoss 2.2, please see previous versions of this document and Zenoss Administration.
Zenoss currently does not support installation or use pre-2.2 ZenPacks. If you have older ZenPacks that you want to
convert to egg-style ZenPacks, see the section titled Section 3.5.2, “Converting older ZenPacks to ZenPack eggs”.
3.2. Creating a ZenPack
ZenPacks can be created through the Zenoss user interface:
1. From the navigation menu, select Advanced > Settings.
2. Select ZenPacks in the left panel.
The list of loaded ZenPacks appears.
3. Select Create a ZenPack from the Action menu.
4. Enter the ZenPack name, and then click OK.
The ZenPack is created on the file system at $ZENHOME/ZenPacks/zenpackid and installed on the system.
3.2.1. ZenPack Names
ZenPack names consist of at least three strings joined by periods. The first of these strings is always "ZenPacks."
Each of these strings must start with a letter and contain only letters, numbers and underscores. The reason for this
naming scheme is that the ZenPack will set up namespaces in Python that reflect these names. There is a Python
namespace called ZenPacks. Within that namespace are packages representing the second part of all the installed
ZenPack and so on. So for example if you have a ZenPack named ZenPacks.MyCompany.MyZenPack then it can be
imported in Python (and zendmd) as:
import ZenPacks.MyCompany.MyZenPack
A data source class provided by this example might be accessed as:
from ZenPacks.MyCompany.MyZenPack.datasources.MyDataSourceClass \
import MyDataSourceClass
The advantage of these namespaces is that they help prevent namespace conflicts among different organizations
authoring ZenPacks. So if a third party wants to develop an HTTP monitoring ZenPack, then they could name it
ZenPacks.OurCompany.HttpMonitor and it would not conflict with the ZenPacks.zenoss.HttpMonitor Core ZenPack.
17
ZenPacks
3.2.2. Specifying Dependencies
The ZenPack edit page allows you to specify versions of Zenoss with which your ZenPack is compatible, as well as
dependencies on other ZenPacks. The first item in the Dependencies section of the page is the version of Zenoss
that is required. If that field is blank then your ZenPack can be installed under any version of Zenoss version 2.2
or later. If you enter a specific version number then the ZenPack will run only under that exact version of Zenoss,
this is usually not desirable. The most typical version requirement is to specify that the ZenPack is compatible
with any version of Zenoss equal to or greater than a specific version. The syntax for this is ">=X" where X is the
minimum version the ZenPack requires. For example, if a ZenPack requires Zenoss version 2.2.1 or greater the
version specification would be >=2.2.1.
Below the Zenoss version specification is a list of all other ZenPack eggs installed. Old-style (non-egg) ZenPacks
cannot be listed as dependencies and do not appear in this list. If your ZenPack requires another ZenPack to be
installed, then select the option in the Required column next to the required ZenPack. You also can give a version
specification for each ZenPack you require.
3.2.3. Locating ZenPack Source Outside of Zenoss
For any non-trivial ZenPacks we recommend maintaining the source code somewhere other than $ZENHOME/ZenPacks. There are a couple reasons for this:
•
Performing a zenpack --remove deletes the ZenPack's directory from $ZENHOME/ZenPacks. If you do not have
the files copied in another location you can easily lose all or some of your work.
•
If your ZenPack source is maintained in a version control system it is frequently easier to keep the code within
a larger checkout directory elsewhere on the filesystem.
To move a ZenPack source directory out of $ZENHOME/ZenPacks you can simply copy the directory to the new location
then run install again using the --link option. This will remove the $ZENHOME/ZenPacks/YourZenPackId directory.
cp -r $ZENHOME/ZenPacks/YourZenPackId SomeOtherDirectory
zenpack --link --install SomeOtherDirectory/YourZenPackId
3.2.4. Community ZenPack Subversion Access
There is a Community ZenPack development site at:
http://community.zenoss.org/community/developers/zenpack_development
This site hosts Subversion source code control access to all contributed Community ZenPacks. Accounts are granted by request and offered to ZenPack contributors. The goal of this site is to encourage ZenPack development and
open up improvements to all ZenPacks to a greater audience.
The Community ZenPack development site contains instructions for:
•
working with Community ZenPacks from Subversion
•
building and modifying ZenPacks
•
converting old-style ZenPacks to Python egg ZenPacks
3.3. ZenPack Structure and Contents
This section describes the files and directory structures that make up most ZenPacks. A more detailed source of
information about Python eggs, entry points and other technical details of building eggs is found here.
18
ZenPacks
Note
The $ZENHOME/Products/ZenModel/ZenPackTemplate directory contains the template files and directories used
when Zenoss creates a ZenPack. If you decide to change these files, note that these changes will not be preserved across upgrades.
A ZenPack has the concept of a namespace, so that multiple people or organizations can create similar ZenPack
names without their code colliding with each other. In this example, the name of the ZenPack is ZenPacks.pkg.zpid,
where pkg is the package name and zpid is the ZenPack id.
In the $ZENHOME/ZenPacks/ directory, you will find the directory ZenPacks.pkg.zpid with the following contents (abbreviated for clarity):
build
build/bdist.linux-i686
build/lib
build/lib/ZenPacks
...
dist
dist/ZenPacks.pkg.zpid-version_id-py2.4.egg
INSTALL.txt
README.txt
setup.py
ZenPacks
ZenPacks/__init__.py
ZenPacks/pkg
ZenPacks/pkg/__init__.py
ZenPacks/pkg/zpid
ZenPacks/pkg/zpid/__init__.py
ZenPacks/pkg/zpid/daemons
ZenPacks/pkg/zpid/datasources
ZenPacks/pkg/zpid/datasources/__init__.py
ZenPacks/pkg/zpid/lib
ZenPacks/pkg/zpid/lib/__init__.py
ZenPacks/pkg/zpid/libexec
ZenPacks/pkg/zpid/migrate
ZenPacks/pkg/zpid/migrate/__init__.py
ZenPacks/pkg/zpid/modeler
ZenPacks/pkg/zpid/modeler/__init__.py
ZenPacks/pkg/zpid/modeler/plugins
ZenPacks/pkg/zpid/modeler/plugins/__init__.py
ZenPacks/pkg/zpid/objects
ZenPacks/pkg/zpid/objects/objects.xml
ZenPacks/pkg/zpid/parsers
ZenPacks/pkg/zpid/parsers/__init__.py
ZenPacks/pkg/zpid/reports
ZenPacks/pkg/zpid/services
ZenPacks/pkg/zpid/services/__init__.py
ZenPacks/pkg/zpid/skins
ZenPacks/pkg/zpid/skins/ZenPacks.pkg.zpid
ZenPacks.pkg.zpid.egg-info
ZenPacks.pkg.zpid.egg-info/entry_points.txt
ZenPacks.pkg.zpid.egg-info/namespace_packages.txt
ZenPacks.pkg.zpid.egg-info/not-zip-safe
ZenPacks.pkg.zpid.egg-info/PKG-INFO
ZenPacks.pkg.zpid.egg-info/SOURCES.txt
ZenPacks.pkg.zpid.egg-info/top_level.txt
19
ZenPacks
This directory is created by Python when the ZenPack is exported to an egg file or when it is installed from
source. This directory can safely be deleted at any time if you wish and need not be kept within any version
control system.
This directory is created when the ZenPack is exported to an egg file. The egg file is initially created within
here then copied to the $ZENHOME/export directory. This directory can safely be deleted at any time if you wish
and need not be kept within any version control system.
This file contains parameters for use by setuptools and distutils in creating eggs and doing source installs.
Zenoss creates an appropriate setup.py when a ZenPack is created. ZenPack developers should usually edit
this information through the ZenPack edit page within Zenoss rather than directly in the setup.py file.
Any time a ZenPack is saved or exported via the GUI Zenoss will modify certain values at the top of the setup.py
file. The lines that Zenoss modifies are clearly commented and segregated at the top of the file. If you wish to
make changes to setup.py you can safely do so as long as you leave those lines intact.
This directory mirrors the dotted name structure of your ZenPack name. For example, if your ZenPack name is
ZenPacks.MyCompany.MyZenPack then this directory will contain a directory named MyCompany which will contain
a MyZenPack directory. This last directory with the same name as the last part of your ZenPack name is where
most of the ZenPack code resides. The structure of that directory is very similar to that of previous non-egg
ZenPacks.
This is the directory whose name is that of the last part of your dotted ZenPack name.
This file contains any code that needs to be executed when the ZenPack is loaded. Zenoss loads all installed
ZenPacks on startup. Typically this file contains a few lines that will register a skins directory if the ZenPack
provides one. Also, if this class contains a class named ZenPack then on installation Zenoss will create an
instance of that class rather than the base ZenPack class in the object database.
See below for more details on providing daemons in ZenPacks.
See below for more details on providing data source classes in ZenPacks.
This directory is intended to hold any 3rd party modules or other code your ZenPack depends on. A module
named Foo in this directory would be imported with
import ZenPacks.MyCompany.MyZenPack.lib.Foo
This directory is intended to hold plugins, such as Nagios-style or Cacti-style plugins.
See below for more details on migrating between versions of your ZenPack.
See below for more details on providing modeler plugins in ZenPacks.
Database objects such as device classes and monitoring templates that are added to the ZenPack via the GUI
are exported to an objects.xml file in this directory. When the ZenPack is installed on another system those
objects will be copied into that object database.
This directory contains any command parsers provided by the ZenPack. See the section that discusses new
platform command parsers for more details.
This directory contains any report plugins provided by the ZenPack.
Zenoss daemons usually communicate with zenhub to retrieve their configuration, send events, and write
performance data. If a ZenPack provides a daemon then it typically will also provide a ZenHub service for that
daemon. See the section on ZenHub for further details.
This directory contains any skins directories that should be added to Zope. Note that this contains directories
of skins, not the skin files themselves. If you include skins directories make sure that the __init__.py file in
the directory above skins is registering this directory. (The default __init__.py file provided in new ZenPacks
does this for you.)
This directory contains files which describe the egg meta-data. This is created when the egg file is generated
or the ZenPack is installed from source. This directory can safely be deleted at any time if you wish and need
not be kept within any version control system.
This file is updated every time a ZenPack is edited and saved. ZenPack developers should normally not edit
this file manually.
20
ZenPacks
3.4. Developing the ZenPack
3.4.1. Base ZenPack Class
$ZENHOME/Products/ZenModel/ZenPack.py contains the base ZenPack class. When a ZenPack is installed Zenoss
inspects YourZenPackId/ZenPacks/..../LastPartOfName/__init__.py to see if it contains a class named ZenPack.
If it does then Zenoss instantiates it, otherwise Zenoss instantiates the base ZenModel.ZenPack.ZenPack class. That
instance is then added to the dmd.ZenPackManager.packs tree.
There are several attributes and methods of ZenPack that subclasses might be interested in overriding:
Interesting ZenPack properties and methods
packZProperties
is a mechanism for easily adding configuration properties. packZProperties is a
list of tuples, with each tuple containing three strings in this order:
•
name of the configuration property
•
default value of the configuration property
•
type of configuration property (such as string or int)
Zenoss will automatically create these when the ZenPack is installed and remove
them when the ZenPack is removed. See ZenPacks.zenoss.MySqlMonitor for an
example of this usage.
install(self, app)
parais called when the ZenPack is installed. If you override this be sure to call
the inherited method within your code.
remove(self, app, leaveObjects)
is called when the ZenPack is removed. As with install(), make sure you call
the inherited method if you override.
3.4.2. Storing Objects in the ZODB
ZenPacks can provide Python classes for objects that will be stored in the object database. The most frequent
example of this is DataSource subclasses. When a ZenPack is removed those classes are no longer accessible
so the objects in the database are broken. (Zeo needs to have the appropriate Python class in order to unpickle
an object from the database.) In previous versions of Zenoss there was not an easy way to associate instances
of a ZenPack-provided class with the ZenPack that provided the class. As a result ZenPack removal could easily
cause broken objects to remain in the database. If Zope had already loaded a class into the interpreter the objects in
question might continue to function until Zope was restarted, making diagnosis of such problems even more difficult.
In Zenoss 2.2 and later the ZenPackPersistance class aims to remedy this problem. Any Python class provided by a ZenPack should subclass the ZenModel.ZenPackPersistence.ZenPackPersistence class. Zenoss
maintains a catalog of all ZenPackPersistence instances in the database. When a ZenPack is removed,
the catalog is queried to determine which objects need to be deleted. Any ZenPack-provided Python class
that might be instantiated in the object database should subclass ZenPackPersistence and define ZENPACKID in the class as the name of the ZenPack providing the class. For an example of this see the
ZenPacks.zenoss.MySqlMonitor.datasources.MySqlMonitorDataSource ZenPack.
3.4.3. Providing DataSource classes
ZenPacks can provide new classes of DataSources by subclassing the ZenModel.RRDDataSource.RRDDataSource
class. If you include only one DataSource class per file, name the modules after the class the contain (for
example, MyDataSource.py contains the class MyDataSource), and place those modules in the ZenPack's data sources directory then they will automatically be discovered by Zenoss. If you want to customize this behavior take a look at the ZenPack.getDataSourceClasses() function. See the ZenPacks.zenoss.HttpMonitor and
ZenPacks.zenoss.MySqlMonitor ZenPacks for examples of ZenPacks that provide custom DataSource classes.
21
ZenPacks
When creating a custom DataSource class one of the first decisions you have to make is whether you want zencommand to process these DataSources for you or whether you will provide a custom collector daemon to process them.
The zencommand daemon is a very versatile mechanism for executing arbitrary commands either on the Zenoss
server or on the device being monitored, processing performance data returned by the DataSource and generating
events in Zenoss as appropriate. zencommand expects the command it executes be compatible with the Nagios
plug-in API. Specifically two aspects of that API are of most importance:
•
Return code -The command should exit with a return code of 0, 1, 2 or 3. See here in the Nagios plug-in API
for more detail.
•
Performance data -- If the command returns performance data then that data can be pulled into Zenoss by
creating DataPoints with the same names used in the command output. See here in the Nagios plug-in API
for more detail.
If you want zencommand to handle instances of your custom DataSource class then several methods in RRDDataSource are of particular interest:
•
getDescription(self) - This returns a string describing the DataSource instance. This string is displayed next to
the DataSource on the RRDTemplate view page.
•
getCommand(self, context, cmd=None) - This returns the string that is the command for zencommand to execute. context is the device or component to be collected. If you need to evaluate TALES expressions in the
command to replace things like ${dev/id} and so forth you can call the parent class's getCommand() and pass
your command as the cmd argument. (cmd will not be passed into your method, it exists specifically for subclasses to pass their commands to the parent for TALES evaluation.)
•
checkCommandPrefix(self, context, cmd) - Zenoss will check the string you return from getCommand() to see if it
is a relative or absolute path to a command. If the string starts with '/' or '$' then Zenoss assumes it is absolute.
Otherwise the configuration property zCommandPath from the context is prepended to the cmd string. You can
override checkCommandPrefix() if you want to alter this behavior.
Make sure that your DataSource subclasses also subclass ZenPackPersistence and list it first among the parent
classes. See the section on ZenPackPersistence.py for more details.
3.4.4. Monitoring Template Checklist
Monitoring templates are one of the easiest places to make a real user experience difference when new features
are added to Zenoss. Spending a very small amount of time to get the templates right goes a long way towards
improving the overall user experience.
3.4.4.1. Data Sources
•
•
Can your data source be named better?
•
Is it a common metric that is being collected from other devices in another way? If so, name yours the same.
This makes global reporting much easier.
•
camelCaseNames are the standard. Use them.
Never use absolute paths for COMMAND data source command templates. This will end up causing problems on
one of the three platforms we deal with. Link your plugin into zenPath('libexec') instead.
3.4.4.2. Data Points
•
•
Using a COUNTER? You might want to think otherwise.
•
Unnoticed counter rollovers can result in extremely skewed data.
•
Using a DERIVE with a minimum of 0 will record unknown instead of wrong data.
Enter the minimum and/or maximum possible values for the data point if you know them.
•
This again will allow unknown to be recorded instead of bad data.
22
ZenPacks
3.4.4.3. Thresholds
•
Don't include a number in your threshold's name.
•
This makes people have to recreate the threshold if they want to change it.
3.4.4.4. Graph Definitions
•
•
Have you entered the units? Do it!
•
This will become the y-axis label and should be all lowercase.
•
Always use the base units. Never kbps or MBs. bps or bytes are better.
Do you know the minimum/maximum allowable values? Enter them!
•
Common scenarios include percentage graphing with minimum 0 and maximum 100.
•
Think about the order of your graph points. Does it make sense?
•
Are there other templates that show similar data to yours? If so, you should try hard to mimic their appearance
to create a consistent experience.
3.4.4.5. Graph Points
•
Have you changed the legend? Do it!
•
Adjust the format so that it makes sense.
•
•
•
%5.2lf%s
is good for values you want RRDTool to auto-scale.
•
%6.2lf%%
is good for percentages.
•
%4.0lf
is good for four digit numbers with no decimal precision or scaling.
Should you be using areas or lines?
•
Lines are good for most values.
•
Areas are good for things that can be thought of as a volume or quantity.
Does stacking the values to present a visual aggregate make sense?
3.4.5. Providing Performance Collector Plugins
When providing performance collectors in a ZenPack (for example, Nagios-style plugins), the suggested method
for referencing the collector in the Command Template area is the following TALES expression:
${here/ZenPackManager/packs/ZenPacks.pkg.zpid/path}/libexec/myplugin.sh
3.4.6. Referencing Collector Plugins in ZenPacks
While modeler plugins are stored in the ZenPack's modeler/plugins directory, collector plugins are, by convention,
stored in the libexec directory. Because Zenoss can be installed in multiple ways, and a ZenPack's directory name,
when installed, includes a version number, Zenoss offers a more portable and "future-proof" way of referencing a
plugin.
In the Command Template section of the data source, you can reference a plugin by using a TALES expression,
such as:
${here/ZenPackManager .....}.../file.sh
For example:
${here/ZenPackManager .....}.../MyCollectorPlugin.sh ${dev/manageIp} ${dev/zSnmpCommunity} OtherParameters
23
ZenPacks
After adding the monitoring template containing the data source to a ZenPack, and then exporting the ZenPack, the
ZenPack's object/objects.xml file will contain an entry similar to:
${here/ZenPackManager .....}.../MyCollectorPlugin.sh ${dev/manageIp} ${dev/zSnmpCommunity} OtherParameters Settings > ZenPacks and selecting Create a ZenPack from the Action menu. This creates the ZenPack on the file system at $ZENHOME/ZenPacks/ZenPacks.community.YourZenPack and installs it into Zenoss. You may then proceed to add device classes,
templates, and MIBs to the ZenPack. (This is known as "development mode" for the ZenPack.) Once you are happy
with your ZenPack, you can export it for others to use. However, once you install a freshly exported .egg ZenPack
on another system (or uninstall and re-install your new ZenPack) you can no longer add things to the ZenPack.
3.6.1. Source ZenPacks
If you have the source for the ZenPack available you can simply attach to the source tree. Assuming that the source
directory is ZenPacks.community.YourZenPack, install the ZenPack with the following commands:
zenpack --link --install ZenPacks.community.YourZenPack
zopectl restart
Your ZenPack should now be usable and back in development mode. Changes made to the ZenPack will be persisted back to the source tree, you may still export and download as necessary. When you are satisfied with your
changes, you may commit them back to the Subversion repository.
3.6.2. Converting .egg Files to Development Mode
If you wish to convert an already installed ZenPack, or to install and convert an .egg ZenPack, follow these steps.
1.
Install the .egg as you would normally.
2.
Restart Zope with the command:
zopectl restart
25
ZenPacks
3.
Copy the ZenPack development files into the .egg's directory (the CONTENTS directory is unnecessary):
cp $ZENHOME/Products/ZenModel/ZenPackTemplate/* \
$ZENHOME/ZenPacks/ZenPacks.community.YourZenPack-1.0.2-py2.4.egg/
4.
You can now make any modifications to the ZenPack, such as updating the version number or adding new
device classes.
5.
Go into the ZenPack (from Advanced > Settings, select ZenPack from the left panel, and then click the ZenPack).
6.
Export the ZenPack (select Export ZenPack from the Action menu). The changes will be persisted to the new
.egg and the file system.
Note
There is a minor bug in the export and download functions. The new version saved in the export directory will
have the correct name with all the updates (for example, ZenPacks.community.YourZenPack-1.0.3-py2.4.egg).
If you choose to export and download the ZenPack, it will have the original name despite the updated version
(for example, ZenPacks.community.YourZenPack-1.0.2-py2.4.egg) or it may fail to download. Use the version in
the export directory.
3.7. Where to Get More Information
Discussion regarding development of ZenPacks takes place on the Zenoss Community forums, at:
http://community.zenoss.org/community/zenpacks
26
Chapter 4. Zenoss Data Stores
There are a few data stores used by Zenoss:
Data Stores
ZODB
Object-oriented database for Python objects
MySQL
The Event database where event information is stored.
Pickle files
Python pickle files are used to cache information otherwise obtained from zenhub.
RRD files
Round Robin Database that stores performance information.
Figure 4.1. Datastores Overview
4.1. Zope Object Database (ZODB)
The ZODB is an object-oriented database used by Zope to store Python objects and their states. For example,
modelers maintain information about devices and their configuration in the ZODB.
Zenoss uses ZEO, which is a layer between Zope and the ZODB. ZEO allows for multiple Zope servers to connect
to the same ZODB. The ZODB is started and stopped by zeoctl.
Note
ZODBs can be clustered using ZEO, but Zenoss Enterprise customers should contact Customer Support before
investigating clustering.
Here is a simple example of using transactions in the ZODB:
27
Zenoss Data Stores
...
import transaction
...
trans= transaction.get()
# Determine that bad things have happened
if bad_thing:
trans.abort()
# ... any other cleanup required inside the function eg 'return'
# Life is good!
# NB: Username or program name -- it's just a text field
trans.setUser( "zenmodeler" )
trans.note( "Added good things to xyz object" )
trans.commit()
The setUser() and note() functions are responsible for creating entries that can be found under the Modifications
tab or menu-item.
There are restrictions on what data can be stored, specifically data types that can be pickled. Basic Python data
types such as strings, numbers, lists and dictionaries can be pickled, but Python code objects cannot be pickled.
In addition, files and sockets cannot be pickled.
Note
The ZODB cannot detect changes to mutable types like lists and dictionaries. In order for changes to be detected,
not only is commit() afterwards, but you must explicitly tell the ZODB about the change by modifying a Persistent
objects _p_changed attribute.
# The following imports shouldn't be required in code
# as it should already be taken care of for you. These are
# included merely to explicitly show the class dependencies.
import ZODB
from Persistence import Persistent
import transaction
...
class myExampleClass( Persistent ):
"""
An example class to be used to demonstrate the use of the
modifying a list and then notifiying ZODB that work needs
to be done through the _p_changed attribute.
"""
def __init__(self):
"""
Initializer
"""
self.mylist= []
def addToMyList( self, listItem ):
"""
Track the listItems that we need
"""
self.mylist.append( listItem )
self._p_changed= True # Notify ZODB
transaction.commit()
As a general rule, use commit() whenever you want other processes to have access to your database changes. So
if a daemon is collecting and Zope needs to do something with the data, run commit() first from the daemon.
This should be enough information to get you started. See ZODB for Python Programmers for more details.
28
Zenoss Data Stores
4.2. MySQL Event database
MySQL is an open-source relational database that Zenoss uses to store events. Configuration information about
the MySQL database can be maintained by going to Events > Event Manager from the navigation bar when you
are logged in as a user with ZenManager privileges.
MySQL-level performance tweaking can substantially improve Zenoss' ability to handle events. One tool that can
be used to improve your database performance is MySQLTuner (http://blog.mysqltuner.com/).
If you need a connection to the MySQL events database, here is how to retrieve a connection and how to put it
back into the pool.
DbConnectionPool is hidden and is accessed through DbAccessBase. It follows the Singleton design pattern, so it'll only actually create one DbConnectionPool. It extends the Python class Queue, so DbConnectionPool is also a synchronized queue and should be thread-safe. DbAccessBase is extended by EventManagerBase>?, so if you have access to
the ZenEventManager (located at /zport/dmd/ZenEventManager) you'll have the ability to get a database connection.
4.2.1. Connecting to the Database
First you'll need to get an instance of ZenEventManager OR an instance of a class that extends DbAccessBase. Within
Zenoss, a ZenEventManager should already be instantiated.
Next is the try block which should include ANY database calls. This is where you'll get a connection from the pool
with the connect() method. You may pass this around to other methods or create a cursor and make some database
transactions. The try block MUST be completed with a finally block that includes the close() method. You MUST
pass the connection object to the close() method. This will ensure that even if the code within the try breaks, we
are not leaking database connections. If you create more than one connection (ie more than one connect() call in
your try block) you will need to have a corresponding close() call. There is ALWAYS a one-to-one relationship
between connect() and close() calls.
Here is a block of code that illustrates best practices for using the DbConnectionPool
...
zem = self.dmd.ZenEventManager
try:
conn1 = zem.connect()
conn2 = zem.connect()
curs1 = conn1.cursor()
...
curs2 = conn2.cursor()
...
# do work
...
curs3 = conn1.cursor()
...
finally:
zem.close(conn1)
zem.close(conn2)
...
...
Take a look at EventManagerBase.py for some examples of code using the DbConnectionPool.
4.2.2. MySQL in 60 Seconds
To start an interactive session with MySQL, run the mysql as the zenoss user. The following example is from a
default install of Zenoss where there is no password for the MySQL root user.
$ mysql -uroot
29
Zenoss Data Stores
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17799
Server version: 5.0.45 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
Once we've logged into MySQL, we can see the various databases and see the tables that are available. The events
database is maintained by Zenoss.
mysql> show databases;
+--------------------+
| Database
|
+--------------------+
| information_schema |
| events
|
| mysql
|
| test
|
+--------------------+
4 rows in set (0.03 sec)
mysql> use events;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------+
| Tables_in_events |
+------------------+
| alert_state
|
| detail
|
| heartbeat
|
| history
|
| log
|
| status
|
+------------------+
6 rows in set (0.00 sec)
From here we can determine what information is in what table. For instance, the log table.
mysql> describe log;
+----------+-------------+------+-----+-------------------+-------+
| Field
| Type
| Null | Key | Default
| Extra |
+----------+-------------+------+-----+-------------------+-------+
| evid
| char(25)
| NO
| MUL |
|
|
| userName | varchar(64) | YES |
| NULL
|
|
| ctime
| timestamp
| NO
|
| CURRENT_TIMESTAMP |
|
| text
| text
| YES |
| NULL
|
|
+----------+-------------+------+-----+-------------------+-------+
4 rows in set (0.00 sec)
4.3. Python Pickle Files
Python's native storage for storing data is called a Pickle. Pickle files are used by zenperfsnmp for caching configuration information gathered from zenhub. This is a performance enhancement for dealing with startup communications
with zenhub, as larger sites with hundreds or more devices could experience enough of a delay during initialization
that Zenoss would have difficulty functioning until the configuration information had been gathered. Every update
from the Zenoss server (which is dealt with by zenhub) causes zenperfsnmp to update the pickle files.
The pickle files are kept in the $ZENHOME/perf/Devices/devicename/ directory, and are named collectorconfig.pickle. These pickle files are only read during startup and are periodically recreated, so it is safe to delete
them, and it is not necessary to back them up.
30
Zenoss Data Stores
4.4. Round-Robin Database
RRD is used by Zenoss to store and graph performance collection data. These data files have a fixed format that
is decided at their creation time, and record data points at set intervals. This data is later consolidated into coarser
time units (so as to reduce the total size of data files) and the RRD toolset also contains code to create graphs.
A few other interesting facts:
•
Zenoss is a gold-level sponsor of RRD.
•
The Renderserver sends RRD graphics to Web browsers.
31
Zenoss Data Stores
Figure 4.2. RRD Overview
32
Chapter 5. Events
5.1. Understanding an Event Entry
From a Python programming perspective, an event is essentially a dictionary of keyword/value pairs that gets passed
up to zenhub to be stored and parsed. A description of the standard fields used in Zenoss can be found in the
section titled Event Database Dictionary.
From the user's perspective, the events can be found in the event console. To view an event's information, double-click it in the list of events. The standard keyword and value pairs are presented to the user in the Details area.
5.1.1. Event Design
There are a few requirements for events:
•
Event objects need to be persisted in the MySQL database.
•
On queries from within Zope these queries must use the Zope security mechanisms to allow controlled access
to the data.
•
Events must be constructed outside of a Zope framework as well.
To meet these requirements there are three types of event:
Event
an event that lives outside of a Zope context and can go in and out of MySQL.
ZEvent
event in a Zope context inherits from Event and has a subset of its fields populated as defined
by resultFields in a getEventList() query.
ZEventDetail
full event information (all fields, detail, and log)
5.2. Sending an Event
Events can be created through a number of different ways:
•
From the command line (zensendevent)
•
Through the user interface (Add Event)
•
By daemons, which convert their messages into events (such as zentrap)
•
From daemons and programs that have detected error conditions
•
From an external source (using, for example, XML-RPC)
Regardless of what program generates the event, or from which protocol the event is sent to Zenoss, the following
fields (at a minimum) should be specified:
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. Note that for
Python code, that mappings to names are provided (see example below).
Here is an example using Python from within a program that connects to zenhub:
# Import severities (eg Clear, Debug, Info, Warning, Error Critical) and
33
Events
# some event classes into our namespace
from Products.ZenEvents.ZenEventClasses import *
class exampleClass(PBDaemon):
def examplefunc( self ):
event= {}
event[ 'component' ]= 'eth0'
event[ 'severity' ]= Warning
event[ 'summary' ]= 'eth0 is down'
event[ 'message' ]= 'Received error code 0xa7 from listen()'
self.sendEvent( event, device='mydevice' )
Using XML-RPC in Python:
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)
Tip
Some suggested non-standard fields for adding to your event are:
resolution
Describe a method of fixing the situation that might have caused the event, or suggest a course
of action for diagnosing the condition.
explanation
Describe in more detail the impact of this event on the computing environment. For instance,
does the condition which generates this event prevent a service from starting or being monitored?
5.3. Adding an Event Class
Event classes can be added easily through the UI. If you need to use an event class internally, however, you need
to make sure that class will always be available, which involves several more steps.
5.3.1. Add to ZenEventClasses
Add a definition of the name of your new event class to Products/ZenEvents/ZenEventClasses:
...
My_New_Class = "/My/New/Class"
Now your event class is centralized and can be imported wherever you need to use it, e.g.:
...
from Products.ZenEvents.ZenEventClasses import My_New_Class
...
if thing.evclass == My_New_Class:
...
5.3.2. Add the class to the import XML
Several event classes are imported from XML by zenload just after the ZODB is created. To include your new event
class in this import, add an