Package ZenEvents :: Module SyslogProcessing
[hide private]
[frames] | no frames]

Source Code for Module ZenEvents.SyslogProcessing

  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 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13  #! /usr/bin/env python  
 14   
 15  __doc__='''SyslogProcessing 
 16   
 17  Class for turning syslog events into Zenoss Events 
 18   
 19  $Id$ 
 20  ''' 
 21   
 22  __version__ = "$Revision$"[11:-2] 
 23   
 24   
 25  import re 
 26  import logging 
 27  slog = logging.getLogger("zen.Syslog") 
 28   
 29  import Globals 
 30  from Event import Event 
 31  from Exceptions import ZenBackendFailure 
 32  from syslog_h import * 
 33   
 34  # Regular expressions that parse syslog tags from different sources 
 35  parsers = ( 
 36       
 37  # ntsyslog windows msg 
 38  r"^(?P<component>.+)\[(?P<ntseverity>\D+)\] (?P<ntevid>\d+) (?P<summary>.*)", 
 39   
 40  # cisco msg with card inicator 
 41  r"%CARD-\S+:(SLOT\d+) %(?P<eventClassKey>\S+): (?P<summary>.*)", 
 42   
 43  # cisco standard msg 
 44  r"%(?P<eventClassKey>(?P<component>\S+)-\d-\S+): (?P<summary>.*)", 
 45   
 46  # unix syslog with pid 
 47  r"(?P<component>\S+)\[(?P<pid>\d+)\]: (?P<summary>.*)", 
 48   
 49  # unix syslog without pid 
 50  r"(?P<component>\S+): (?P<summary>.*)", 
 51   
 52  # adtran devices 
 53  r"^(?P<deviceModel>[^\[]+)\[(?P<deviceManufacturer>ADTRAN)\]:(?P<component>[^\|]+\|\d+\|\d+)\|(?P<summary>.*)" 
 54  )  
 55   
 56  # compile regex parsers on load 
 57  compiledParsers = [] 
 58  for regex in parsers: 
 59      compiledParsers.append(re.compile(regex))  
 60   
 61   
62 -class SyslogEvent(Event):
63
64 - def getDedupFields(self, default):
65 """Return list of dedupid fields. 66 """ 67 default = list(default[:]) 68 if not getattr(self, "eventKey", False): 69 default.append("summary") 70 return default
71 72
73 -class SyslogProcessor(object):
74
75 - def __init__(self, zem, minpriority, parsehost):
76 self.minpriority = minpriority 77 self.parsehost = parsehost 78 self.zem = zem
79 80
81 - def process(self, msg, ipaddr, host, rtime):
82 evt = SyslogEvent(device=host, ipAddress=ipaddr, rcvtime=rtime, 83 agent='zensyslog', eventGroup='syslog') 84 slog.debug("host=%s, ip=%s", host, ipaddr) 85 slog.debug(msg) 86 87 evt, msg = self.parsePRI(evt, msg) 88 if evt.priority > self.minpriority: return 89 90 evt, msg = self.parseHEADER(evt, msg) 91 evt = self.parseTag(evt, msg) 92 #rest of msg now in summary of event 93 evt = self.buildEventClassKey(evt) 94 self.zem.sendEvent(evt)
95 96
97 - def parsePRI(self, evt, msg):
98 """ 99 Parse RFC-3164 PRI part of syslog message to get facility and priority. 100 """ 101 pri = self.zem.defaultPriority 102 fac = None 103 if msg[:1] == '<': 104 pos = msg.find('>') 105 fac, pri = LOG_UNPACK(int(msg[1:pos])) 106 msg = msg[pos+1:] 107 elif msg and msg[0] < ' ': 108 fac, pri = LOG_KERN, ord(msg[0]) 109 msg = msg[1:] 110 evt.facility = fac_names.get(fac,"unknown") 111 evt.priority = pri 112 evt.severity = self.defaultSeverityMap(pri) 113 slog.debug("fac=%s pri=%s", fac, pri) 114 slog.debug("facility=%s severity=%s", evt.facility, evt.severity) 115 return evt, msg
116 117
118 - def defaultSeverityMap(self, pri):
119 """Default mapping from syslog priority to severity. 120 """ 121 sev = 1 122 if pri < 3: sev = 5 123 elif pri == 3: sev = 4 124 elif pri == 4: sev = 3 125 elif 7 < pri > 4: sev = 2 126 return sev
127 128 129 timeParse = \ 130 re.compile("^(\S{3} [\d ]{2} [\d ]{2}:[\d ]{2}:[\d ]{2}) (.*)").search 131 notHostSearch = re.compile("[-\[:]").search
132 - def parseHEADER(self, evt, msg):
133 """Parse RFC-3164 HEADER part of syslog message. TIMESTAMP format is: 134 MMM HH:MM:SS and host is next token without the characters '[' or ':'. 135 """ 136 slog.debug(msg) 137 m = self.timeParse(msg) 138 if m: 139 slog.debug("parseHEADER timestamp=%s", m.group(1)) 140 #FIXME date parsing in event not working 141 #evt.initTime(m.group(1)) 142 evt.originalTime = m.group(1) 143 msg = m.group(2).strip() 144 msglist = msg.split() 145 if self.parsehost and not self.notHostSearch(msglist[0]): 146 evt.device = msglist[0] 147 slog.debug("parseHEADER hostname=%s", evt.device) 148 msg = " ".join(msglist[1:]) 149 return evt, msg
150 151
152 - def parseTag(self, evt, msg):
153 """Parse the RFC-3164 tag of the syslog message using the regex defined 154 at the top of this module. 155 """ 156 slog.debug(msg) 157 for regex in compiledParsers: 158 slog.debug("tag regex: %s", regex.pattern) 159 m = regex.search(msg) 160 if not m: continue 161 slog.debug("tag match: %s", m.groupdict()) 162 evt.updateFromDict(m.groupdict()) 163 break 164 else: 165 slog.warn("parseTag failed:'%s'", msg) 166 evt.summary = msg 167 return evt
168 169
170 - def buildEventClassKey(self, evt):
171 """Build the key used to find an events dictionary record. If eventClass 172 is defined it is used. For NT events "Source_Evid" is used. For other 173 syslog events we use the summary of the event to perform a full text 174 or'ed search. 175 """ 176 if hasattr(evt, 'eventClassKey') or hasattr(evt, 'eventClass'): 177 return evt 178 elif hasattr(evt, 'ntevid'): 179 evt.eventClassKey = "%s_%s" % (evt.component,evt.ntevid) 180 elif hasattr(evt, 'component'): 181 evt.eventClassKey = evt.component 182 if hasattr(evt, 'eventClassKey'): 183 slog.debug("eventClassKey=%s", evt.eventClassKey) 184 try: 185 evt.eventClassKey = evt.eventClassKey.decode('latin-1') 186 except: 187 evt.eventClassKey = evt.eventClassKey.decode('utf-8') 188 else: 189 slog.debug("no eventClassKey assigned") 190 return evt
191