使用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")

参考资料来源:现任明教教主

到此这篇关于使用Python对Syslog信息进行分析并绘图的实现的文章就介绍到这了,更多相关Python Syslog分析 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python绘图之柱形图绘制详解

    前言 用python编程绘图,其实非常简单.中学生.大学生.研究生都能通过这10篇教程从入门到精通!快速绘制几种简单的柱状图. 1垂直柱图(普通柱图) 绘制普通柱图的python代码如下: (左右滑动可以查看全部代码) # -*- coding:utf-8 -*- # 申明编码格式为utf-8 import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams["font.sans-serif"]=["S

  • Python实现手绘图效果实例分享

    首先我们来看看原图: 接着我们来看看效果图: 通过分析我们不难发现以下特征: 主要颜色为黑白灰 边界线条较重 相同或相近色趋于白色 略有光源效果 需要用到的库有: numpy PIL 代码实现: import numpy as np from PIL import Image baseImg = Image.open("./img/myimg2.jpg").convert("L")  # 这里放置你要手绘的图片原图 a = np.array(baseImg).ast

  • python绘图pyecharts+pandas的使用详解

    pyecharts介绍 pyecharts 是一个用于生成 Echarts 图表的类库.Echarts 是百度开源的一个数据可视化 JS 库.用 Echarts 生成的图可视化效果非常棒 为避免绘制缺漏,建议全部安装 为了避免下载缓慢,作者全部使用镜像源下载过了 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ echarts-countries-pypkg pip install -i https://pypi.tuna.tsin

  • Python数据可视化常用4大绘图库原理详解

    今天我们就用一篇文章,带大家梳理matplotlib.seaborn.plotly.pyecharts的绘图原理,让大家学起来不再那么费劲! 1. matplotlib绘图原理 关于matplotlib更详细的绘图说明,大家可以参考下面这篇文章,相信你看了以后一定学得会. matplotlib绘图原理:http://suo.im/678FCo 1)绘图原理说明 通过我自己的学习和理解,我将matplotlib绘图原理高度总结为如下几步: 导库;创建figure画布对象;获取对应位置的axes坐标

  • python绘图模块之利用turtle画图

    模块之turtle 小故事 前两天朋友说:"常文啊!听说你会python,那能不能用python画一些好看的图呢?"然后我特意去学了一下turtle模块,现在给大家分享一下. 一.什么是turtle Turtle是python内嵌的绘制线.圆以及其他形状(包括文本)的图形模块. 二.turtle函数的使用 import turtle turtle.pendown() # 放下画笔 turtle.penup() # 抬起画笔 turtle.pensize(int) # 设置画笔宽度,值为

  • Python实战之画哆啦A梦(超详细步骤)

    一.写在前面 本文基于64位windows系统(鼠标右键点击桌面"此电脑"图标--属性可查看电脑系统版本).python3.x(pycharm自动安装的版本, 3.0以上).文中代码内容所使用的工具是pycharm-community-2020.1,实践中如有碰到问题,可留言提问. 前阵子有看到zh上有大神画了这个哆啦A梦的大头贴,自己也来试了一下,很简单,但长篇整段的代码对刚刚学会海龟绘图语法的初学者来说还是有一定难度,所以来做一个拆解版详细步骤讲解实现. 二.效果图 言归正传,先上

  • Python绘图之二维图与三维图详解

    各位工程师累了吗? 推荐一篇可以让你技术能力达到出神入化的网站"持久男" 1.二维绘图 a. 一维数据集 用 Numpy ndarray 作为数据传入 ply 1. import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt np.random.seed(1000) y = np.random.standard_normal(10) print "y = %s"% y x =

  • Python Matplotlib绘图基础知识代码解析

    1.Figure和Subplot import numpy as np import matplotlib.pyplot as plt #创建一个Figure fig = plt.figure() #不能通过空figure绘图,必须使用add_subplot创建一个或多个subplot #图像为2x2,第三个参数为当前选中的第几个 ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot

  • 用Python的绘图库(matplotlib)绘制小波能量谱

    时间小波能量谱 反映信号的小波能量沿时间轴的分布. 由于小波变换具有等距效应,所以有: 式中 表示信号强度,对于式①在平移因子b方向上进行加权积分 式中 代表时间-小能量谱 尺度小波能量谱 反映信号的小波能量随尺度的变化情况. 同理,对式①在尺度方向上进行加权积分: 式中 连续小波变换 连续小波变换的结果是一个小波系数矩阵,随着尺度因子和位移因子变化.然后将系数平方后得到小波能量,把每个尺度因子对应的所有小波能量进行叠加,那么就可以得到随尺度因子变换的小波能量谱曲线.把尺度换算成频率后,这条曲线

  • Python下使用Trackbar实现绘图板

    本次实验利用到了cv2中的createTrackbar和getTrackbarPos函数实现一个绘图板的功能,用户可以选择矩形或是画笔模式,并设置调色板中的值来选择颜色,再选择画笔大小,进行绘图.除此之外,还可以用橡皮擦进行擦除,模式同样也分为矩形和画笔. 下面是具体的代码: import cv2 import numpy as np drawing = False mode = True ix, iy = -1, -1 def nothing(x): pass def draw_circle(

  • python 绘图模块matplotlib的使用简介

    上周对线上某几个磁盘进行了fio硬盘性能测试,测试完成之后的结果需要绘制成图像展示出来.我在官网上查找了一下fio自带的命令fio_generate_plot和fio2gnuplot工具的用法,找到了图像的绘制方法,在某一个单一的场景下,确实可以使用这两个工具来进行硬盘性能图像绘制,但是问题是,如果要对比多个场景下绘制出来的图像的差异,fio自带的绘图工具实现起来就有些困难了,但是确实也能实现.例如下图: 如图所示为磁盘iodepth不变,numjobs在(1,8,16)三种不同的场景下绘制出来

  • Python三维绘图之Matplotlib库的使用方法

    前言 在遇到三维数据时,三维图像能给我们对数据带来更加深入地理解.python的matplotlib库就包含了丰富的三维绘图工具. 1.创建三维坐标轴对象Axes3D 创建Axes3D主要有两种方式,一种是利用关键字projection='3d'l来实现,另一种则是通过从mpl_toolkits.mplot3d导入对象Axes3D来实现,目的都是生成具有三维格式的对象Axes3D. #方法一,利用关键字 from matplotlib import pyplot as plt from mpl_

  • python之 matplotlib和pandas绘图教程

    不得不说使用python库matplotlib绘图确实比较丑,但使用起来还算是比较方便,做自己的小小研究可以使用.这里记录一些统计作图方法,包括pandas作图和plt作图. 前提是先导入第三方库吧 import pandas as pd import matplotlib.pyplot as plt import numpy as np 然后以下这两句用于正常显示中文标签什么的. plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签

  • python matplotlib绘图实现删除重复冗余图例的操作

    问题: 由于自己做项目的时候,需要循环的绘制数据,假设有100个样本,每个样本包含两个坐标点(A, B),我需要对这两个点标上不同的颜色,同时还要画出两点间的连线. 显然这个问题中图例我只需要3个(A点,B点,AB的连线),而不是300个,因为每个样本的A点都是同样的颜色,B点也都是一样的颜色,AB的连线也是. 但是单纯的在画完图之后用plt.legend(), 它会给你画出所有300个图例来,这肯定不是我想要的. 探索过程: 如何解决呢? 当然有一种很强制的方法,就是只在画第一个样本,或最后一

随机推荐