Tornado - 应用程序和请求日志如何工作?

4 投票
1 回答
1347 浏览
提问于 2025-04-18 07:15

我正在使用tornado 3.2.1、python 2.7.3和supervisord 3.0,在AWS EC2上运行Amazon Linux AMI。

我想要实现请求级别的日志记录,比如“200 POST / (127.0.0.1) 0.75ms”(这就是请求级别日志的定义,对吧?),希望这些信息能写入一个日志文件,而异常的堆栈跟踪信息则写入另一个日志文件。我从这里看到,Tornado有三种可能的日志可用,理想情况下,我也希望从那个普通日志中输出的信息能写入另一个文件。我了解到,最好是让supervisord(或者其他工具,而不是Tornado)来处理日志文件的写入。

我的supervisord配置文件看起来是这样的:

[unix_http_server]
file=/var/lib/supervisor/supervisor.sock   ; (the path to the socket file)

[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10           ; (num of main logfile rotation backups;default 10)
loglevel=info                ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false               ; (start in foreground if true;default false)
minfds=1024                  ; (min. avail startup file descriptors;default 1024)
minprocs=200                 ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/lib/supervisor/supervisor.sock ; use a unix:// URL  for a unix socket

[include]
files=supervisord.d/*.ini

这是我的应用程序supervisord ini文件:

[program:myapp]
process_name=myapp%(process_num)s
directory=/opt/me/venvs/myapp
command=/opt/me/venvs/myapp/bin/python /opt/me/venvs/myapp/bin/run_myapp.py --port=%(process_num)s --logging=DEBUG
startsecs=2
user=me
stdout_logfile=/var/log/myapp/access-%(process_num)s.log
stderr_logfile=/var/log/myapp/error-%(process_num)s.log
numprocs=2
numprocs_start=14000

在run_myapp.py的底部,我有这个代码片段:

if __name__ == "__main__":
    tornado.options.define("port", default=7777, help="run on the given port", type=int)
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(tornado.options.options.port)
    tornado.ioloop.IOLoop.instance().start()

看起来发生的情况是,请求级别的信息、堆栈跟踪,以及使用logging.info('doing something...')的记录,都会被写入supervisord的stderr_logfile指定的文件中。而stdout_logfile则没有记录任何内容。只有当我在代码中实际放入print语句,并使用sys.stdout.flush()来刷新缓冲区(或者用-u标志启动python)时,才能让stdout_logfile记录到任何内容。

那么,正确的方式是什么,才能将请求的日志记录到stdout_logfile,将堆栈跟踪和其他应用级别的输出记录到stderr_logfile?我想问题的第二部分已经解决了,因为它已经在做这个,但第一部分到现在为止还没有解决。

1 个回答

0

Tornado自带的日志配置在解析命令行时,无法帮助你分开不同的日志流。你需要把tornado.options.options.logging设置为None,然后直接在Python的日志模块中自己管理配置。

Supervisord只能处理两个日志文件(标准输出和标准错误),所以你不能既让supervisord处理你的日志文件,又想要更细致的分离。不过,你可以有两个日志流。你可以把tornado.access日志设置为写入标准输出,并且设置propagate=False,然后把根日志设置为写入标准错误。这样,你就可以在supervisord中为这两个日志流指定不同的输出文件。

撰写回答