1. 程式人生 > >使用 WebSocket 和 Python 編寫日誌檢視器

使用 WebSocket 和 Python 編寫日誌檢視器

在生產環境運維工作中,檢視線上伺服器日誌是一項常規工作。如果這項工作可以在瀏覽器中進行,而無需登入伺服器執行 tail -f 命令,就太方便了。我們可以使用 WebSocket 技術輕鬆實現這一目標。在本文中,我將帶各位一起使用 Python 編寫一個日誌檢視工具。

基於 WebSocket 的日誌檢視器

WebSocket 簡介

WebSocket 是一個標準化協議,構建在 TCP 之上,能夠在客戶端和服務端之間建立一個全雙工的通訊渠道。這裡的客戶端和服務端通常是使用者瀏覽器和 Web 伺服器。在 WebSocket 誕生之前,如果我們想保持這樣的一個長連線,就需要使用諸如長輪詢、永久幀、Comet 等技術。而現今 WebSocket 已經得到了所有主流瀏覽器的支援,我們可以使用它開發出線上聊天室、遊戲、實時儀表盤等軟體。此外,WebSocket 可以通過 HTTP Upgrade 請求來建立連線,並使用 80 埠通訊,從而降低對現有網路環境的影響,如無需穿越防火牆。

websockets Python 類庫

websockets 是第三方的 Python 類庫,它能基於 Python 提供的 asyncio 包來實現 WebSocket 服務端以及客戶端應用。我們可以使用 pip 來安裝它,要求 Python 3.3 以上的版本。

pip install websockets
# For Python 3.3
pip install asyncio

下面是一段簡單的 Echo 服務程式碼:

import asyncio
import websockets

@asyncio.coroutine
def echo(websocket, path)
:
message = yield from websocket.recv() print('recv', message) yield from websocket.send(message) start_server = websockets.serve(echo, 'localhost', 8765) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()

可以看到,我們使用 Python 的協程來處理客戶端請求。協程是 Python 3.3 引入的新概念,簡單來說,它能通過單個執行緒來實現併發程式設計,主要適用於處理套接字 I/O 請求等場景。Python 3.5 開始又引入了 async

await 關鍵字,方便程式設計師使用協程。以下是使用新關鍵字對 Echo 服務進行改寫:

async def echo(websocket, path):
    message = await websocket.recv()
    await websocket.send(message)

對於客戶端應用,我們直接使用瀏覽器內建的 WebSocket 類。將下面的程式碼直接貼上到 Chrome 瀏覽器的 JavaScript 控制檯中就可以運行了:

let ws = new WebSocket('ws://localhost:8765')
ws.onmessage = (event) => {
  console.log(event.data)
}
ws.onopen = () => {
  ws.send('hello')
}

檢視並監聽日誌

我們將通過以下幾步來構建日誌檢視器:

  • 首先,客戶端發起一個 WebSocket 請求,並將請求的檔案路徑包含在 URL 中,形如 ws://localhost:8765/tmp/build.log?tail=1
  • 服務端接受到請求後,將檔案路徑解析出來,順帶解析出是否要持續監聽日誌的標誌位;
  • 服務端開啟日誌檔案,開始不斷向客戶端傳送日誌檔案內容。

完整的原始碼可以在 GitHub 中檢視,以下只擷取重要的部分:

@asyncio.coroutine
def view_log(websocket, path):
    parse_result = urllib.parse.urlparse(path)
    file_path = os.path.abspath(parse_result.path)
    query = urllib.parse.parse_qs(parse_result.query)
    tail = query and query['tail'] and query['tail'][0] == '1'
    with open(file_path) as f:
        yield from websocket.send(f.read())
        if tail:
            while True:
                content = f.read()
                if content:
                    yield from websocket.send(content)
                else:
                    yield from asyncio.sleep(1)
        else:
            yield from websocket.close()

其它特性

  • 在實際應用中發現,瀏覽器有時不會正確關閉 WebSocket 連線,導致服務端資源浪費,因此我們新增一個簡單的心跳機制:
if time.time() - last_heartbeat > HEARTBEAT_INTERVAL:
    yield from websocket.send('ping')
    pong = yield from asyncio.wait_for(websocket.recv(), 5)
    if pong != 'pong':
        raise Exception('Ping error'))
    last_heartbeat = time.time()
  • 日誌檔案中有時會包含 ANSI 顏色高亮(如日誌級別),我們可以使用 ansi2html 包來將高亮部分轉換成 HTML 程式碼:
from ansi2html import Ansi2HTMLConverter
conv = Ansi2HTMLConverter(inline=True)
yield from websocket.send(conv.convert(content, full=False))
  • 最後,日誌檔案路徑也需要進行許可權檢查,本例中是將客戶端傳遞的路徑轉換成絕對路徑後,簡單判斷了路徑字首,以作許可權控制。

參考資料

相關推薦

使用 WebSocket Python 編寫日誌檢視

在生產環境運維工作中,檢視線上伺服器日誌是一項常規工作。如果這項工作可以在瀏覽器中進行,而無需登入伺服器執行 tail -f 命令,就太方便了。我們可以使用 WebSocket 技術輕鬆實現這一目標。在本文中,我將帶各位一起使用 Python 編寫一個日誌檢視工

使用python編寫遊戲修改

最近比較懷舊,在玩一個比較老的PC遊戲。由於遊戲難度太高了,於是就打算自己寫一個修改器。 通過查閱資料,在 Windows 下的修改器主要需要用到四個函式:OpenProcess, CloseHandle, WriteProcessMemory, ReadProcessMemory。

利用python編寫遊戲修改!俗稱:外掛!

最近比較懷舊,在玩一個比較老的PC遊戲。由於遊戲難度太高了,於是就打算自己寫一個修改器。 通過查閱資料,在 Windows 下的修改器主要需要用到四個函式:OpenProcess, CloseHandle, WriteProcessMemory, ReadProcessMemory。 這幾個

Java 檢視 Java Plug-in 檢視之間的區別

本文中的知識涉及:水晶報表 9適用於:所有版本Java 檢視器比較 大綱 某些 Crystal Decisions 產品提供兩種Java 檢視器: · (智慧) Java 檢視器 · Java Plug-in 檢視器 這兩種檢視器之間的有什麼區別呢? 解決方案 當你選擇“(智

利用kvaserPython編寫監控介面(2)

利用Python,通過kvaser讀取CAN訊號,在DBC翻譯訊號時發生錯誤 錯誤資訊: UnicodeDecodeError:‘utf-8’ codec can’t decode byte … 解決方法: 1、利用文字編輯器(Geany)開啟DBC檔案 2、進行如下設定:“文件”-

利用kvaserPython編寫監控介面(3)

在視窗中列印byte時,特殊現象的解釋 def printframe(frame, width): form = '═^' + str(width - 1) print(format(" Frame received ", form)) print("id:",

基於Html5 websocketPython的線上聊天室

握手協議:request中有三個隨機的key值,頭部有兩個,後面body裡是長度為8位元組的key3(括號裡的文字是提示,還有字元間的冒號也是為了看上去清晰才加上的,真正傳輸是沒有的),以此向server傳送一個challenge,server需要根據這三個key計算出一個token,在響應中發回給clien

嵌入式Linux——應用除錯:自制系統呼叫,並編寫程序檢視

簡介:     本文主要講解在ARM Linux中系統呼叫的原理,並根據這些原理在系統中新增自制的系統呼叫函式,最後我們還將通過自制的系統呼叫函式來檢視應用程式指定位置的資訊,用此方法實現應用程式的除錯。  Linux核心:linux-2.6.22.6  所用開發板

Python——編寫類裝飾

編寫類裝飾器類裝飾器類似於函式裝飾器的概念,但它應用於類,它們可以用於管理類自身,或者用來攔截例項建立呼叫以管理例項。 -----------------------------------------------------------------------------

配置Apache2.x 支援shell指令碼Python編寫CGI程式+測試程式

1.安裝apache <span style="font-size:18px;">[email protected]:~$ aptitude search apache p apache2

自托管websocketwebapi部署雲服務域名及遠程訪問

bapi png 開放 技術分享 登錄 控制臺 限制 .com bsp 當寫完websocket和webapi服務端時,在本地測試時是沒有問題的,因為是通過本地IP及端口號訪問(例:127.0.0.1:8080\api\test),也就沒有防火墻等安全限制,但當部署到

python編寫文件閱讀

python閱讀器最近在學習python老師布置了一個作業寫一個文件閱讀器:要求如下:可上下翻頁有自動翻頁閱讀和手動控制實戰:代碼如下:time tl = [] readers(path,lines=,auto=,times=): (path,) f: f.seek(,)

第四百零五節,centos7下搭建sentry錯誤日誌服務,接收python以及Django錯誤,

rate install 中文 engine some remove master -- 復制 第四百零五節,centos7下搭建sentry錯誤日誌服務器,接收python以及Django錯誤, 通過docker安裝sentry 安裝docker 1.卸載舊版本

查看python iterpreter的路徑當前選擇的解釋

pre div 路徑 body code spa down where logs whereis python which python 查看python iterpreter的路徑和當前選擇的解釋器

Python之叠代生成器

OS 返回 內部 16px fun break 得到 urn b- 叠代器 一 叠代 # 叠代是一個重復的過程,每次重復即一次叠代,並且每次叠代的結果都是下一次叠代的

python之叠代生成器內置函數,匿名函數

提取 gen sys 狀態 elf 返回 led rip 獲取   今天學習了叠代器生成器以及內置函數和匿名函數,說實話有些懵圈,有些難度了。    一、叠代器和生成器 1、如何從列表、字典中取值的: index索引 for循環 凡是可以使用for循環取值的都

python 信息收集CMS識別腳本

name beautiful https all mage jpg st2 host family 前言: 信息收集是滲透測試重要的一部分 這次我總結了前幾次寫的經驗,將其 進化了一下 正文: 信息收集腳本的功能: 1.端口掃描 2.子域名挖掘 3.D

syslog、日誌服務安裝、卸載詳解、如何安裝卸載EventLog Analyzer

技術 src 如何 RoCE analyze sys ESS watermark 詳解 syslog、日誌服務器安裝、卸載詳解、如何安裝和卸載EventLog Analyzer

python的叠代生成器

而是 ... 斐波那契數 聯系 python2.7 如果 s函數 span fibonacci 本文將簡要介紹python中叠代器和生成器的區別與聯系,以下內容基於python2.7環境 1. 可叠代對象與叠代器 1.1 可叠代對象   可叠代對象需要滿足的條件:實

Python日誌產生

win 有一個 mozilla baidu linu lin count oca 狀態 Python日誌產生器 寫在前面 有的時候,可能就是我們做實時數據收集的時候,會有一個頭疼的問題就是,你會發現,你可能一下子,沒有日誌的數據源。所以,我們可以簡單使用python腳本來實