使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn)
實(shí)驗(yàn)?zāi)康模?/h2>
- 對(duì)設(shè)備Syslong信息進(jìn)行分析記錄,并寫(xiě)入sqlite數(shù)據(jù)庫(kù)中;后續(xù)讀取數(shù)據(jù)庫(kù)的信息,對(duì)Syslog的嚴(yán)重級(jí)別分布、來(lái)源進(jìn)行分析進(jìn)行分析。
- 同時(shí)監(jiān)控OSPF的狀態(tài)信息,狀態(tài)一旦改變,進(jìn)行告警。
實(shí)驗(yàn)結(jié)果:
監(jiān)控Syslog的嚴(yán)重級(jí)別分布,和日志源分布,并繪圖:
監(jiān)控OSPF狀態(tài)信息:
實(shí)驗(yàn)環(huán)境:
兩臺(tái)CSR1000v,完成Syslog(其中一臺(tái))和OSPF的配置:
logging hosy x.x.x.x /將Syslong日志信息發(fā)送給目的主機(jī)(運(yùn)行python)進(jìn)行處理。
logging trap debugging /監(jiān)控所有級(jí)別的Syslog信息。
ospf配置略。
python腳本:
腳本一:監(jiān)控CSR1000v發(fā)送的Syslog Trap信息,并對(duì)信息進(jìn)行分詞處理,寫(xiě)入數(shù)據(jù)庫(kù)。同時(shí)監(jiān)控OSPF鄰居狀態(tài)是否改變。
import socketserver import re from dateutil import parser import os import sqlite3 # facility與ID的對(duì)應(yīng)關(guān)系的字典,方便后續(xù)分詞時(shí)提取對(duì)應(yīng)的信息 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的對(duì)應(yīng)關(guān)系的字典,方便后續(xù)分詞時(shí)提取對(duì)應(yīng)的信息 severity_level_dict = {0: 'EMERG', 1: 'ALERT', 2: 'CRIT', 3: 'ERR', 4: 'WARNING', 5: 'NOTICE', 6: 'INFO', 7: 'DEBUG'} # 分詞處理的類(lèi) class SyslogUDPHandler(socketserver.BaseRequestHandler): def handle(self): data = bytes.decode(self.request[0].strip()) # 讀取數(shù)據(jù) # 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,我們需要對(duì)此進(jìn)行提煉分詞,并將分詞結(jié)果記入到一個(gè)字典里面;具體的分詞過(guò)程簡(jiǎn)單了解即可 syslog_info = re.match(r'^<(\d*)>(\d*): \*(.*): %(\w+)-(\d)-(\w+): (.*)', str(data)).groups() # print(syslog_info[0]) 提取為整數(shù) 例如 185 # 185 二進(jìn)制為 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: # 有些日志會(huì)缺失%SYS-5-CONFIG_I, 造成第一個(gè)正則表達(dá)式無(wú)法匹配 , 也無(wú)法提取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 二進(jìn)制為 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) # 根據(jù)分詞后的字典進(jìn)行分析,如果用正則表達(dá)式匹配到了OSPF狀態(tài)有了改變,則打印告警信息 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]) # 將字典信息寫(xiě)入sqlite數(shù)據(jù)庫(kù)中 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) # 連接數(shù)據(jù)庫(kù) conn = sqlite3.connect(gl_dbname) cursor = conn.cursor() # 創(chuàng)建數(shù)據(jù)庫(kù) 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 服務(wù)已啟用, 寫(xiě)入日志到數(shù)據(jù)庫(kù)!!!") server.serve_forever(poll_interval=0.5) # 運(yùn)行服務(wù)器,和輪詢間隔 except (IOError, SystemExit): raise except KeyboardInterrupt: # 捕獲Ctrl+C,打印信息并退出 print("Crtl+C Pressed. Shutting down.") finally: conn.commit()
腳本二:讀取數(shù)據(jù)庫(kù)中的信息,并根據(jù)信息進(jìn)行餅圖繪制。
import sqlite3 from matplotlib import pyplot as plt from syslog_server_to_db import severity_level_dict # 繪制嚴(yán)重等級(jí)的餅圖 def syslog_show_error_level_pie(dbname): # 連接數(shù)據(jù)庫(kù) conn = sqlite3.connect(dbname) cursor = conn.cursor() # 提取安全級(jí)別和數(shù)量信息 cursor.execute("select severity_level as level,COUNT(*) as count from syslogdb group by severity_level") yourresults = cursor.fetchall() level_list = [] count_list = [] # 把結(jié)果寫(xiě)入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'] # 設(shè)置中文 # 調(diào)節(jié)圖形大小,寬,高 plt.figure(figsize=(6, 6)) # 使用count_list的比例來(lái)繪制餅圖 # 使用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) # 改變文本的大小 # 方法是把每一個(gè)text遍歷。調(diào)用set_size方法設(shè)置它的屬性 for t in l_text: t.set_size = 30 for t in p_text: t.set_size = 20 # 設(shè)置x,y軸刻度一致,這樣餅圖才能是圓的 plt.axis('equal') plt.title('SYSLOG嚴(yán)重級(jí)別分布圖') # 主題 plt.legend() plt.show() # 繪制Syslog來(lái)源的餅圖 def syslog_show_source_pie(dbname): # 連接數(shù)據(jù)庫(kù) conn = sqlite3.connect(dbname) cursor = conn.cursor() # 提取log源與其對(duì)應(yīng)的數(shù)量 cursor.execute("select log_source,COUNT(*) as count from syslogdb group by log_source") yourresults = cursor.fetchall() source_list = [] count_list = [] # 將數(shù)據(jù)庫(kù)的信息,依次寫(xiě)入兩個(gè)列表 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'] # 設(shè)置中文 # 調(diào)節(jié)圖形大小,寬,高 plt.figure(figsize=(6, 6)) # 使用count_list的比例來(lái)繪制餅圖 # 使用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) # 改變文本的大小 # 方法是把每一個(gè)text遍歷。調(diào)用set_size方法設(shè)置它的屬性 for t in l_text: t.set_size = 30 for t in p_text: t.set_size = 20 # 設(shè)置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")
參考資料來(lái)源:現(xiàn)任明教教主
到此這篇關(guān)于使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Syslog分析 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python在windows下實(shí)現(xiàn)ping操作并接收返回信息的方法
這篇文章主要介紹了python在windows下實(shí)現(xiàn)ping操作并接收返回信息的方法,實(shí)例分析了Python實(shí)現(xiàn)ping操作的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03Django動(dòng)態(tài)展示Pyecharts圖表數(shù)據(jù)的幾種方法
本文主要介紹了Django動(dòng)態(tài)展示Pyecharts圖表數(shù)據(jù)的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08一篇文章帶你學(xué)習(xí)Python3的高級(jí)特性(2)
這篇文章主要為大家詳細(xì)介紹了Python3的高階函數(shù),主要介紹什么是高級(jí)特性,高級(jí)特性的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01pandas數(shù)據(jù)類(lèi)型之Series的具體使用
本文主要介紹了pandas數(shù)據(jù)類(lèi)型之Series的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Python callable()函數(shù)用法實(shí)例分析
這篇文章主要介紹了Python callable()函數(shù)用法,結(jié)合實(shí)例形式分析了Python callable()函數(shù)的功能、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-03-03Python爬蟲(chóng)常用小技巧之設(shè)置代理IP
這篇文章主要給大家介紹了關(guān)于Python爬蟲(chóng)常用小技巧之設(shè)置代理IP的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09python爬蟲(chóng)基礎(chǔ)知識(shí)點(diǎn)整理
在本篇文章里小編給大家整理的是一篇關(guān)于python爬蟲(chóng)基礎(chǔ)知識(shí)點(diǎn)整理內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2020-06-06