显示更新日志文件的内容

时间:2016-02-21 19:27:31

标签: javascript python flask stream

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

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

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

3 个答案:

答案 0 :(得分:17)

使用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几乎相同,后者描述了如何流式传输和解析消息,尽管永远从外部文件中读取新内容足以成为它自己的答案。这里的代码更简单,因为我们不关心解析消息或结束流,只是永远拖尾文件。

答案 1 :(得分:2)

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

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

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

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

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

  

显示更新日志文件的内容

答案 2 :(得分:0)

对我来说@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 高度调整为当前文本大小。