この問題の目的は次のとおりです:
目的は、Unix コマンドの tail -f に似た、リモート サーバーにあるログ ファイルを監視するシステムを開発することです。ログ ファイルには新しいデータが継続的に追加されます。このシステムは以下で構成されます:
同じサーバー上にある指定されたログ ファイルに対する進行中の変更を追跡するサーバー アプリケーション。このアプリケーションは、新しく追加されたデータをクライアントにリアルタイムで送信できる必要があります。
URL (例: http://localhost/log) 経由でアクセス可能な Web ベースのクライアント インターフェイス。ユーザーがページをリロードすることなく、ログ ファイルの更新が発生すると動的に表示するように設計されています。最初に、ページにアクセスすると、ログ ファイルから最新の 10 行が表示されるはずです。
次のシナリオも処理しました:
サーバーは、遅延を最小限に抑え、可能な限りリアルタイムに近い更新を実現するために、更新をクライアントに積極的にプッシュする必要があります。
ログ ファイルが非常に大きい (可能性としては数ギガバイト) 可能性があることを考慮して、ファイル全体を処理せずに最後の 10 行を効率的にフェッチする戦略を開発する必要があります。
サーバーは、ファイル全体を再送信するのではなく、ファイルに新たに追加した部分のみをクライアントに送信する必要があります。
サーバーがパフォーマンスを低下させることなく複数のクライアントからの同時接続をサポートすることが重要です。
クライアントの Web ページは、最初のリクエスト後に読み込み状態に留まらずにすぐに読み込まれる必要があり、新しい更新を表示するために再読み込みする必要はありません。
最後の 10 件のメッセージを表示するシンプルな UI を備えた Flask アプリケーションを作成しました。
私は 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>
フラスコ アプリケーションの静的フォルダーの下に client.log ファイルも作成します。
何か間違ったことをした場合は、遠慮なく修正してください。修正があれば以下にコメントしてください!
以上がUnix コマンドの tail -f と同様に、リモート サーバー上にあるログ ファイルを監視するシステムを開発します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。