python監控伺服器應用日誌,推送釘釘機器人,實時關注日誌異常

MELODY_FENG發表於2020-07-18

生產環境多臺伺服器上部署了多個應用,日誌出現報錯時,無法及時反饋到開發人員。部署一個大型的運維監控應用,不但耗資源,而且配置也不簡單。

簡簡單單寫個python指令碼來監控伺服器日誌就簡單多了,廢話不多說,直接上指令碼。

主要邏輯:

1. 使用python的subprocess模組,執行shell命令,“tail -f” 來監聽日誌檔案

2. 對輸出的日誌檔案,逐行比對字串,如果匹配到預設的字串則開始記錄,keywords中配置需要預設的異常字串

3. 開始記錄日誌至陣列中,可通過rows來預設記錄多少條,達到規定數量後

4. 將日誌內容通過http傳送給釘釘伺服器,釘釘機器人就會在群裡通知我們啦

簡單,高效,實時

#!/usr/bin/python
# encoding=utf-8
# Filename: monitorLog.py
import os
import signal
import subprocess
import time
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import requests
import json
import threading

serverName="prod:192.168.100.20"

#日誌檔案路徑地址
logFiles =[
"/opt/app/mall/mall-admin/logs/mall-admin-0.0.1-SNAPSHOT.log",
"/opt/app/mall/mall-portal/logs/mall-portal-0.0.1-SNAPSHOT.log"
];

#機器人回撥地址 , 釘釘群裡新增一個機器人就可以了
webhook = 'https://oapi.dingtalk.com/robot/send?access_token=38670255eb92cd3a8ce94732fd785dc753134fc1c4d69141f56e942a5d453e5b'

#日誌快取資料
logs = []

#記錄日誌行數,從匹配行開始記錄,到達數量就用推給釘釘機器人
rows = 2

# 是否開始記錄日誌標記位
recordFlags = []

# 檢測的關鍵字陣列,大小寫敏感
keywords = []
keywords.append("threw exception")
keywords.append("java.lang.NullPointerException")
keywords.append("com.macro.mall.exception.ApiRRException")
keywords.append("SocketTimeoutException")

#訊息內容,url地址
def dingtalk(msg,webhook):
    headers = {'Content-Type': 'application/json; charset=utf-8'}
    data = {'msgtype': 'text', 'text': {'content': msg}, 'at': {'atMobiles': [], 'isAtAll': False}}
    post_data = json.dumps(data)
    response = requests.post(webhook, headers=headers, data=post_data)
    return response.text



# 檢查行
def checkLine(line, index):
    curLog = logs[index]
    if recordFlags[index]==1:
        curLog.append(line)
        if len(curLog)>rows:
            content = "\n".join('%s' %id for id in curLog)
            print(content)
            dingtalk(content,webhook)
            recordFlags[index] = 0
            logs[index]=[]
    else:
        for keyword in keywords:
            if keyword in line:
                recordFlags[index] = 1
                curLog.append(serverName)
                curLog.append(logFiles[index])
                curLog.append(line)
                break

#日誌檔案一般是按天產生,則通過在程式中判斷檔案的產生日期與當前時間,更換監控的日誌檔案
#程式只是簡單的示例一下,監控test1.log 10秒,轉向監控test2.log
def monitorLog(logFile, index):
    #print('監控的日誌檔案 是%s' % logFile)
    popen = subprocess.Popen('tail -f ' + logFile, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    pid = popen.pid
    print('Popen.pid:' + str(pid))
    while True:
        line = popen.stdout.readline().strip()
        # 判斷內容是否為空
        if line:
            #print line
            checkLine(str(line), index)

if __name__ == '__main__':
    for index, logFile in enumerate(logFiles):
        logs.append([])
        recordFlags.append(0)
        tt = threading.Thread(target=monitorLog,args=(logFile,index))
        tt.start()
        print ("monitor:"+str(logFile))

  

相關文章