通過源碼可以發現,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的先后順序。
