Python中怎么对Syslog分析和实现绘图
Admin 2022-07-15 群英技术资讯 727 次浏览
今天这篇给大家分享的知识是“Python中怎么对Syslog分析和实现绘图”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“Python中怎么对Syslog分析和实现绘图”文章能帮助大家解决问题。监控Syslog的严重级别分布,和日志源分布,并绘图:


监控OSPF状态信息:

两台CSR1000v,完成Syslog(其中一台)和OSPF的配置:
logging hosy x.x.x.x /将Syslong日志信息发送给目的主机(运行python)进行处理。
logging trap debugging /监控所有级别的Syslog信息。
ospf配置略。
脚本一:监控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")
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
#用正则简单过滤html的<>标签importrestr="<img/><a>srcd</a>hello</br><br/>"str=re.sub(r'</?\w+[^>]*>','',str)print(str)importretest='&am
这篇文章主要介绍了python 基础绘图之关于随时间序列变动的图的画法,首先大家要明白画图需要考虑的问题,如何在图中适当的显示轴标签的样式和数量,详细代码跟随小编一起看看吧
这篇文章主要介绍了Pytest之测试命名规则的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
这篇文章主要为大家详细介绍了python实现简单五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
最近在进行django项目开发的时候,遇到了需要连接两个MySQL数据库的问题,下面这篇文章主要给大家介绍了关于Django项目配置连接多个数据库的相关资料,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008