通过源码可以发现,tornado中也是大量使用了python中的logging模块来处理日志操作。但tornado在处理日志的时候,特别是tornado.options.parse_command_line()时将根日志的级别设置为info,这点需要特别注意!如果在tornado.options.parse_command_line()之前程序对logging的日志级别进行了设置,则很有可能会被tornado进行改写,这点需要特别注意。
通过下面的代码可以很容易就能看出tornado对跟logger的级别进行了调整:
import os import ssl import logging from tornado.httpserver import HTTPServer from tornado.web import Application, RequestHandler from tornado.ioloop import IOLoop import tornado.options from tornado.options import define, options LOG = logging.getLogger(__name__) define("port", default=8000, help="run on the given port", type=int) class TestHandler(RequestHandler): def get(self): self.write("Hello, World!\n") application = Application([ (r"/", TestHandler),], debug = True) if __name__ == "__main__": print "main 1 getEffectiveLevel = ", LOG.getEffectiveLevel() print "tornado default log level = "tornado.options.options.logging tornado.options.options.logging = "debug" tornado.options.parse_command_line() print "main getEffectiveLevel = ", LOG.getEffectiveLevel() # server = HTTPServer(application,ssl_options={ # "certfile": os.path.join(os.path.abspath("."), "cert.pem"), # "keyfile": os.path.join(os.path.abspath("."), "privatekey.pem"), # }) server = HTTPServer(applicatio) server.listen(options.port) IOLoop.instance().start()
对根logger的日志级别进行更改主要是tornado的tornado.options所为,源码如下:
def parse_command_line(self, args=None): if args is None: args = sys.argv remaining = [] for i in xrange(1, len(args)): # All things after the last option are command line arguments if not args[i].startswith("-"): remaining = args[i:] break if args[i] == "--": remaining = args[i + 1:] break arg = args[i].lstrip("-") name, equals, value = arg.partition("=") name = name.replace('-', '_') if not name in self: print_help() raise Error('Unrecognized command line option: %r' % name) option = self[name] if not equals: if option.type == bool: value = "true" else: raise Error('Option %r requires a value' % name) option.parse(value) if self.help: print_help() sys.exit(0) # Set up log level and pretty console logging by default if self.logging != 'none': logging.getLogger().setLevel(getattr(logging, self.logging.upper())) enable_pretty_logging() return remaining
# Default options define("help", type=bool, help="show this help information") define("logging", default="info", help=("Set the Python log level. If 'none', tornado won't touch the " "logging configuration."), metavar="debug|info|warning|error|none")
可以看到,tornado.options在parse_command_line的时候,会判断self.logging 是否为none,非none时执行logging.getLogger().setLevel(getattr(logging, self.logging.upper())),也就是对根logger的level进行设置,在tornado.options被import的时候定义了一个logging,parse_command_line的时候将logging的根级别设置为info。
总之,在tornado应用中,应该特别注意logging级别设置同tornado.options.parse_command_line的先后顺序。