python3 mysql报警日志_Python监听MySQL日志
前言
在使用后臺語言開發中,每天都是在與數據庫打交道,而很多時候出問題都出在SQL語句上,而調試起來也不太方便,當然大佬例外哈,我等新手還真沒辦法在短時間內練習出一些技巧,我是用PHP的,之前在網上也搜索的時候,見別人使用的PHP工具箱,里面有個SQL追蹤工具,感覺很不錯,能夠監聽到當前執行的SQL語句,然而那個東西需要自動手動去點擊刷新,作為程序猿,要的就是懶,還要手動點,不開心!
既然想懶,那就做成自動的,經過查詢資料了解,MySQL內置了log功能,只需要將其開啟,然后我們監聽其內容變化即可,思路通了,接下來就是開搞了.
動手開搞
這里我選用的是Python來寫,畢竟"人生苦短,我用Python"
先上代碼,然后再來依次講解,代碼精簡一下其實50行不到,我這個完全沒優化啥的,主要是實現功能,哪位大佬有時間可以幫忙改改,萬分感謝!點擊下載
import pymysql
import re
import time
import os
import subprocess
# 數據庫信息
host = 'localhost'
user = 'root'
password = '123456'
port = 8889
db = 'JCL'
# 表前綴(如果沒有就留空)
prefix = 'xh_'
logpath = os.getcwd() + '/mysql.log'
def connectMySQL(ip, user, pwd, port, db):
# 開始連接數據庫
connect = pymysql.connect(
host=ip,
user=user,
passwd=pwd,
port=port,
db=db,
charset='utf8'
)
# 獲取游標
cur = connect.cursor()
# 開啟mysql標準日志
cur.execute('set global general_log = on')
connect.commit()
currentPath = 'set global log_output = \'file\''
cur.execute(currentPath)
connect.commit()
cur.execute('set global general_log_file=' + '\'' + logpath + '\'')
connect.commit()
connect.close()
def monitor():
command = 'tail -f ' + logpath
popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
try:
while True:
line = popen.stdout.readline().strip()
encodeStr = bytes.decode(line)
pattern = re.findall('Query\s*(.*)', encodeStr, re.S)
if len(pattern) != 0:
selectStr = pattern[0]
if selectStr != "COMMIT":
joinTime = time.strftime("%H:%M:%S", time.localtime()) + ' '
if prefix != "":
reg = re.findall(r'\b' + prefix + '\w*', encodeStr, re.S)
if len(reg) != 0:
table = '操作的表:' + reg[0]
joinTime += table
print(joinTime + ' ' + selectStr)
except KeyboardInterrupt:
os.remove(logpath)
if __name__ == '__main__':
connectMySQL(host, user, password, port, db)
time.sleep(2)
monitor()
講解
首先是需要導入需要使用到的庫
pymysql連接數據庫
re正則匹配
time時間
os系統庫,我這用來獲取路徑
subprocess用于調用終端命令
在開始我們定義一下數據庫信息和日志保存的路徑,我這里是直接使用了腳本當前目錄生成一個名為mysql.log的文件
# 數據庫信息
host = 'localhost'
user = 'root'
password = '123456'
port = 8889
db = 'JCL'
# 表前綴(如果沒有就留空)
prefix = 'xh_'
logpath = os.getcwd() + '/mysql.log'
3.連接數據庫,開啟數據庫的日志,并設置日志輸入目錄和保存類型
def connectMySQL(ip, user, pwd, port, db):
# 開始連接數據庫
connect = pymysql.connect(
host=ip,
user=user,
passwd=pwd,
port=port,
db=db,
charset='utf8'
)
# 獲取游標
cur = connect.cursor()
# 開啟mysql標準日志
cur.execute('set global general_log = on')
connect.commit()
currentPath = 'set global log_output = \'file\''
cur.execute(currentPath)
connect.commit()
cur.execute('set global general_log_file=' + '\'' + logpath + '\'')
connect.commit()
connect.close()
上段代碼中有個'set global log_output = \'file\'',MySQL其實還有個輸出方式是Table,日志會保存到mysql數據庫下的general_log表里面,剛開始我就用的這種方法,想的是待會做數據提取的時候方便,但是使用后發現,好像無法直接清除日志(我沒找到簡單辦法),而且性能沒寫文件好,所以我舍棄了Table使用了File方式,因為沒有直接改動my.cnf,所以在MySQL重啟后,這個設置就消失了.如果需要一直保持的話,可以自己去修改my.cnf.
因為這里連接數據庫的作用只是用來開啟一下設置而已,所以在開啟設置后將數據庫連接關閉掉
4.開始監聽數據,因為linux上有個tail命令就可以直接實時監聽某個文件的變化,所以就直接使用subprocess來調用tail命令
def monitor():
command = 'tail -f ' + logpath
popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
try:
while True:
line = popen.stdout.readline().strip()
encodeStr = bytes.decode(line)
pattern = re.findall('Query\s*(.*)', encodeStr, re.S)
if len(pattern) != 0:
selectStr = pattern[0]
if selectStr != "COMMIT":
joinTime = time.strftime("%H:%M:%S", time.localtime()) + ' '
if prefix != "":
reg = re.findall(r'\b' + prefix + '\w*', encodeStr, re.S)
if len(reg) != 0:
table = '操作的表:' + reg[0]
joinTime += table
print(joinTime + ' ' + selectStr)
except KeyboardInterrupt:
os.remove(logpath)
其中使用了正則表達式篩選了一些非Query的命令,這一段寫了一堆的if自己都覺得惡心,后面再改吧!
最終添加了一個try except來監聽ctrl+c命令,然后將mysql.log文件刪掉!
最后上一張效果圖
QQ20180119-194411@2x.png
文中的正則可能不是特別好,希望對正則比較了解的朋友提點建議,文中有不正確的地方希望大家積極指出,共同進步!
總結
以上是生活随笔為你收集整理的python3 mysql报警日志_Python监听MySQL日志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql safe无法启动_(转)my
- 下一篇: mysql数据迁移 脚本_PHP将数据从