Unix 명령 tail -f와 유사하게 원격 서버에 있는 로그 파일을 모니터링하는 시스템을 개발합니다.

Barbara Streisand
풀어 주다: 2024-09-28 22:11:02
원래의
814명이 탐색했습니다.

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)을 통해 접속할 수 있는 웹 기반 클라이언트 인터페이스로, 사용자가 페이지를 다시 로드할 필요 없이 로그 파일 업데이트가 발생할 때 이를 동적으로 표시하도록 설계되었습니다. 처음에 페이지를 방문하면 사용자는 로그 파일에서 가장 최근 10줄을 보게 됩니다.
    다음 시나리오도 처리했습니다.

  3. 서버는 지연을 최소화하고 최대한 실시간에 가까운 업데이트를 달성하기 위해 클라이언트에 적극적으로 업데이트를 푸시해야 합니다.

  4. 로그 파일이 매우 클 수 있다는 점을 고려하면(수 기가바이트에 달할 수 있음) 전체 파일을 처리하지 않고 마지막 10줄을 효율적으로 가져오기 위한 전략을 개발해야 합니다.

  5. 서버는 파일 전체를 다시 보내기보다는 파일에 새로 추가된 내용만 클라이언트에 전송해야 합니다.

  6. 서버가 성능 저하 없이 여러 클라이언트의 동시 연결을 지원하는 것이 중요합니다.

  7. 클라이언트의 웹페이지는 최초 요청 이후 로딩 상태를 유지하지 않고 즉시 로딩되어야 하며, 새로운 업데이트를 표시하기 위해 다시 로딩할 필요가 있어서는 안 됩니다.

최근 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>
로그인 후 복사

Flask 애플리케이션의 static 폴더 아래에 client.log 파일도 생성하세요.
내가 뭔가 잘못한 것이 있으면 언제든지 바로잡아 주시기 바랍니다. 수정 사항이 있으면 아래에 댓글을 달아주세요!

위 내용은 Unix 명령 tail -f와 유사하게 원격 서버에 있는 로그 파일을 모니터링하는 시스템을 개발합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿