Skip to content

Commit

Permalink
Merge pull request #4608 from zenoss/bugfix/ZEN-35141.7x
Browse files Browse the repository at this point in the history
Clean up SNMP event handling.
  • Loading branch information
jpeacock-zenoss authored Nov 11, 2024
2 parents da9b679 + 064ff45 commit 718ed69
Showing 1 changed file with 51 additions and 50 deletions.
101 changes: 51 additions & 50 deletions Products/ZenRRD/zenprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from pprint import pformat

import six
import zope.component
import zope.interface

Expand Down Expand Up @@ -59,7 +60,9 @@

unused(DeviceProxy, ProcessProxy, SnmpConnInfo)

log = logging.getLogger("zen.zenprocess")
COLLECTOR_NAME = "zenprocess"

log = logging.getLogger("zen.{}".format(COLLECTOR_NAME))

# HOST-RESOURCES-MIB OIDs used
HOSTROOT = ".1.3.6.1.2.1.25"
Expand All @@ -76,6 +79,12 @@

PROC_SCAN_ERROR = "Unable to read processes on device %s"

RESOURCE_MIB = "resource_mib"
SNMP_CONFIG_ERROR = "snmp_config_error"
TABLE_SCAN_TIMEOUT = "table_scan_timeout"
TABLE_SCAN_V3_ERROR = "table_scan_v3_error"
PROCESS_STATUS = "process_status"


class HostResourceMIBException(Exception):
pass
Expand All @@ -91,7 +100,7 @@ def __init__(self):
Constructs a new ZenProcessPreferences instance and provide default
values for needed attributes.
"""
self.collectorName = "zenprocess"
self.collectorName = COLLECTOR_NAME
self.configCycleInterval = 20 # minutes

# will be updated based on Performance Config property of same name
Expand Down Expand Up @@ -361,7 +370,13 @@ def __init__(
self._dataService = zope.component.queryUtility(IDataService)
self._eventService = zope.component.queryUtility(IEventService)
self._preferences = zope.component.queryUtility(
ICollectorPreferences, "zenprocess"
ICollectorPreferences, COLLECTOR_NAME
)
self._snmpStatusEvent = dict(
self.statusEvent,
agent=COLLECTOR_NAME,
device=self._devId,
eventClass=Status_Snmp,
)
self.snmpProxy = None
self.snmpConnInfo = self._device.snmpConnInfo
Expand All @@ -387,15 +402,12 @@ def doTask(self):
try:
self.openProxy()
self._clearSnmpError(
"SNMP config error cleared",
eventKey="snmp_config_error",
severity=Event.Clear,
"SNMP config error cleared", SNMP_CONFIG_ERROR
)
except Exception as ex:
log.error("failed to create SNMP session: %s", ex)
self._sendSnmpError(
"SNMP config error: {}".format(ex),
eventKey="snmp_config_error",
"SNMP config error: {}".format(ex), SNMP_CONFIG_ERROR
)
else:
log.debug(
Expand All @@ -421,26 +433,26 @@ def _collectCallback(self):
tableResult = yield self._getTables(tables)
summary = "Process table up for device %s" % self._devId
self._clearSnmpError(
"%s - timeout cleared" % summary, "table_scan_timeout"
"%s - timeout cleared" % summary, TABLE_SCAN_TIMEOUT
)
if self.snmpConnInfo.zSnmpVer == "v3":
self._clearSnmpError(
"%s - v3 error cleared" % summary, "table_scan_v3_error"
"%s - v3 error cleared" % summary, TABLE_SCAN_V3_ERROR
)

processes = self._parseProcessNames(tableResult)
self._clearSnmpError(summary, "resource_mib")
self._clearSnmpError(summary, RESOURCE_MIB)
self._deviceStats.update(self._device)
processStatuses = self._determineProcessStatus(processes)
self._sendProcessEvents(processStatuses)
self._clearSnmpError(summary)
self._clearSnmpError(summary, PROCESS_STATUS)
yield self._fetchPerf()
log.debug(
"Device %s [%s] scanned successfully",
self._devId,
self._manageIp,
)
except HostResourceMIBException as e:
except HostResourceMIBException:
summary = (
"Device %s does not publish HOST-RESOURCES-MIB" % self._devId
)
Expand All @@ -449,13 +461,12 @@ def _collectCallback(self):
NAMETABLE,
)
log.warn(summary)
self._sendSnmpError(summary, "resource_mib", resolution=resolution)

except error.TimeoutError as e:
self._sendSnmpError(summary, RESOURCE_MIB, resolution=resolution)
except error.TimeoutError:
log.debug("Timeout fetching tables on device %s", self._devId)
self._sendSnmpError(
"%s; Timeout on device" % PROC_SCAN_ERROR % self._devId,
"table_scan_timeout",
"%s; Timeout on device" % (PROC_SCAN_ERROR % self._devId,),
TABLE_SCAN_TIMEOUT,
)
except Snmpv3Error as e:
msg = (
Expand All @@ -466,12 +477,12 @@ def _collectCallback(self):
log.debug(msg)
self._sendSnmpError(
"%s; %s" % (PROC_SCAN_ERROR % self._devId, msg),
"table_scan_v3_error",
TABLE_SCAN_V3_ERROR,
)
except Exception as e:
log.exception("Unexpected Error on device %s", self._devId)
msg = "%s; error: %s" % (PROC_SCAN_ERROR % self._devId, e)
self._sendSnmpError(msg)
self._sendSnmpError(msg, PROCESS_STATUS)

def _finished(self):
"""
Expand Down Expand Up @@ -879,33 +890,25 @@ def _showProcessList(self, procs):
"#===== Processes on %s:\n%s", device_name, "\n".join(proc_list)
)

def _sendSnmpError(self, message, eventKey=None, **kwargs):
event = self.statusEvent.copy()
def _sendSnmpError(self, message, eventKey, **kwargs):
event = self._snmpStatusEvent.copy()
event.update(kwargs)
self._eventService.sendEvent(
event,
eventClass=Status_Snmp,
device=self._devId,
severity=Event.Error,
eventKey=eventKey,
summary=message,
event, eventKey=eventKey, severity=Event.Error, summary=message
)

def _clearSnmpError(self, message, eventKey=None):
def _clearSnmpError(self, message, eventKey):
"""
Send an event to clear other events.
@parameter message: clear text
@type message: string
"""
self._eventService.sendEvent(
self.statusEvent,
eventClass=Status_Snmp,
device=self._devId,
summary=message,
agent="zenprocess",
self._snmpStatusEvent,
eventKey=eventKey,
severity=Event.Clear,
summary=message,
)

def _save(self, pidName, statName, value, rrdType, min="U"):
Expand Down Expand Up @@ -946,22 +949,20 @@ def _save(self, pidName, statName, value, rrdType, min="U"):
trace_info = traceback.format_exc()

self._eventService.sendEvent(
dict(
dedupid="%s|%s"
% (
self._preferences.options.monitor,
"Metric write failure",
{
"dedupid": "{0.options.monitor}|{1}".format(
self._preferences, "Metric write failure"
),
severity=Event.Critical,
device=self._preferences.options.monitor,
eventClass=Status_Perf,
component="METRIC",
pidName=pidName,
statName=statName,
message=message,
traceback=trace_info,
summary=summary,
)
"severity": Event.Critical,
"device": self._preferences.options.monitor,
"eventClass": Status_Perf,
"component": "METRIC",
"pidName": pidName,
"statName": statName,
"message": message,
"traceback": trace_info,
"summary": summary,
}
)


Expand Down Expand Up @@ -1006,7 +1007,7 @@ def extract(dictionary, oid, value):
path = paths.get(pid, "")
if path and path.find("\\") == -1:
name = path
arg = unicode(args.get(pid, ""), errors="replace")
arg = six.text_type(args.get(pid, ""), errors="replace")
procs.append((pid, (name + " " + arg).strip()))

return procs
Expand Down

0 comments on commit 718ed69

Please sign in to comment.