4

我遵循了一个 SO 接受的关于如何从这里从 /var/log/gateway 读取 Django 中的日志文件的答案,并且我设法在终端上输出文件,就像这里一样。

2013-05-09T11:15:02.539091+08:00 localhost gateway[5205]: System starting up...
2013-05-09T12:57:44.160246+08:00 localhost gateway[5205]: System start complete.
2013-05-09T15:13:47.428553+08:00 localhost gateway[4777]: * Unable to connect to device /home/smartsensor1. Device may be offline. *

下一步是,我想输出日志文件并以 html 格式显示,我对原始代码进行了轻微修改,如下所示。

def Logs(request):
    with open('../../../../../var/log/gateway') as f:
        while True:
            line = f.readline()
            if line:
                print line
                return HttpResponse(line)

所以在客户端,我根据另一个 SO 接受的答案在这里放置 Ajax 。

$.ajax({
    type: "GET", 
    url : "{% url WebServiceApp.logging.Logs %}",
    success: function (data) {
            $("#output").append(data);
            setTimeout("doUpdate()", 2000);
    }
});
}

setTimeout("doUpdate()", 2000);

这样,来自 Ajax 的输出数据就会继续显示日志文件的第一行。在这种情况下,是这样的

2013-05-09T11:15:02.539091+08:00 localhost gateway[5205]: System starting up...
2013-05-09T11:15:02.539091+08:00 localhost gateway[5205]: System starting up...
2013-05-09T11:15:02.539091+08:00 localhost gateway[5205]: System starting up...

我知道会发生这种情况,因为每次 ajax 访问服务器时,服务器都会执行它需要做的事情并发送回作为日志文件第一行的输出并通过 HttpResponse 输出并完成循环,但它从来没有机会做另一行,因为它已经完成了。当另一个查询完成时,它会一次又一次地做同样的事情。

所以可能的解决方案是客户端询问服务器一次,服务器保持逐行输出日志文件并将其发送给客户端。我不确定这是否可能,所以在这里我向任何专家询问如何可能实现我可以逐行输出日志文件的结果/

4

2 回答 2

0

好吧,你可以使用这样的想法:

使用GET参数,您可以像这样控制视图的方法:

def Logs(request):
    whole_file = True
    if request.GET.get('whole_file') == 0:
        whole_file = False
    return_string = ''
    with open('../../../../../var/log/gateway') as f:
        while True:
            line = f.readline()
            if line:
                return_string += line + '<br>' # <br> is for breakline html, do it your way
                if not whole_file: break # break if you only need first line
    return HttpResponse(line)

这样,您在 get 参数中包含一个变量,该变量告诉您​​的视图是返回整个日志文件(第一次)还是只返回第一行(下一次)。

然后在您的 ajax 中,您将必须包含一种将GET参数插入 url 的方法。你使用{{url}}标签,我不太确定如何使用它,但我相信你会在文档中找到一些东西,如果你不能尝试其他方法,比如静态字符串(不是很漂亮)或为它创建自己的自定义标签。

这将是您可能的 javascript 的一个示例:

$.ajax({
    type: "GET", 
    url : "/ajax_log/?whole_file=0", //this will request the whole file
    success: function (data) {
            $("#output").append(data);
            setTimeout("doUpdate()", 2000);
    }
});
}

setTimeout("doNextUpdate()", 2000);

function doNextUpdate(){

    $.ajax({
        type: "GET", 
        url : "/ajax_log/?whole_file=1", //this will request the just the first line            success: function (data) {
                $("#output").append(data);
                setTimeout("doUpdate()", 2000);
        }
    });
    }
}

这是我的想法来完成你想要的。我希望它有所帮助。

于 2013-05-10T02:09:08.607 回答
0

我找到了解决此问题的方法是执行 Server-Sent Event

在服务器端,我使用依赖于sse的 django- sse

import os
from django.conf import settings
from django.views.generic import View
from django_sse.views import BaseSseView
import time
from django.utils.timezone import now
from datetime import datetime
from django.utils.timezone import now
from dateutil import parser

class MySseEvents(BaseSseView):
    def iterator(self):
        while True:
            if not os.path.exists('/var/log/gateway'):
                file('/var/log/gateway', 'w+').close()
            with open('/var/log/gateway') as f:
                while True:
                    #get the current time
                    currenttime = now()
                    #read a line from gateway
                    line = f.readline()
                    if line:
                        #split the line read into 4 section
                        str = line.split(' ',3)
                        #compare if the time from the log file is less than the current time
                        logtime = parser.parse(str[0])
                        if logtime >= currenttime:
                            #print when the log is written after the current time
                            output = '%s: %s' % (datetime.strftime(logtime,'%d/%m %H:%M %p'), str[3])
                            self.sse.add_message("line", output)
                            time.sleep(1)
                            yield

我在上面所做的if logtime >= currenttime:检查是确保 html 仅在页面加载后打印出日志,而不是整个日志文件。

然后在 HTML5 方面,我做了类似于作者在我提供的第一个链接上显示的示例。

<div id="tab9" class="tab_content">
    <table>
        <tr>
            <td>
                <p> Shows the records of the logs on gateway.</p>
                <div style="border:1px solid; height: 200px; width: 850px; overflow: auto;" id="output"></div>
            </td>
        </tr>
    </table>
</div>
<script>
$(document).ready(function() {
    var source = new EventSource('/gtwy/logging/');
    var events_dom = $("#output");

    source.addEventListener("line", function(e) {
        events_dom.append(e.data + "<br>");
    });
});
</script>

使用它,我设法显示可用的日志。我面临的唯一问题是创建需要权限的网关文件本身,因为我试图在/var/log.

于 2013-06-19T03:41:43.927 回答