无法正确使用apache2的CustomLog配置python日志
我正在尝试使用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。你现在的做法成本太高了,而实际上你只需要一个很简单的解决方案。
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)