Skip to content

Commit

Permalink
Bugfixes and better error handling on zabbix alerter.
Browse files Browse the repository at this point in the history
  • Loading branch information
NSDDataDope committed Feb 6, 2020
1 parent ec5d03b commit 2864bbb
Showing 1 changed file with 40 additions and 20 deletions.
60 changes: 40 additions & 20 deletions elastalert/zabbix.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
from alerts import Alerter # , BasicMatchString
import logging
from pyzabbix.api import ZabbixAPI
from pyzabbix import ZabbixSender, ZabbixMetric
from datetime import datetime

from pyzabbix import ZabbixSender, ZabbixMetric, ZabbixAPI

from .alerts import Alerter
from .util import elastalert_logger, EAException


class ZabbixClient(ZabbixAPI):

def __init__(self, url='http://localhost', use_authenticate=False, user='Admin', password='zabbix', sender_host='localhost',
sender_port=10051):
def __init__(self, url='http://localhost', use_authenticate=False, user='Admin', password='zabbix',
sender_host='localhost', sender_port=10051):
self.url = url
self.use_authenticate = use_authenticate
self.sender_host = sender_host
self.sender_port = sender_port
self.metrics_chunk_size = 200
self.aggregated_metrics = []
self.logger = logging.getLogger(self.__class__.__name__)
super(ZabbixClient, self).__init__(url=self.url, use_authenticate=self.use_authenticate, user=user, password=password)

super(ZabbixClient, self).__init__(url=self.url,
use_authenticate=self.use_authenticate,
user=user,
password=password)

def send_metric(self, hostname, key, data):
zm = ZabbixMetric(hostname, key, data)
if self.send_aggregated_metrics:

self.aggregated_metrics.append(zm)
if len(self.aggregated_metrics) > self.metrics_chunk_size:
self.logger.info("Sending: %s metrics" % (len(self.aggregated_metrics)))
elastalert_logger.info("Sending: %s metrics" % (len(self.aggregated_metrics)))
try:
ZabbixSender(zabbix_server=self.sender_host, zabbix_port=self.sender_port).send(self.aggregated_metrics)
ZabbixSender(zabbix_server=self.sender_host, zabbix_port=self.sender_port) \
.send(self.aggregated_metrics)
self.aggregated_metrics = []
except Exception as e:
self.logger.exception(e)
pass
elastalert_logger.exception(e)
else:
try:
ZabbixSender(zabbix_server=self.sender_host, zabbix_port=self.sender_port).send(zm)
ZabbixSender(zabbix_server=self.sender_host, zabbix_port=self.sender_port).send([zm])
except Exception as e:
self.logger.exception(e)
pass
elastalert_logger.exception(e)


class ZabbixAlerter(Alerter):

# By setting required_options to a set of strings
# You can ensure that the rule config file specifies all
# of the options. Otherwise, ElastAlert will throw an exception
Expand All @@ -54,6 +55,9 @@ def __init__(self, *args):
self.zbx_sender_port = self.rule.get('zbx_sender_port', 10051)
self.zbx_host = self.rule.get('zbx_host')
self.zbx_key = self.rule.get('zbx_key')
self.timestamp_field = self.rule.get('timestamp_field', '@timestamp')
self.timestamp_type = self.rule.get('timestamp_type', 'iso')
self.timestamp_strptime = self.rule.get('timestamp_strptime', '%Y-%m-%dT%H:%M:%S.%fZ')

# Alert is called
def alert(self, matches):
Expand All @@ -63,10 +67,26 @@ def alert(self, matches):
# the aggregation option set
zm = []
for match in matches:
ts_epoch = int(datetime.strptime(match['@timestamp'], "%Y-%m-%dT%H:%M:%S.%fZ").strftime('%s'))
zm.append(ZabbixMetric(host=self.zbx_host, key=self.zbx_key, value=1, clock=ts_epoch))
if ':' not in match[self.timestamp_field] or '-' not in match[self.timestamp_field]:
ts_epoch = int(match[self.timestamp_field])
else:
try:
ts_epoch = int(datetime.strptime(match[self.timestamp_field], self.timestamp_strptime)
.strftime('%s'))
except ValueError:
ts_epoch = int(datetime.strptime(match[self.timestamp_field], '%Y-%m-%dT%H:%M:%SZ')
.strftime('%s'))
zm.append(ZabbixMetric(host=self.zbx_host, key=self.zbx_key, value='1', clock=ts_epoch))

ZabbixSender(zabbix_server=self.zbx_sender_host, zabbix_port=self.zbx_sender_port).send(zm)
try:
response = ZabbixSender(zabbix_server=self.zbx_sender_host, zabbix_port=self.zbx_sender_port).send(zm)
if response.failed:
elastalert_logger.warning("Missing zabbix host '%s' or host's item '%s', alert will be discarded"
% (self.zbx_host, self.zbx_key))
else:
elastalert_logger.info("Alert sent to Zabbix")
except Exception as e:
raise EAException("Error sending alert to Zabbix: %s" % e)

# get_info is called after an alert is sent to get data that is written back
# to Elasticsearch in the field "alert_info"
Expand Down

0 comments on commit 2864bbb

Please sign in to comment.