Python Syslog分析 使用Python对Syslog信息进行分析并绘图的实现
格洛米爱学习 人气:0想了解使用Python对Syslog信息进行分析并绘图的实现的相关内容吗,格洛米爱学习在本文为您仔细讲解Python Syslog分析 的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Python,Syslog分析,Python,Syslog分析绘图,下面大家一起来学习吧。
实验目的:
- 对设备Syslong信息进行分析记录,并写入sqlite数据库中;后续读取数据库的信息,对Syslog的严重级别分布、来源进行分析进行分析。
- 同时监控OSPF的状态信息,状态一旦改变,进行告警。
实验结果:
监控Syslog的严重级别分布,和日志源分布,并绘图:
监控OSPF状态信息:
实验环境:
两台CSR1000v,完成Syslog(其中一台)和OSPF的配置:
logging hosy x.x.x.x /将Syslong日志信息发送给目的主机(运行python)进行处理。
logging trap debugging /监控所有级别的Syslog信息。
ospf配置略。
python脚本:
脚本一:监控CSR1000v发送的Syslog Trap信息,并对信息进行分词处理,写入数据库。同时监控OSPF邻居状态是否改变。
import socketserver import re from dateutil import parser import os import sqlite3 # facility与ID的对应关系的字典,方便后续分词时提取对应的信息 facility_dict = {0: 'KERN', 1: 'USER', 2: 'MAIL', 3: 'DAEMON', 4: 'AUTH', 5: 'SYSLOG', 6: 'LPR', 7: 'NEWS', 8: 'UUCP', 9: 'CRON', 10: 'AUTHPRIV', 11: 'FTP', 16: 'LOCAL0', 17: 'LOCAL1', 18: 'LOCAL2', 19: 'LOCAL3', 20: 'LOCAL4', 21: 'LOCAL5', 22: 'LOCAL6', 23: 'LOCAL7'} # severity_level与ID的对应关系的字典,方便后续分词时提取对应的信息 severity_level_dict = {0: 'EMERG', 1: 'ALERT', 2: 'CRIT', 3: 'ERR', 4: 'WARNING', 5: 'NOTICE', 6: 'INFO', 7: 'DEBUG'} # 分词处理的类 class SyslogUDPHandler(socketserver.BaseRequestHandler): def handle(self): data = bytes.decode(self.request[0].strip()) # 读取数据 # print(data) syslog_info_dict = {'device_ip': self.client_address[0]} try: # syslog信息如下:<187>83: *Apr 4 00:03:12.969: %LINK-3-UPDOWN: Interface GigabitEthernet2, # changed state to up,我们需要对此进行提炼分词,并将分词结果记入到一个字典里面;具体的分词过程简单了解即可 syslog_info = re.match(r'^<(\d*)>(\d*): \*(.*): %(\w+)-(\d)-(\w+): (.*)', str(data)).groups() # print(syslog_info[0]) 提取为整数 例如 185 # 185 二进制为 1011 1001 # 前5位为facility >> 3 获取前5位 # 后3位为severity_level & 0b111 获取后3位 syslog_info_dict['facility'] = (int(syslog_info[0]) >> 3) syslog_info_dict['facility_name'] = facility_dict[int(syslog_info[0]) >> 3] syslog_info_dict['logid'] = int(syslog_info[1]) syslog_info_dict['time'] = parser.parse(syslog_info[2]) syslog_info_dict['log_source'] = syslog_info[3] syslog_info_dict['severity_level'] = int(syslog_info[4]) syslog_info_dict['severity_level_name'] = severity_level_dict[int(syslog_info[4])] syslog_info_dict['description'] = syslog_info[5] syslog_info_dict['text'] = syslog_info[6] except AttributeError: # 有些日志会缺失%SYS-5-CONFIG_I, 造成第一个正则表达式无法匹配 , 也无法提取severity_level # 下面的icmp的debug就是示例 # <191>91: *Apr 4 00:12:29.616: ICMP: echo reply rcvd, src 10.1.1.80, dst 10.1.1.253, topology BASE, dscp 0 topoid 0 syslog_info = re.match(r'^<(\d*)>(\d*): \*(.*): (\w+): (.*)', str(data)).groups() print(syslog_info[0]) syslog_info_dict['facility'] = (int(syslog_info[0]) >> 3) syslog_info_dict['facility_name'] = facility_dict[int(syslog_info[0]) >> 3] syslog_info_dict['logid'] = int(syslog_info[1]) syslog_info_dict['time'] = parser.parse(syslog_info[2]) syslog_info_dict['log_source'] = syslog_info[3] # 如果在文本部分解析不了severity_level, 切换到syslog_info[0]去获取 # 185 二进制为 1011 1001 # 前5位为facility >> 3 获取前5位 # 后3位为severity_level & 0b111 获取后3位 syslog_info_dict['severity_level'] = (int(syslog_info[0]) & 0b111) syslog_info_dict['severity_level_name'] = severity_level_dict[(int(syslog_info[0]) & 0b111)] syslog_info_dict['description'] = 'N/A' syslog_info_dict['text'] = syslog_info[4] # print(syslog_info_dict) # 根据分词后的字典进行分析,如果用正则表达式匹配到了OSPF状态有了改变,则打印告警信息 if syslog_info_dict['log_source'] == 'OSPF': result_ospf = re.findall('(Process \d+), Nbr ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).+to (\w+)', syslog_info_dict['text'])[0] if result_ospf: print('OSPF '+result_ospf[0]+' Neighbor '+result_ospf[1]+' status '+result_ospf[2]) # 将字典信息写入sqlite数据库中 conn = sqlite3.connect(gl_dbname) cursor = conn.cursor() cursor.execute("insert into syslogdb (time, \ device_ip, \ facility, \ facility_name, \ severity_level, \ severity_level_name, \ logid, \ log_source, \ description, \ text) values ('%s', '%s', %d, '%s', %d, '%s', %d, '%s', '%s', '%s')" % ( syslog_info_dict['time'].strftime("%Y-%m-%d %H:%M:%S"), syslog_info_dict['device_ip'], syslog_info_dict['facility'], syslog_info_dict['facility_name'], syslog_info_dict['severity_level'], syslog_info_dict['severity_level_name'], syslog_info_dict['logid'], syslog_info_dict['log_source'], syslog_info_dict['description'], syslog_info_dict['text'], )) conn.commit() if __name__ == "__main__": # 使用Linux解释器 & WIN解释器 global gl_dbname gl_dbname = 'syslog.sqlite' if os.path.exists(gl_dbname): os.remove(gl_dbname) # 连接数据库 conn = sqlite3.connect(gl_dbname) cursor = conn.cursor() # 创建数据库 cursor.execute("create table syslogdb(id INTEGER PRIMARY KEY AUTOINCREMENT,\ time varchar(64), \ device_ip varchar(32),\ facility int,\ facility_name varchar(32),\ severity_level int,\ severity_level_name varchar(32),\ logid int,\ log_source varchar(32), \ description varchar(128), \ text varchar(1024)\ )") conn.commit() try: HOST, PORT = "0.0.0.0", 514 # 本地地址与端口 server = socketserver.UDPServer((HOST, PORT), SyslogUDPHandler) # 绑定本地地址,端口和syslog处理方法 print("Syslog 服务已启用, 写入日志到数据库!!!") server.serve_forever(poll_interval=0.5) # 运行服务器,和轮询间隔 except (IOError, SystemExit): raise except KeyboardInterrupt: # 捕获Ctrl+C,打印信息并退出 print("Crtl+C Pressed. Shutting down.") finally: conn.commit()
脚本二:读取数据库中的信息,并根据信息进行饼图绘制。
import sqlite3 from matplotlib import pyplot as plt from syslog_server_to_db import severity_level_dict # 绘制严重等级的饼图 def syslog_show_error_level_pie(dbname): # 连接数据库 conn = sqlite3.connect(dbname) cursor = conn.cursor() # 提取安全级别和数量信息 cursor.execute("select severity_level as level,COUNT(*) as count from syslogdb group by severity_level") yourresults = cursor.fetchall() level_list = [] count_list = [] # 把结果写入leve_list和count_list的列表 for level_info in yourresults: level_list.append(severity_level_dict[level_info[0]]) count_list.append(level_info[1]) print(level_list) print([float(count) for count in count_list]) plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文 # 调节图形大小,宽,高 plt.figure(figsize=(6, 6)) # 使用count_list的比例来绘制饼图 # 使用level_list作为注释 patches, l_text, p_text = plt.pie(count_list, labels=level_list, labeldistance=1.1, autopct='%3.1f%%', shadow=False, startangle=90, pctdistance=0.6) # 改变文本的大小 # 方法是把每一个text遍历。调用set_size方法设置它的属性 for t in l_text: t.set_size = 30 for t in p_text: t.set_size = 20 # 设置x,y轴刻度一致,这样饼图才能是圆的 plt.axis('equal') plt.title('SYSLOG严重级别分布图') # 主题 plt.legend() plt.show() # 绘制Syslog来源的饼图 def syslog_show_source_pie(dbname): # 连接数据库 conn = sqlite3.connect(dbname) cursor = conn.cursor() # 提取log源与其对应的数量 cursor.execute("select log_source,COUNT(*) as count from syslogdb group by log_source") yourresults = cursor.fetchall() source_list = [] count_list = [] # 将数据库的信息,依次写入两个列表 for source_info in yourresults: source_list.append(source_info[0]) count_list.append(source_info[1]) print(source_list) print([float(count) for count in count_list]) plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文 # 调节图形大小,宽,高 plt.figure(figsize=(6, 6)) # 使用count_list的比例来绘制饼图 # 使用level_list作为注释 patches, l_text, p_text = plt.pie(count_list, labels=source_list, labeldistance=1.1, autopct='%3.1f%%', shadow=False, startangle=90, pctdistance=0.6) # 改变文本的大小 # 方法是把每一个text遍历。调用set_size方法设置它的属性 for t in l_text: t.set_size = 30 for t in p_text: t.set_size = 20 # 设置x,y轴刻度一致,这样饼图才能是圆的 plt.axis('equal') plt.title('日志源分布图') # 主题 plt.legend() plt.show() if __name__ == '__main__': syslog_show_error_level_pie("syslog.sqlite") syslog_show_source_pie("syslog.sqlite")
参考资料来源:现任明教教主
加载全部内容