Advertisement
syntax53

Zabbix Alert Monitor

Mar 4th, 2019 (edited)
902
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.84 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import sys
  4. import logging
  5. import smtplib
  6. import string
  7. from email.mime.text import MIMEText
  8. from datetime import datetime, timedelta
  9. from calendar import timegm
  10. from pyzabbix import ZabbixAPI
  11. from array import array
  12.  
  13. ###################################################
  14.  
  15. # [ CONFIG START ]
  16.  
  17. # Zabbix Server Info
  18. URL = 'https://host.your.org/zabbix'
  19. API_USER = 'api'
  20. API_PASSWORD = 'api_password' # avoid or escape ( \' )  apostrophes in password
  21.  
  22. # Action IDs to check in comma seperated array: [1, 2, 3]
  23. CHECK_ACTIONS = [3]
  24.  
  25. # after ALERTS_PER alerts are generated for an action within MINUTES_DISABLE minutes, the action will be disabled
  26. # action will be re-enabled after no alerts have been generated for that action for MINUTES_RECOVERY minutes.
  27. #
  28. # NOTES: -Both problem and recovery operation alerts get counted, unless you filter them out (see below)
  29. #    -Once the action is disabled, no alerts are generated. So it will always recover after MINUTES_RECOVERY.
  30. #    -MINUTES_RECOVERY must be >= MINUTES DISABLE to prevent flapping
  31. #
  32. ALERTS_PER = 5
  33. MINUTES_DISABLE = 5
  34. MINUTES_RECOVERY = 15
  35.  
  36. # Ignore alerts where string found in subject, array format: ["ignore me", "ignore me too"]
  37. ALERT_IGNORE = ["Resolved:"]
  38.  
  39. # SMTP server info for being alerted when action status changes
  40. SMTP_SERVER = "10.11.12.13"
  41. SMTP_PORT = 25
  42. SMTP_SSL = 0
  43. SMTP_USER = "anonymous" # leave as "anonymous" for no logon
  44. SMTP_PASS = "anonymous"
  45.  
  46. # recipients in array format: ["recip1@a.com", "recip2@b.com"]
  47. SMTP_TO = ["email1@your.org","email2@your.org"]
  48. SMTP_FROM = "zabbix_monitor@your.org"
  49. SMTP_SUBJECT = "Zabbix Alert Monitor"
  50.  
  51. SMTP_ALERT_WHEN_DISABLED = 1
  52. SMTP_ALERT_WHEN_ENABLED = 1
  53. SMTP_ALERT_ERRORS = 1
  54.  
  55.  
  56. # [ CONFIG END ]
  57.  
  58. ###################################################
  59.  
  60. DEBUG=False
  61. if DEBUG:
  62.     stream = logging.StreamHandler(sys.stdout)
  63.     stream.setLevel(logging.DEBUG)
  64.     log = logging.getLogger('pyzabbix')
  65.     log.addHandler(stream)
  66.     log.setLevel(logging.DEBUG)
  67.  
  68.  
  69. def unix_time(dttm=None):
  70.     if dttm is None:
  71.        dttm = datetime.utcnow()
  72.  
  73.     return timegm(dttm.utctimetuple())
  74.  
  75.  
  76. def send_email(sub, body):
  77.     mail_server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
  78.     if SMTP_USER != "anonymous":
  79.         mail_server.login(SMTP_USER, SMTP_PASS)
  80.     if SMTP_SSL == 1:
  81.         mail_server.starttls()
  82.     msg = MIMEText(body)
  83.     msg['Subject'] = sub
  84.     msg['From'] = SMTP_FROM
  85.     msg['To'] = ", ".join(SMTP_TO)
  86.     mail_server.sendmail(SMTP_FROM, SMTP_TO, msg.as_string())
  87.     mail_server.quit
  88.  
  89. if MINUTES_RECOVERY < MINUTES_DISABLE or ALERTS_PER < 1:
  90.     print("Config error with MINUTES_RECOVERY, MINUTES_DISABLE, or ALERTS_PER")
  91.     quit()
  92.  
  93. # init the API and Authenticate
  94. zapi = ZabbixAPI(URL)
  95. zapi.timeout = 5.1
  96. zapi.login(API_USER, API_PASSWORD)
  97.  
  98. disable_start_time = datetime.utcnow() - timedelta(minutes = MINUTES_DISABLE)
  99. recovery_start_time = datetime.utcnow() - timedelta(minutes = MINUTES_RECOVERY)
  100. recovery_enable_time = (datetime.now() + timedelta(minutes = MINUTES_RECOVERY)).strftime("%Y-%m-%d %H:%M:%S")
  101.  
  102.  
  103. # DISABLE CHECKS
  104. print("")
  105. print("Action disable checks for alerts starting at:", disable_start_time.strftime("%Y-%m-%d %H:%M:%S"), "(UTC)...")
  106. disable_start_time = unix_time(disable_start_time)
  107.  
  108. seen_eventids = []
  109. for action_id in CHECK_ACTIONS:
  110.     for action in zapi.action.get(actionids=action_id):
  111.         if action['status'] != '1':
  112.             alert_count = 0
  113.             skip_count = 0
  114.             for alert in zapi.alert.get(actionids=action_id, time_from=disable_start_time):
  115.                 ignore_alert = 0
  116.                 for str_ignore in ALERT_IGNORE:
  117.                     if str_ignore.lower() in alert['subject'].lower():
  118.                         ignore_alert = 1
  119.  
  120.                 if alert['status'] != '0' and ignore_alert == 0:
  121.                     if alert['eventid'] in seen_eventids:
  122.                         print('Skipped due to duplicate event: ' + alert['subject'])
  123.                         skip_count += 1
  124.                     else:
  125.                         print(alert['subject'])
  126.                         alert_count += 1
  127.                         seen_eventids.append(alert['eventid'])
  128.                 else:
  129.                     skip_count += 1
  130.  
  131.             print("Alerts for action " + str(action_id) + " (\"" + action['name'] + "\"): skipped: " + str(alert_count) + ", counted: " + str(skip_count))
  132.  
  133.             if alert_count >= ALERTS_PER:
  134.                 err = 0
  135.                 try:
  136.                     zapi.action.update(
  137.                         actionid=action_id,
  138.                         status=1
  139.                     )
  140.                 except:
  141.                     err = 1
  142.  
  143.                 if err == 0:
  144.                     subject = SMTP_SUBJECT + ": " + action['name'] + " DISABLED"
  145.                     message = "Action \"" + action['name'] + "\" has been disabled and will be re-enabled after " + recovery_enable_time
  146.                     print(message)
  147.                     if SMTP_ALERT_WHEN_DISABLED == 1:
  148.                         send_email(subject, message)
  149.                 else:
  150.                     subject = SMTP_SUBJECT + ": ERROR"
  151.                     message = "ERROR disabling: " + action['name']
  152.                     print(message)
  153.                     if SMTP_ALERT_ERRORS == 1:
  154.                         send_email(subject, message)
  155.         else:
  156.             print("Action " + str(action_id) + " (\"" + action['name'] + "\") is currently disabled")
  157.  
  158. # RECOVERY CHECKS
  159.  
  160. print("")
  161. print("Action recover checks for alerts starting at:", recovery_start_time.strftime("%Y-%m-%d %H:%M:%S"), "(UTC)...")
  162.  
  163. recovery_start_time = unix_time(recovery_start_time)
  164.  
  165. for action_id in CHECK_ACTIONS:
  166.     for action in zapi.action.get(actionids=action_id):
  167.         if action['status'] != '0':
  168.             alert_count = 0
  169.             for alert in zapi.alert.get(actionids=action_id, time_from=recovery_start_time):
  170.                 print(alert['subject'])
  171.                 alert_count += 1
  172.                 last_eventid = alert['eventid']
  173.  
  174.             print("Alerts counted for action " + str(action_id) + " (\"" + action['name'] + "\"): " + str(alert_count))
  175.  
  176.             if alert_count == 0:
  177.                                 err = 0
  178.                                 try:
  179.                                         zapi.action.update(
  180.                                                 actionid=action_id,
  181.                                                 status=0
  182.                                         )
  183.                                 except:
  184.                                         err = 1
  185.  
  186.                                 if err == 0:
  187.                                         subject = SMTP_SUBJECT + ": " + action['name'] + " ENABLED"
  188.                                         message = "Action " + action['name'] + " has been re-enabled"
  189.                                         print(message)
  190.                                         if SMTP_ALERT_WHEN_ENABLED == 1:
  191.                                                 send_email(subject, message)
  192.                                 else:
  193.                                         subject = SMTP_SUBJECT + ": ERROR"
  194.                                         message = "ERROR enabling: " + action['name']
  195.                                         print(message)
  196.                                         if SMTP_ALERT_ERRORS == 1:
  197.                                                 send_email(subject, message)
  198.  
  199.         else:
  200.             print("Action " + str(action_id) + " (\"" + action['name'] + "\") is not currently disabled")
  201.  
  202. print("")
  203. # fin
  204.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement