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