【问题标题】:Display the contents of a log file as it is updated在更新时显示日志文件的内容
【发布时间】:2016-06-03 03:02:01
【问题描述】:

我有外部程序,例如 ffmpeg 和 gstreamer 在后台运行并写入日志文件。我想用我的 Flask 应用程序显示此日志的内容,以便用户可以观看日志更新,就像 tail -f job.log 在终端中所做的那样。

我尝试使用<object data="/out.log" type="text/plain"> 指向日志文件,但无法显示数据,或者浏览器告诉我需要插件。

如何在 HTML 页面中嵌入和更新日志文件?

【问题讨论】:

    标签: javascript python flask stream


    【解决方案1】:

    对我来说@davidism 解决方案(已接受的答案)仅适用于 Firefox。它在 Chrome、Brave、Vivaldi 中不起作用。也许后端和前端循环中存在某种不同步?我不知道。

    无论如何,我使用了更简单的解决方案,后端没有循环,前端没有 javascript 循环。也许它“更丑”并且可能会导致一些非常长的日志出现问题,但至少它适用于我使用的每个浏览器。

    @app.route('/stream')
    def stream():
        with open("job.log", "r") as f:
                content = f.read()
        # as you see, file is loaded only once, no loop here, (loop is on frontend side)
        return app.response_class(content, mimetype='text/plain')
    
    <!DOCTYPE html>
    <html>
        <head>
            <!-- page auto-refresh every 10 seconds -->
            <meta http-equiv="refresh" content="10">
            <title>Some title</title>
        </head>
        <body>
            <h1>Log file ...</h1>
            <script>
               // function for adjusting iframe height to log size
                function resizeIframe(obj) {
                  obj.style.height = obj.contentWindow.document.documentElement.scrollHeight + 'px';
                }
              </script>
            <!-- iframe pulls whole file -->
            <iframe src="{{ url_for('stream') }}" frameborder="0" style="overflow:hidden;width:100%" width="100%" frameborder="0" scrolling="no" onload="resizeIframe(this)"></iframe>
        </body>
    </html>
    
    

    如您所见,唯一的 javascript 代码用于将 iframe 高度调整为当前文本大小。

    【讨论】:

      【解决方案2】:

      我正在使用来自 npm 的 frontail 包。

      npm i frontail -g
      frontail /var/log/syslog
      

      访问http://127.0.0.1:9001查看日志

      来源:https://github.com/mthenw/frontail

      这可能不是问题的确切答案(嵌入html页面),但它解决了许多专门寻找的用户的问题

      在更新时显示日志文件的内容

      【讨论】:

        【解决方案3】:

        使用 Flask 视图永久地连续读取文件并流式传输响应。使用 JavaScript 从流中读取并更新页面。此示例发送整个文件,您可能希望在某些时候截断它以节省带宽和内存。此示例在读取之间休眠以减少无限循环的 CPU 负载并允许其他线程有更多的活动时间。

        from time import sleep
        from flask import Flask, render_template
        
        app = Flask(__name__)
        
        @app.route('/')
        def index():
            return render_template('index.html')
        
        @app.route('/stream')
        def stream():
            def generate():
                with open('job.log') as f:
                    while True:
                        yield f.read()
                        sleep(1)
        
            return app.response_class(generate(), mimetype='text/plain')
        
        app.run()
        
        <pre id="output"></pre>
        <script>
            var output = document.getElementById('output');
        
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '{{ url_for('stream') }}');
            xhr.send();
        
            setInterval(function() {
                output.textContent = xhr.responseText;
            }, 1000);
        </script>
        

        这与 this answer 几乎相同,它描述了如何流式传输和解析消息,尽管永远从外部文件读取是新奇的,足以成为它自己的答案。这里的代码更简单,因为我们不关心解析消息或结束流,只是永远拖尾文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-06-01
          • 1970-01-01
          • 2015-10-03
          • 1970-01-01
          • 2016-05-22
          • 1970-01-01
          相关资源
          最近更新 更多