Unix コマンドの tail -f と同様に、リモート サーバー上にあるログ ファイルを監視するシステムを開発します。

Barbara Streisand
リリース: 2024-09-28 22:11:02
オリジナル
797 人が閲覧しました

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. URL (例: http://localhost/log) 経由でアクセス可能な Web ベースのクライアント インターフェイス。ユーザーがページをリロードすることなく、ログ ファイルの更新が発生すると動的に表示するように設計されています。最初に、ページにアクセスすると、ログ ファイルから最新の 10 行が表示されるはずです。
    次のシナリオも処理しました:

  3. サーバーは、遅延を最小限に抑え、可能な限りリアルタイムに近い更新を実現するために、更新をクライアントに積極的にプッシュする必要があります。

  4. ログ ファイルが非常に大きい (可能性としては数ギガバイト) 可能性があることを考慮して、ファイル全体を処理せずに最後の 10 行を効率的にフェッチする戦略を開発する必要があります。

  5. サーバーは、ファイル全体を再送信するのではなく、ファイルに新たに追加した部分のみをクライアントに送信する必要があります。

  6. サーバーがパフォーマンスを低下させることなく複数のクライアントからの同時接続をサポートすることが重要です。

  7. クライアントの 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 サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!