1.. _aiohttp-logging: 2 3Logging 4======= 5 6.. currentmodule:: aiohttp 7 8 9*aiohttp* uses standard :mod:`logging` for tracking the 10library activity. 11 12We have the following loggers enumerated by names: 13 14- ``'aiohttp.access'`` 15- ``'aiohttp.client'`` 16- ``'aiohttp.internal'`` 17- ``'aiohttp.server'`` 18- ``'aiohttp.web'`` 19- ``'aiohttp.websocket'`` 20 21You may subscribe to these loggers for getting logging messages. The 22page does not provide instructions for logging subscribing while the 23most friendly method is :func:`logging.config.dictConfig` for 24configuring whole loggers in your application. 25 26Logging does not work out of the box. It requires at least minimal ``'logging'`` 27configuration. 28Example of minimal working logger setup:: 29 30 import logging 31 from aiohttp import web 32 33 app = web.Application() 34 logging.basicConfig(level=logging.DEBUG) 35 web.run_app(app, port=5000) 36 37.. versionadded:: 4.0.0 38 39Access logs 40----------- 41 42Access logs are enabled by default. If the `debug` flag is set, and the default 43logger ``'aiohttp.access'`` is used, access logs will be output to 44:obj:`~sys.stderr` if no handlers are attached. 45Furthermore, if the default logger has no log level set, the log level will be 46set to :obj:`logging.DEBUG`. 47 48This logging may be controlled by :meth:`aiohttp.web.AppRunner` and 49:func:`aiohttp.web.run_app`. 50 51To override the default logger, pass an instance of :class:`logging.Logger` to 52override the default logger. 53 54.. note:: 55 56 Use ``web.run_app(app, access_log=None)`` to disable access logs. 57 58 59In addition, *access_log_format* may be used to specify the log format. 60 61.. _aiohttp-logging-access-log-format-spec: 62 63Format specification 64^^^^^^^^^^^^^^^^^^^^ 65 66The library provides custom micro-language to specifying info about 67request and response: 68 69+--------------+---------------------------------------------------------+ 70| Option | Meaning | 71+==============+=========================================================+ 72| ``%%`` | The percent sign | 73+--------------+---------------------------------------------------------+ 74| ``%a`` | Remote IP-address | 75| | (IP-address of proxy if using reverse proxy) | 76+--------------+---------------------------------------------------------+ 77| ``%t`` | Time when the request was started to process | 78+--------------+---------------------------------------------------------+ 79| ``%P`` | The process ID of the child that serviced the request | 80+--------------+---------------------------------------------------------+ 81| ``%r`` | First line of request | 82+--------------+---------------------------------------------------------+ 83| ``%s`` | Response status code | 84+--------------+---------------------------------------------------------+ 85| ``%b`` | Size of response in bytes, including HTTP headers | 86+--------------+---------------------------------------------------------+ 87| ``%T`` | The time taken to serve the request, in seconds | 88+--------------+---------------------------------------------------------+ 89| ``%Tf`` | The time taken to serve the request, in seconds | 90| | with fraction in %.06f format | 91+--------------+---------------------------------------------------------+ 92| ``%D`` | The time taken to serve the request, in microseconds | 93+--------------+---------------------------------------------------------+ 94| ``%{FOO}i`` | ``request.headers['FOO']`` | 95+--------------+---------------------------------------------------------+ 96| ``%{FOO}o`` | ``response.headers['FOO']`` | 97+--------------+---------------------------------------------------------+ 98 99The default access log format is:: 100 101 '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' 102 103.. versionadded:: 2.3.0 104 105*access_log_class* introduced. 106 107Example of a drop-in replacement for the default access logger:: 108 109 from aiohttp.abc import AbstractAccessLogger 110 111 class AccessLogger(AbstractAccessLogger): 112 113 def log(self, request, response, time): 114 self.logger.info(f'{request.remote} ' 115 f'"{request.method} {request.path} ' 116 f'done in {time}s: {response.status}') 117 118 119.. _gunicorn-accesslog: 120 121Gunicorn access logs 122^^^^^^^^^^^^^^^^^^^^ 123When `Gunicorn <http://docs.gunicorn.org/en/latest/index.html>`_ is used for 124:ref:`deployment <aiohttp-deployment-gunicorn>`, its default access log format 125will be automatically replaced with the default aiohttp's access log format. 126 127If Gunicorn's option access_logformat_ is 128specified explicitly, it should use aiohttp's format specification. 129 130Gunicorn's access log works only if accesslog_ is specified explicitly in your 131config or as a command line option. 132This configuration can be either a path or ``'-'``. If the application uses 133a custom logging setup intercepting the ``'gunicorn.access'`` logger, 134accesslog_ should be set to ``'-'`` to prevent Gunicorn to create an empty 135access log file upon every startup. 136 137 138 139 140Error logs 141---------- 142 143:mod:`aiohttp.web` uses a logger named ``'aiohttp.server'`` to store errors 144given on web requests handling. 145 146This log is enabled by default. 147 148To use a different logger name, pass *logger* (:class:`logging.Logger` 149instance) to the :meth:`aiohttp.web.AppRunner` constructor. 150 151 152.. _access_logformat: 153 http://docs.gunicorn.org/en/stable/settings.html#access-log-format 154 155.. _accesslog: 156 http://docs.gunicorn.org/en/stable/settings.html#accesslog 157