一、负责把达到报警条件的trigger进行分析 ,并根据 action 表中的配置来进行报警

1、目录结构

2、功能如下

  1. 1、找到trigger的关联动作,
  2. 2、收到的数据传给trigger_msg就是trigger_data
  3. 3、trigger_id') == None怎么会等于None
  4. 4、每个action都可以直接包含多个主机或主机组

3、实现代码

class ActionHandler(object):
'''
负责把达到报警条件的trigger进行分析 ,并根据 action 表中的配置来进行报警
''' def __init__(self,trigger_data,alert_counter_dic):
self.trigger_data = trigger_data
#self.trigger_process()
self.alert_counter_dic = alert_counter_dic def record_log(self,action_obj,action_operation,host_id,trigger_data):
"""record alert log into DB"""
models.EventLog.objects.create(
event_type = 0,
host_id=host_id,
trigger_id = trigger_data.get('trigger_id'),
log = trigger_data
)

二、报警发送邮件内容

1、实现代码

   def action_email(self,action_obj,action_operation_obj,host_id,trigger_data):
'''
sending alert email to who concerns.
:param action_obj: 触发这个报警的action对象
:param action_operation_obj: 要报警的动作对象
:param host_id: 要报警的目标主机
:param trigger_data: 要报警的数据
:return:
''' print("要发报警的数据:",self.alert_counter_dic[action_obj.id][host_id])
print("action email:",action_operation_obj.action_type,action_operation_obj.notifiers,trigger_data)
notifier_mail_list = [obj.email for obj in action_operation_obj.notifiers.all()]
subject = '级别:%s -- 主机:%s -- 服务:%s' %(trigger_data.get('trigger_id'),
trigger_data.get('host_id'),
trigger_data.get('service_item')) send_mail(
subject,
action_operation_obj.msg_format,
settings.DEFAULT_FROM_EMAIL,
notifier_mail_list,
)

2、邮件截图类似于下图

三、分析trigger并报警

1、为什么tigger里关联了template,template里又关联了主机,那action还要直接关联主机呢?

  那是因为一个trigger可以被多个template关联,这个trigger触发了,不一定是哪个tempalte里的主机导致的

2、功能如下

1、第一次被 触,先初始化一个action counter dic

2、这个主机第一次触发这个action的报警

  你不是触发一次我报一次,我是到了触发时间触发才报警,
3、如果达到报警触发interval次数,就记数+1

4、该报警了

  1. 报完警后更新一下报警时间 ,这样就又重新计算alert interval了
  2. 打印离下次触发报警的时间还有[%s]s" %

3、实现代码

    def trigger_process(self):
'''
分析trigger并报警
:return:
'''
print('Action Processing'.center(50,'-')) if self.trigger_data.get('trigger_id') == None: #trigger id == None
print(self.trigger_data)
if self.trigger_data.get('msg'):
print(self.trigger_data.get('msg')) #既然没有trigger id,直接报警给管理 员
else:
print("\033[41;1mInvalid trigger data %s\033[0m" % self.trigger_data) else:#正经的trigger 报警要触发了
print("\033[33;1m%s\033[0m" %self.trigger_data) trigger_id = self.trigger_data.get('trigger_id')
host_id = self.trigger_data.get('host_id')
trigger_obj = models.Trigger.objects.get(id=trigger_id)
actions_set = trigger_obj.action_set.select_related() #找到这个trigger所关联的action list
print("actions_set:",actions_set)
matched_action_list = set() # 一个空集合
for action in actions_set:
#每个action 都 可以直接 包含多个主机或主机组,
# 为什么tigger里关联了template,template里又关联了主机,那action还要直接关联主机呢?
#那是因为一个trigger可以被多个template关联,这个trigger触发了,不一定是哪个tempalte里的主机导致的
for hg in action.host_groups.select_related():
for h in hg.host_set.select_related():
if h.id == host_id:# 这个action适用于此主机
matched_action_list.add(action)
if action.id not in self.alert_counter_dic: #第一次被 触,先初始化一个action counter dic
self.alert_counter_dic[action.id] = {}
print("action, ",id(action))
if h.id not in self.alert_counter_dic[action.id]: # 这个主机第一次触发这个action的报警
self.alert_counter_dic[action.id][h.id] = {'counter': 0, 'last_alert': time.time()}
# self.alert_counter_dic.setdefault(action,{h.id:{'counter':0,'last_alert':time.time()}})
else:
#如果达到报警触发interval次数,就记数+1
if time.time() - self.alert_counter_dic[action.id][h.id]['last_alert'] >= action.interval:
self.alert_counter_dic[action.id][h.id]['counter'] += 1
#self.alert_counter_dic[action.id][h.id]['last_alert'] = time.time() else:
print("没达到alert interval时间,不报警",action.interval,
time.time() - self.alert_counter_dic[action.id][h.id]['last_alert'])
#self.alert_counter_dic.setdefault(action.id,{}) for host in action.hosts.select_related():
if host.id == host_id: # 这个action适用于此主机
matched_action_list.add(action)
if action.id not in self.alert_counter_dic: # 第一次被 触,先初始化一个action counter dic
self.alert_counter_dic[action.id] = {}
if h.id not in self.alert_counter_dic[action.id]: #这个主机第一次触发这个action的报警
self.alert_counter_dic[action.id][h.id] ={'counter': 0, 'last_alert': time.time()}
#self.alert_counter_dic.setdefault(action,{h.id:{'counter':0,'last_alert':time.time()}})
else:
# 如果达到报警触发interval次数,就记数+1
if time.time() - self.alert_counter_dic[action.id][h.id]['last_alert'] >= action.interval:
self.alert_counter_dic[action.id][h.id]['counter'] += 1
#self.alert_counter_dic[action.id][h.id]['last_alert'] = time.time()
else:
print("没达到alert interval时间,不报警", action.interval,
time.time() - self.alert_counter_dic[action.id][h.id]['last_alert']) print("alert_counter_dic:",self.alert_counter_dic)
print("matched_action_list:",matched_action_list)
for action_obj in matched_action_list:#
if time.time() - self.alert_counter_dic[action_obj.id][host_id]['last_alert'] >= action_obj.interval:
#该报警 了
print("该报警了.......",time.time() - self.alert_counter_dic[action_obj.id][host_id]['last_alert'],action_obj.interval)
for action_operation in action_obj.operations.select_related().order_by('-step'):
if action_operation.step > self.alert_counter_dic[action_obj.id][host_id]['counter']:
#就
print("##################alert action:%s" %
action_operation.action_type,action_operation.notifiers) action_func = getattr(self,'action_%s'% action_operation.action_type)
action_func(action_obj,action_operation,host_id,self.trigger_data) #报完警后更新一下报警时间 ,这样就又重新计算alert interval了
self.alert_counter_dic[action_obj.id][host_id]['last_alert'] = time.time()
self.record_log(action_obj,action_operation,host_id,self.trigger_data)
# else:
# print("离下次触发报警的时间还有[%s]s" % )

  

分布式监控系统开发【day38】:报警模块解析(六)的更多相关文章

  1. Python之路,Day20 - 分布式监控系统开发

    Python之路,Day20 - 分布式监控系统开发   本节内容 为什么要做监控? 常用监控系统设计讨论 监控系统架构设计 监控表结构设计 为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个 ...

  2. 分布式监控系统开发【day37】:需求讨论(一)

    本节内容 为什么要做监控? 常用监控系统设计讨论 监控需求讨论 如何实现监控服务器的水平扩展? 监控系统架构设计 一.为什么要做监控? 熟悉IT监控系统的设计原理 开发一个简版的类Zabbix监控系统 ...

  3. Python之分布式监控系统开发

    为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个简版的类Zabbix监控系统 –掌握自动化开发项目的程序设计思路及架构解藕原则 常用监控系统设计讨论 Zabbix Nagios 监控系统需求 ...

  4. day26 分布式监控系统开发

    本节内容 为什么要做监控? 常用监控系统设计讨论 监控系统架构设计 监控表结构设计 为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个简版的类Zabbix监控系统 –掌握自动化开发项目的程序设 ...

  5. 分布式监控系统开发【day38】:报警阈值程序逻辑解析(三)

    一.需求讨论 1.请问如何解决延迟问题 1000台机器,每1分钟循环一次但是刚好第一次循环第一秒刚处理完了,结果还没等到第二分钟又出问题,你那必须等到第二次循环,假如我这个服务很重要必须实时知道,每次 ...

  6. 分布式监控系统开发【day38】:主机存活检测程序解析(七)

    一.目录结构 二.入口 1.文件MonitorServer.py import os import sys if __name__ == "__main__": os.enviro ...

  7. 分布式监控系统开发【day38】:报警自动升级代码解析及测试(八)

    一.报警自动升级代码解析 发送邮件代码 def action_email(self,action_obj,action_operation_obj,host_id,trigger_data): ''' ...

  8. 分布式监控系统开发【day38】:监控trigger表结构设计(一)

    一.需求讨论 1.zabbix触发器的模板截图 1.zabbix2.4.7 2.zabbix3.0 2.模板与触发器关联的好处 好处就是可以批量处理,比如我说我有1000机器都要监控cpu.内存.IO ...

  9. 分布式监控系统开发【day38】:报警策略队列处理(五)

    一.目录结构 二.报警策略队列处理 1.入口MonitorServer import os import sys if __name__ == "__main__": os.env ...

随机推荐

  1. chrome总是提示“请停用开发者模式运行的扩展程序”

    方法1:通过组策略的扩展白名单.要下载一个组策略管理模板 1.开始 -> 运行 -> 输入gpedit.msc -> 回车确定打开计算机本地组策略编辑器(通过Win + R快捷键可以 ...

  2. jenkins使用开始踩坑(1)

    上篇文章 安装教程 :https://www.cnblogs.com/linuxchao/p/linuxchao-jenkins-setup.html 一.前戏 话说上一篇文章安装完 JDK 和 je ...

  3. 模块简介:(logging)(re)(subprocess)

    ''' logging模块: logging的日志可以分为 debug():Detailed information, typically of interest only when diagnosi ...

  4. WPFの命中测试

    概述:  WPF中的Canvas是常用的一个绘图控件,可以方便地在Canvas中添加我们需要处理的各种元素如:图片.文字等.但Canvas中元素增加到一定数量,并且有重合的时候,我们如何通过在Canv ...

  5. day7-基础函数的学习(二)

    过了元旦,加油鸭,冲鸭!!! 闲话不说,开始今日份学习整理. 今日目录,今天的学习内容不是很多! 1.函数名的运用 2.闭包(重要) 3.迭代器(重要) 开始今日份总结 1.函数名的运用 1.1函数名 ...

  6. CSAPP:第九章 虚拟内存

    CSAPP:第九章 虚拟内存 关键点:虚拟内存.物理内存 9.1 物理地址和虚拟地址9.2 地址空间9.3 虚拟内存作为缓存的公工具 9.1 物理地址和虚拟地址   计算机的主存被组织成一个由M个连续 ...

  7. bsxfun

    By HYB bsxfun(fun,A,B)偶然间发现了这个函数,强大得不得了呀,它的作用是:对两个矩阵A和B之间的每一个元素进行指定的计算(函数fun指定):并且具有自动扩维的作用 例如,A是一个4 ...

  8. C# — 调用dll出现试图加载不正确格式的程序问题

    今天在调用百度dll包时,运行项目出现了如下警告: 修改:鼠标右击项目名称----选择属性----生成-----平台目标-----X64(由于我调用的是X64的dll包,所以这里选择X64,网上许多说 ...

  9. EF Core 多对多配置

    1.配置2个数据表 T_Authors ,T_Books 2.新建控制台项目,安装EF驱动 PM> Install-Package Pomelo.EntityFrameworkCore.Mysq ...

  10. JVM调优:HotSpot JVM垃圾收集器

    HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html