我已经写了一个Python脚本,从syslog-ng获取日志条目,并将它们写入MongoDB(我不能用afmongodb驱动程序来做,因为我需要做一些特殊的处理)。
这是在syslog-ng.conf中的样子:
destination d_mongodb_events { program("/home/test/syslog_piper.py" template("$UNIXTIME|$PRIORITY|$FACILITY|$SOURCEIP|$SEQNUM|$PID|$PROGRAM|$MSGONLY\n") flags(no_multi_line) flush_lines(1) flush_timeout(1000) ); };
这是脚本:(删除逻辑)
import sys try: lines = sys.stdin.readlines() for line in lines: # process `line` and save to DB except Exception, e: f = open('/tmp/error.txt','ab') f.write(e) f.close() exit(0)
脚本的作品 – 也就是说,如果我从命令行运行它,它将等待input,并在我按下Ctrl+D立即插入这些行并退出。
使用syslog-ng它是不同的。 条目被传递给脚本,但只有在我停止 syslog-ng守护进程之后。 另外,当syslog-ng运行时,我也看到我的脚本也在运行(在进程列表中)。 我已经尝试设置flush_lines()和flush_timeout() (见上面的configuration),但我不能使syslog-ng刷新其输出。
我的猜测是,我处理pipe道的方式有些问题,但我无法弄清楚。 任何人都可以发现问题吗?
更新 :如果我发送1000条消息,其中一些被推送通过,所以我想有一些缓冲正在进行。 任何人都知道调整哪个设置?
解决scheme :它看起来像Python缓冲大量的input/输出。 这是从手册页:
-u Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xread- lines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.
所以基本上我不得不改变程序使用sys.stdin.readline() 。 非常感谢Janne。
我没有将任何Python脚本挂接到syslog-ng,但是使用Perl脚本,我必须在实时工作之前closures输出缓冲。 在Perl中,这就是$|=1 。
我不是一个Python家伙,但我想用-u运行你的Python脚本或设置variablesPYTHONUNBUFFERED可能会有所帮助。