這個問題的目標是:
目標是開發一個監視遠端伺服器上日誌檔案的系統,類似於 Unix 命令 tail -f。日誌檔案不斷新增資料。系統應包括:
一個伺服器應用程序,用於追蹤同一伺服器上指定日誌檔案的持續變更。該應用程式應該能夠將新添加的數據即時傳輸給客戶端。
基於 Web 的客戶端介面,可透過 URL(例如 http://localhost/log)訪問,旨在動態顯示日誌檔案更新,而不需要使用者重新載入頁面。最初,在造訪該頁面時,使用者應該會看到日誌檔案中的最新 10 行。
也處理了以下場景:
伺服器必須主動向客戶端推送更新,以確保最小延遲,以實現盡可能接近即時的更新。
鑑於日誌檔案可能非常大(可能有幾 GB),您需要製定一種策略來有效取得最後 10 行而不處理整個檔案。
伺服器應僅將檔案的新新增內容傳輸給客戶端,而不是重新傳送整個檔案。
伺服器支援來自多個客戶端的並發連接而不降低效能至關重要。
客戶端的網頁應立即加載,而不是在初始請求後停留在加載狀態,並且不應該需要重新加載來顯示新的更新。
我創建了一個 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中文網其他相關文章!