tornado總結10-日誌配置

tornado源代碼分析

打開site-packages/tornado/log.py,最開頭的註釋文檔說明了tornado的日誌模塊是直接和logging模塊集成的python

"""Logging support for Tornado.

Tornado uses three logger streams:

* ``tornado.access``: Per-request logging for Tornado's HTTP servers (and
  potentially other servers in the future)
* ``tornado.application``: Logging of errors from application code (i.e.
  uncaught exceptions from callbacks)
* ``tornado.general``: General-purpose logging, including any errors
  or warnings from Tornado itself.

These streams may be configured independently using the standard library's
`logging` module.  For example, you may wish to send ``tornado.access`` logs
to a separate file for analysis.
"""

其中一共用到了三種被命名的loggerweb

access_log = logging.getLogger("tornado.access")
app_log = logging.getLogger("tornado.application")
gen_log = logging.getLogger("tornado.general")

access_log 用於記錄每個訪問請求app

app_log 用於記錄程序運行過程當中,全部未被處理的異常ide

gen_log 用於記錄tornado本身運行過程當中報的錯誤和警告tornado

 

 

自定義訪問日誌格式

先看下tornado的源代碼,access_log是在tornado.web.RequestHandler中調用的,打開site-packages/tornado/web.py, 日誌是在請求完成時調用log_request完成的post

def log_request(self, handler):
    """Writes a completed HTTP request to the logs.

    By default writes to the python root logger.  To change
    this behavior either subclass Application and override this method,
    or pass a function in the application settings dictionary as
    ``log_function``.
    """
    if "log_function" in self.settings:
        self.settings["log_function"](handler)
        return
    if handler.get_status() < 400:
        log_method = access_log.info
    elif handler.get_status() < 500:
        log_method = access_log.warning
    else:
        log_method = access_log.error
    request_time = 1000.0 * handler.request.request_time()
    log_method("%d %s %.2fms", handler.get_status(),
               handler._request_summary(), request_time)

其中的日誌格式是由handler._request_summary()來決定的this

def _request_summary(self):
    return "%s %s (%s)" % (self.request.method, self.request.uri,
                           self.request.remote_ip)

所以咱們只須要繼承tornado.web.RequestHandler,而後重寫_request_summary就能夠配置本身的access_log格式了,下面是我本身寫的一個BaseHandlerspa

class BaseHandler(tornado.web.RequestHandler):
    def __init__(self, application, request, **kwargs):
        super(BaseHandler, self).__init__(application, request)
        self._operator_name = 'NO_LOGIN'

    def _request_summary(self):
        if self.request.method == 'post':
            return "%s %s (%s@%s)" % (self.request.method, self.request.uri,
                                      self._operator_name, self.request.remote_ip)

        return "%s %s %s(%s@%s)" % (self.request.method, self.request.uri, self.request.body.decode(),
                                  self._operator_name, self.request.remote_ip)

BaseHandler重寫了_request_summary,並給日誌增長了操做者信息和遠端IP信息日誌

 

使用配置檔初始化

一個logging.yaml例子,這裏只配置了tornado.access,其中的logs文件夾須要手動創建code

version: 1

loggers:
  root:
    level: DEBUG
    handlers: [console]
  tornado:
    level: DEBUG
    handlers: [console,log]
    propagate: no
  tornado.access:
    level: DEBUG
    handlers: [console, access]
    propagate: no
  log:
    level: DEBUG
    handlers: [console,log]
    propagate: no

formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
  timedRotating:
    format: '%(asctime)s %(name)-12s %(levelname)-8s - %(message)s'

handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
  access:
    class: logging.handlers.TimedRotatingFileHandler
    level: DEBUG
    formatter: simple
    filename: 'logs/access.log'
    when: 'midnight'
    interval: 1
    backupCount: 180
  log:
    class: logging.handlers.TimedRotatingFileHandler
    level: DEBUG
    formatter: timedRotating
    filename: 'logs/log.log'
    when: 'midnight'
    interval: 1
    backupCount: 180
    encoding: 'utf8'

tornado初始化以前記得初始化log配置

log_config = yaml.load(open('logging.yaml', 'r'))
logging.config.dictConfig(log_config)
相關文章
相關標籤/搜索