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

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

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