python運維篇---實時查看liunx後臺日誌(轉)

原文:https://blog.51cto.com/u_12203282/6000840

作者:咪哥雜談

爲啥要用python去做實時監控linux後臺日誌呢,其實是因爲在元旦監控生產環境時發現的詬病,服務器太多導致xshell一開窗口要開好多個,而現在又沒有實現自動化運維的功能,不僅是這樣,若想要查看某臺服務器上的日誌還需要先ctrl + c終止終端(terminal),而查看篩選條件也需要重複性的大量操作,於是想到有沒有可以用python寫個腳本連接到各臺服務器上,監控的同時直接把日誌寫入到本地上。有了想法,實現只是時間問題咯。。。

環境

python3

linux的各種ip以及對應的賬號密碼
第三方庫:paramiko
這裏要說一下,windows下藉助的第三方庫是paramiko這個加密及SSH功能的強大庫,推薦再有網的情況下進行安裝:

pip install paramiko

 

代碼實現

廢話不多說,直接上碼,註釋寫的很詳細,老規矩不多講:

import time
import paramiko
import select
now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
now_day = time.strftime('%Y-%m-%d', time.localtime(time.time()))

#方法複用,連接客戶端通過不同id進來即可
#這個方法是進行非實時的連接返回,例如ls這樣的cmd命令,或者grep這樣的命令。。
def link_server_cmd(serverip,user,pwd):
    print('------------開始連接服務器(%s)-----------' % serverip)
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    print('------------開始認證......-----------')
    client.connect(serverip, 22, username=user, password=pwd, timeout=4)
    print('------------認證成功!.....-----------')
    while 1:
        cmd = input('(輸入linux命令)~:')
        stdin, stdout, stderr = client.exec_command(cmd)
        #enumerate這個寫法可遍歷迭代對象以及對應索引
        for i, line in enumerate(stdout):
            print(line.strip("\n"))
        break
    client.close()

#此方法是進行實時返回,例如tail -f這樣的命令,本次監控就用的是此方法。
#將實時返回的日誌返回到本地
def link_server_client2(serverip, user, pwd):
    # 進行連接
    print('------------開始連接服務器(%s)-----------' % serverip)
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    print('------------開始認證......-----------')
    client.connect(serverip, 22, username=user, password=pwd, timeout=4)
    print('------------認證成功!.....-----------')
    # 開啓channel 管道
    transport = client.get_transport()
    channel = transport.open_session()
    channel.get_pty()
    # 執行命令nohup.log.2017-12-30
    tail = 'tail -f /xxxx/xxxxx/nohuplogs/nohuplogs20180101.log'
    #將命令傳入管道中
    channel.exec_command(tail)
    while True:
        #判斷退出的準備狀態
        if channel.exit_status_ready():
            break
        try:
            # 通過socket進行讀取日誌,個人理解,linux相當於客戶端,我本地相當於服務端請求獲取數據(此處若有理解錯誤,望請指出。。謝謝)
            rl, wl, el = select.select([channel], [], [])
            if len(rl) > 0:
                recv = channel.recv(1024)
                # 此處將獲取的數據解碼成gbk的存入本地日誌
                print(recv.decode('gbk', 'ignore'))
                text_save(recv.decode('gbk', 'ignore'), 'tail(' + serverip + ').txt')
        #鍵盤終端異常
        except KeyboardInterrupt:
            print("Caught control-C")
            channel.send("\x03")  # 發送 ctrl+c
            channel.close()
    client.close()

# 文件存儲
def text_save(self,content, filename, mode='a'):
    # Try to save a list variable in txt file.
    file = open(filename, mode)
    for i in content:
        file.write(i)
    file.close()

結論

結果不言而喻呀,當然是成功了,這裏因爲涉及到隱私問題,就不上傳生產的圖片結果了,有需要的同學可以親測一下,通過這次的代碼需求,感覺對於自己監控而言,確實是方便了不少,在解決channel管道進行實時傳輸數據那裏費時比較多…..因爲對socket編程不是很瞭解,後續繼續看看吧…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章