You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flask和JavaScript实现网页实时展示日志文件变更

Flask实现日志实时更新的问题修复方案

现有代码核心问题

  • Flask默认开启响应缓冲,yield的内容会被缓存到一定大小才推送给前端,无法实时输出
  • Debug模式默认开启的重载器会启动双进程,导致生成器逻辑重复执行,流输出异常
  • 前端XHR直接全量替换文本内容,日志量大时性能差,也没有针对流式响应做增量读取
  • 部分文本编辑器修改日志文件时会直接替换原文件而非追加写入,导致原有打开的文件句柄读取不到新内容

修复后的代码

后端Flask代码

import time
import os
from flask import Flask, render_template

app = Flask(__name__)

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

@app.route('/logs')
def logs():
    def generate():
        # 用绝对路径定位日志文件,避免运行目录不同导致找不到文件
        log_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "log.log")
        with open(log_path, "r", encoding="utf-8") as f:
            # 如果需要模拟标准tail -f效果,默认不展示历史日志,直接从末尾读新增内容,可取消下一行注释
            # f.seek(0, os.SEEK_END)
            while True:
                line = f.readline()
                if not line:
                    time.sleep(0.1)
                    continue
                yield line
    # 核心配置:添加响应头关闭所有缓存,强制流式输出
    headers = {
        "Cache-Control": "no-cache, no-store, must-revalidate",
        "Pragma": "no-cache",
        "Expires": "0",
        "X-Accel-Buffering": "no"
    }
    return app.response_class(generate(), mimetype="text/plain", headers=headers)

if __name__ == "__main__":
    # 关闭重载器避免双进程冲突,保留debug的报错提示能力
    app.run(debug=True, use_reloader=False)

前端模板代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Logs</title>
</head>
<body>
    <p>LOGS</p>
    <pre id="output" style="max-height: 80vh; overflow-y: auto;"></pre>
    <script>
        const output = document.getElementById('output');
        // 用Fetch API流式读取响应,只追加新增内容,性能更高
        fetch('{{ url_for('logs') }}')
        .then(response => {
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            function processChunk({ done, value }) {
                if (done) return;
                // 追加新内容而非全量替换
                output.textContent += decoder.decode(value);
                // 自动滚动到日志底部
                output.scrollTop = output.scrollHeight;
                return reader.read().then(processChunk);
            }
            return reader.read().then(processChunk);
        });
    </script>
</body>
</html>

测试注意事项

  • 测试日志更新时建议用追加写入的方式修改文件,比如执行命令echo "新日志内容" >> log.log,避免用部分编辑器直接保存(部分编辑器会生成新文件替换原文件,导致原有文件句柄失效)
  • 如果需要限制初始加载的历史日志大小,可以在生成器中添加逻辑,初始时只读取日志最后10行,避免大日志首次加载过慢

内容的提问来源于stack exchange,提问作者Glen Veigas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:54:06