无法正确使用apache2的CustomLog配置python日志

1 投票
2 回答
514 浏览
提问于 2025-04-16 12:32

我正在尝试使用Apache的CustomLog指令,把日志信息传递到一个Python脚本里(这个脚本应该能记录到Django后台)。在一个虚拟主机中,我使用了以下的customlog行:

CustomLog "|/usr/bin/python -u /home/rolf/feedmemore/myproject/logger.py > /tmp/out.txt 2> /tmp/err.txt" combined

这是logger.py中的主要循环:

c = sys.stdin.read(1)
line = ""
while True:

    if c:
        line += c
        if ord(c) == 4:
            break
    else:
        sys.stderr.write("huh?\n")

    if c == '\n':
        print line
        logline(line.rstrip('\n'))
        line = ""

    c = sys.stdin.read(1)

起初我以为,如果我从Apache那里用read(1)接收到"",那么程序就应该退出。然而,不管服务器有没有活动,Apache总是不断地发送""。/tmp/err.txt很快就被“huh?”填满了。这是怎么回事呢?

我的日志程序应该怎么知道输入什么时候结束并且该退出了呢?我试着检查0x4(EOT),但那也不管用。

我第一次尝试使用“readline()”,但结果也一样失败。

如果有其他关于如何在Django中集中记录请求的建议,那也会很有帮助。

2 个回答

0

我想说的是,你最后一句话提到的内容。你可能不想为每个请求都运行一个Python脚本。这样做的话,你要用一个大约20MB的程序来读取一行文本,实在是太浪费了。

建议你了解一下现代的系统日志工具,比如syslog-ng。你现在的做法成本太高了,而实际上你只需要一个很简单的解决方案。

http://www.balabit.com/sites/default/files/documents/syslog-ng-admin-guide_en.html/configuring_destinations_tcpudp.html

0

我已经搞定了。Apache在停止的时候会关闭标准输入,所以你只需要在主循环中等到sys.stdin.closed变成True,然后忽略空字符串就可以了。

奇怪的是,现在Apache会多出一个僵尸日志进程。因为这个僵尸进程的父进程ID是1,所以如果代码发现自己的父进程ID是1,就会直接退出。

这个方法对我有效:

if os.getppid() == 1:
    sys.exit()
c = sys.stdin.read(1)
line = ""
while not sys.stdin.closed:
    if c:
        line += c

    if c == '\n':
        print line,
        logline(line.rstrip('\n'))
        line = ""

    c = sys.stdin.read(1)

撰写回答