首頁 >後端開發 >Python教學 >開發一個監視位於遠端伺服器上的記錄檔的系統,類似 Unix 指令 tail -f。

開發一個監視位於遠端伺服器上的記錄檔的系統,類似 Unix 指令 tail -f。

Barbara Streisand
Barbara Streisand原創
2024-09-28 22:11:02838瀏覽

Develop a system that monitors a log file located on a remote server, similar to the Unix command tail -f.

這個問題的目標是:
目標是開發一個監視遠端伺服器上日誌檔案的系統,類似於 Unix 命令 tail -f。日誌檔案不斷新增資料。系統應包括:

  1. 一個伺服器應用程序,用於追蹤同一伺服器上指定日誌檔案的持續變更。該應用程式應該能夠將新添加的數據即時傳輸給客戶端。

  2. 基於 Web 的客戶端介面,可透過 URL(例如 http://localhost/log)訪問,旨在動態顯示日誌檔案更新,而不需要使用者重新載入頁面。最初,在造訪該頁面時,使用者應該會看到日誌檔案中的最新 10 行。
    也處理了以下場景:

  3. 伺服器必須主動向客戶端推送更新,以確保最小延遲,以實現盡可能接近即時的更新。

  4. 鑑於日誌檔案可能非常大(可能有幾 GB),您需要製定一種策略來有效取得最後 10 行而不處理整個檔案。

  5. 伺服器應僅將檔案的新新增內容傳輸給客戶端,而不是重新傳送整個檔案。

  6. 伺服器支援來自多個客戶端的並發連接而不降低效能至關重要。

  7. 客戶端的網頁應立即加載,而不是在初始請求後停留在加載狀態,並且不應該需要重新加載來顯示新的更新。

我創建了一個 Flask 應用程序,它具有簡單的 UI,可顯示最後 10 個訊息。

我使用了flask-socketio來形成連接,也使用了處理文件的一些基本概念,如fileObj.seek()、fileObj.tell()等

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from threading import Lock

app = Flask(__name__)
socketio = SocketIO(app)
thread = None
thread_lock = Lock()
LOG_FILE_PATH = "./static/client.txt"
last_position = 0
position_lock = Lock()

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('connect')
def test_connect():
    global thread
    with thread_lock:
        if thread is None:
            print("started execution in background!")
            thread = socketio.start_background_task(target=monitor_log_file)

def monitor_log_file():
    global last_position
    while True:
        try:
            with open(LOG_FILE_PATH, 'rb') as f:
                f.seek(0, 2)
                file_size = f.tell()
                if last_position != file_size:
                    buffer_size = 1024
                    if file_size < buffer_size:
                        buffer_size = file_size
                    f.seek(-buffer_size, 2)
                    lines = f.readlines()
                    last_lines = lines[-10:]
                    content = b'\n'.join(last_lines).decode('utf-8')
                    socketio.sleep(1)  # Add a small delay to prevent high CPU usage
                    socketio.emit('log_updates', {'content': content})
                    print("Emitted new Lines to Client!")
                    last_position = file_size
                else:
                    pass
        except FileNotFoundError:
            print(f"Error: {LOG_FILE_PATH} not found.")
        except Exception as e:
            print(f"Error while reading the file: {e}")

if __name__ == '__main__':
    socketio.run(app, debug=True, log_output=True, use_reloader=False)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Basics</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.4/socket.io.js"></script>
</head>
<body>
<h1>User Updated Files Display it over here:</h1>
<div id="output"></div>

<script>
    var socket = io("http://127.0.0.1:5000");
    socket.on('connect', function() {
        console.log('Connected to the server');
    });
    socket.on('disconnect', function() {
        console.log('Client disconnected');
    });
    socket.on('log_updates', function(data) {
        console.log("data", data);
        var div = document.getElementById('output');
        var lines = data.content.split('\n');
        div.innerHTML = '';
        lines.forEach(function(line) {
            var p = document.createElement('p');
            p.textContent = line;
            div.appendChild(p);
        });
    });
</script>
</body>
</html>

還在 Flask 應用程式的 static 資料夾下建立一個 client.log 檔案。
如果我做錯了什麼,請隨時糾正我。有任何更正請在下面評論!

以上是開發一個監視位於遠端伺服器上的記錄檔的系統,類似 Unix 指令 tail -f。的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn