分布式监控系统开发【day38】:报警模块解析(六)
一、负责把达到报警条件的trigger进行分析 ,并根据 action 表中的配置来进行报警
1、目录结构

2、功能如下
- 1、找到trigger的关联动作,
- 2、收到的数据传给trigger_msg就是trigger_data
- 3、trigger_id') == None怎么会等于None
- 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、该报警了
- 报完警后更新一下报警时间 ,这样就又重新计算alert interval了
- 打印离下次触发报警的时间还有[%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】:报警模块解析(六)的更多相关文章
- Python之路,Day20 - 分布式监控系统开发
Python之路,Day20 - 分布式监控系统开发 本节内容 为什么要做监控? 常用监控系统设计讨论 监控系统架构设计 监控表结构设计 为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个 ...
- 分布式监控系统开发【day37】:需求讨论(一)
本节内容 为什么要做监控? 常用监控系统设计讨论 监控需求讨论 如何实现监控服务器的水平扩展? 监控系统架构设计 一.为什么要做监控? 熟悉IT监控系统的设计原理 开发一个简版的类Zabbix监控系统 ...
- Python之分布式监控系统开发
为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个简版的类Zabbix监控系统 –掌握自动化开发项目的程序设计思路及架构解藕原则 常用监控系统设计讨论 Zabbix Nagios 监控系统需求 ...
- day26 分布式监控系统开发
本节内容 为什么要做监控? 常用监控系统设计讨论 监控系统架构设计 监控表结构设计 为什么要做监控? –熟悉IT监控系统的设计原理 –开发一个简版的类Zabbix监控系统 –掌握自动化开发项目的程序设 ...
- 分布式监控系统开发【day38】:报警阈值程序逻辑解析(三)
一.需求讨论 1.请问如何解决延迟问题 1000台机器,每1分钟循环一次但是刚好第一次循环第一秒刚处理完了,结果还没等到第二分钟又出问题,你那必须等到第二次循环,假如我这个服务很重要必须实时知道,每次 ...
- 分布式监控系统开发【day38】:主机存活检测程序解析(七)
一.目录结构 二.入口 1.文件MonitorServer.py import os import sys if __name__ == "__main__": os.enviro ...
- 分布式监控系统开发【day38】:报警自动升级代码解析及测试(八)
一.报警自动升级代码解析 发送邮件代码 def action_email(self,action_obj,action_operation_obj,host_id,trigger_data): ''' ...
- 分布式监控系统开发【day38】:监控trigger表结构设计(一)
一.需求讨论 1.zabbix触发器的模板截图 1.zabbix2.4.7 2.zabbix3.0 2.模板与触发器关联的好处 好处就是可以批量处理,比如我说我有1000机器都要监控cpu.内存.IO ...
- 分布式监控系统开发【day38】:报警策略队列处理(五)
一.目录结构 二.报警策略队列处理 1.入口MonitorServer import os import sys if __name__ == "__main__": os.env ...
随机推荐
- Proxmox VE中出现TASK ERROR: command 'apt-get update' failed: exit code 100的解决方法
问题描述: 出现这个错误一般在WEB或者在Proxmox VE的服务器上面能看到日志: PVE中出现TASK ERROR: command 'apt-get update' failed: exit ...
- 小小白搭建nextcloud云盘
我是一名linux的小小白,今天就利用自己的所学搭建属于自己的云盘——nextcloud. 本人学生狗,普通的云盘也要几十块钱,既然我们只是拿来搭建巩固自己知识并不做为生产力,我们就用VMware W ...
- 持续代码质量管理-SonarQube Scanner部署
1. SonarQube Scanner地址 上一篇文章我们安装了SonarQube-7.3,让我们可以在页面查看代码质量.但是具体的扫描工作则需要SonarQube Scanner完成. 下载页面 ...
- 进程间数据传递:Queue,Pipe 进程间数据共享:Manager
1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯: Queue,用法跟线程里的Queue一样,put,get 线程queue没有做序列化,进程queue做序列化了 ...
- 解决IntelliJ IDEA 创建Maven项目速度慢问题
IntelliJ IDEA 创建maven项目速度很慢,甚至卡住不动了. 原因 IDEA根据maven archetype的本质,其实是执行mvn archetype:generate命令,该命令执行 ...
- android 实现点击edittext的“小眼睛”切换明密文
android 实现点击edittext的“小眼睛”切换明密文 版权声明:本文为博主原创文章,未经博主允许不得转载. 很多时候,我们为了用户的隐私安全,需要在密码输入的时候,显示密文.为了更 ...
- Axios
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端.简单的理解就是ajax的封装 它本身具有以下特征: a.从浏览器中创建 XMLHttpRequest b ...
- HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法
深蓝前几篇博客讲了Fabric的环境搭建,在环境搭建好后,我们就可以进行Fabric的开发工作了.Fabric的开发主要分成2部分,ChainCode链上代码开发和基于SDK的Application开 ...
- Redis入门之增删改查等常用命令总结
Redis是用C语言实现的,一般来说C语言实现的程序"距离"操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多线程可能产生的竞争问题. 作者对于Redis源代 ...
- PHP之提升代码质量36计
转载:https://www.binarytides.com/35-techniques-to-enhance-your-php-code/ 1.不要使用相对路径 常常会看到: require_onc ...