Reportables: Modify what is Reported

Reportables allow you to control what data Analytis will extract from your zenpack. To invoke reportables you need to create a reportable.py in your zenpack toplevel directory. You can an example of this in:

  • ZenPacks.zenoss.OpenStackInfrastructure

Things to consider about Reportables:

  1. Reportables are reporting on properties that come from metric data, which bogs down zenmodeletl: Sometimes this is unavoidable, but sometimes the property isn’t really that important, or worth the extra load on zenmodeletl, so it can be removed to save load.
  2. Datasource configs are using information from metric data, which bogs down zenperfetl: This is much more likely to be something that is a bug in the zenpack in question, as such values probably are not being propagated to the collector properly anyway, since there would be no invalidations associated with them changing- it is most, at best, a waste of time, and at worst, a bug that will bite us in subtle ways later.

Setup

Reportables are configured by creating a reportable.py which inherits from either:

  • ZenPacks.zenoss.ZenETL.reportable.Reportable
  • ZenPacks.zenoss.ZenETL.reportable.BaseReportable

In addition you will probably need to import a Factory from:

  • ZenPacks.zenoss.ZenETL.reportable.BaseReportableFactory

Once you have defined a reportable class for your device or component, you will need to register it in configure.zcml or your equivalent.

Note

Many ZenPacks have a basereportable.py that defines a normalized set of properties. This basereportable is then imported into reportable.py. The purpose of this is to create a simpler reportable.py and provide a more appropriate default set of reportables.

Examples

Below is a simple self-contained example which modifies a PortChannel: Note the following:

  1. entity_class_name must be defined for each property you modify and it must be less than 28 characters long. Exceeding this created dimension (dim_*) table names that cause problems in Analytics.
  2. reportProperties() is the main class method that provides the change.
import logging
log = logging.getLogger("zen.CiscoMonitor.etl")

from zope.interface import implements
from zope.component import adapts
from ZenPacks.zenoss.CiscoMonitor.PortChannel import PortChannel


from Products.Zuul.interfaces import (
   IReportable
)

from ZenPacks.zenoss.ZenETL.reportable import (
   MARKER_LENGTH,
   BaseReportableFactory,
   IpInterfaceReportable,
   Reportable
)


class CiscoMonitorBaseRelReportable(Reportable):
   implements(IReportable)

   def __init__(self, fromObject, toObject):
      super(CiscoMonitorBaseRelReportable, self).__init__()
      self.fromObject = fromObject
      self.toObject = toObject

   @property
   def id(self):
      return "%s__%s" % (self.fromObject.id, self.toObject.id)

   @property
   def uid(self):
      return "%s__%s" % (self.fromObject.uid, self.toObject.uid)

   @property
   def sid(self):
      return "%s__%s" % (IReportable(self.fromObject).sid, IReportable(self.toObject).sid)


class PortChannelReportableFactory(BaseReportableFactory):
   adapts(PortChannel)

   def exports(self):
      # The interface as Interface
      yield IpInterfaceReportable(self.context)

      for child in self.context.member_interfaces():
            yield PortChannelToMemberInterfaceReportable(self.context, child)


class PortChannelToMemberInterfaceReportable(CiscoMonitorBaseRelReportable):
   @property
   def entity_class_name(self):
      return 'cisco_portchannel_interfaces'

   def reportProperties(self):
      return [
            ('portchannel_ip_interface_key', 'reference', IReportable(self.fromObject).sid, MARKER_LENGTH),
            ('ip_interface_key', 'reference', IReportable(self.toObject).sid, MARKER_LENGTH),
      ]

This is the associated ZCML entry:

<configure zcml:condition="installed ZenPacks.zenoss.ZenETL">

  <adapter provides="Products.Zuul.interfaces.IReportableFactory"
    for=".PortChannel.PortChannel"
    factory=".reportable.PortChannelReportableFactory"
    />

</configure>