Package Products :: Package ZenEvents :: Package browser :: Module EventPillsAndSummaries |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenEvents.browser.EventPillsAndSummaries

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  import re
     12
     13  from Products.Five.browser import BrowserView
     14  from Products.ZenUtils.jsonutils import json
     15  from Products.ZenModel.DeviceOrganizer import DeviceOrganizer
     16
     17 -class SinglePill(BrowserView):
     18 -    def __call__(self):
     19          """
     20          Gets event pill for worst severity.
     21
     22          @return: HTML that will render the event pill.
     23          @rtype: str
     24          """
     25          pill = getEventPillME(self.context)
     26          if isinstance(pill, (list, tuple)) and len(pill)==1: return pill[0]
     27          return pill
     28
     29
     30 -class ObjectsEventSummary(BrowserView):
     31      """
     32      Return an HTML link and event pill for each object passed as a JSON
     33      object ready for inclusion in a YUI data table.
     34
     35      @param objects: The objects for which to create links and pills.
     36      @type objects: list
     37      @return: A JSON-formatted string representation of the columns and rows
     38          of the table
     39      @rtype: string
     40      """
     41      @json
     42 -    def __call__(self):
     43          zem = self.context.dmd.ZenEventManager
     44          obs = self._getObs()
     45          return getDashboardObjectsEventSummary(zem, obs)
     46
     47 -    def _getObs(self):
     48          raise NotImplementedError
     49
     50
     51 -class SubOrganizersEventSummary(ObjectsEventSummary):
     52 -    def _getObs(self):
     53          return self.context.children()
     54
     55
     56 -class SubDevicesEventSummary(ObjectsEventSummary):
     57 -    def _getObs(self):
     58          return self.context.devices()
     59
     60
     61 -class SingleObjectEventSummary(ObjectsEventSummary):
     62 -    def _getObs(self):
     63          return [self]
     64
     65
     66 -def _getPillSortKey(pill,
     67      _severities = ('critical', 'error', 'warning'),
     68      _getseverity = re.compile(r'<td class="severity-icon-small\s+(' +
     69                                r'critical|error|warning' +
     70                                r') "\s+title="(\d+) out of (\d+) acknowledged">',
     71                             re.S|re.I|re.M).search
     72      ):
     73      """
     74      Internal method for converting pill class to an integer severity sort key.
     75      Use default arguments _getseverity and _severities to store runtime constants.
     76      """
     77      try:
     78          reMatch = _getseverity(pill.lower())
     79          if reMatch:
     80              sev, numacked, numtotal = reMatch.group(1, 2, 3)
     81              index = _severities.index(sev)
     82              index += 0.5 if numacked != '0' else 0
     83              return (index, -int(numtotal))
     84      except Exception:
     85          pass
     86
     87      return (5,0)
     88
     89 -def getObjectsEventSummary(zem, objects, prodState=None, REQUEST=None):
     90      """
     91      Return an HTML link and event pill for each object passed as a JSON
     92      object ready for inclusion in a YUI data table.
     93
     94      @param objects: The objects for which to create links and pills.
     95      @type objects: list
     96      @return: dict containing 'columns' and 'data' entries
     97      @rtype: dict
     98      """
     99      ret = {'columns':['Object', 'Events'], 'data':[]}
    100
    101      # build list of device-pill-pillsortkey tuples
    102      devdata = []
    103      for obj in objects:
    104          alink = obj.getPrettyLink()
    105          pill = getEventPillME(obj, showGreen=True, prodState=prodState)
    106          if isinstance(pill, (list, tuple)): pill = pill[0]
    107          devdata.append((alink, pill, _getPillSortKey(pill)))
    108      devdata.sort(key=lambda x:x[-1])
    109
    110      # save object-pill data to return dict
    111      ret['data'] = [{'Object':x[0],'Events':x[1]} for x in devdata]
    112
    113      return ret
    114
    115
    116 -def getDashboardObjectsEventSummary(zem, objects, REQUEST=None):
    117      """
    118      Event summary that takes dashboard production state threshold into account.
    119      """
    120      thold = zem.dmd.prodStateDashboardThresh
    121      return getObjectsEventSummary(zem, objects, thold, REQUEST)
    122
    123
    124 -def _getPill(summary, url=None, number=3):
    125      iconTemplate = """
    126          <td class="severity-icon-small
    127              %(severity)s %(cssclass)s"
    128              title="%(acked)s out of %(total)s acknowledged">
    129              %(total)s
    130          </td>
    131      """
    132      rainbowTemplate = """
    133      <table onclick="location.href='%(url)s';"
    134          class="eventrainbow eventrainbow_cols_%(number)s">
    135          <tr>%(cells)s</tr>
    136      </table>
    137      """
    138      stati = ('critical','error','warning','info','debug')
    139      summary = [summary[x] for x in stati]
    140
    141      cells = []
    142      for i, counts in enumerate(summary[:number]):
    143          total = counts['count']
    144          acked = counts['acknowledged_count']
    145          cssclass = 'no-events' if not total else 'acked-events' if total==acked else ''
    146          cells.append(iconTemplate % {
    147              'cssclass': cssclass,
    148              'severity': stati[i],
    149              'total': total,
    150              'acked': acked
    151          })
    152      return rainbowTemplate % {
    153          'url': url,
    154          'cells': ''.join(cells),
    155          'number': number
    156      }
    157
    158 -def getEventPillME(me, number=3, minSeverity=0, showGreen=True,
    159                     prodState=None, severities=None):
    160      """
    161      Get HTML code displaying the maximum event severity and the number of
    162      events of that severity on a particular L{ManagedEntity} in a pleasing
    163      pill-shaped container. Optionally return pills for lesser severities as
    164      well. Optionally return a green pill if there are no events (normally no
    165      events in a severity will not yield a result).
    166
    167      @param me: The object regarding which event data should be queried.
    168      @type me: L{ManagedEntity}
    169      @param number: The number of pills to return
    170      @type number: int
    171      @param showGreen: Whether to return an empty green pill if all is well
    172      @type showGreen: bool
    173      @return: HTML strings ready for template inclusion
    174      @rtype: list
    175      @param severities: The severity counts that you can pass in if
    176      you do not want the getEventSeveritiesCount to be called. This is useful
    177      for batch pills queries
    178      @param type: dictionary
    179      """
    180      url = getEventsURL(me)
    181      sevs = severities
    182      if not severities:
    183          sevs = me.getEventSeveritiesCount()
    184      return _getPill(sevs, url, number)
    185
    186
    187  organizerTypes = {
    188      'Devices': 'devices',
    189      'Groups': 'groups',
    190      'Locations': 'locs',
    191      'Systems': 'systems'
    192  }
    193
    194
    195 -def getEventsURL(me) :
    196      from Products.ZenModel.Device import Device
    197      if isinstance(me, DeviceOrganizer) :
    198          path = me.getPrimaryPath()
    199          url = ('/zport/dmd/itinfrastructure?filter=default#'
    200                 '%s:%s:events_grid' % (
    201                     organizerTypes[path[3]], '.'.join(path)))
    202      elif isinstance(me, Device) :
    203          url = (me.getPrimaryUrlPath() +
    204                 '/devicedetail?filter=default#'
    205                 'deviceDetailNav:device_events')
    206      else:
    207          url = me.getPrimaryUrlPath()+'/viewEvents?filter=default'
    208      return url
    209