We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
web access log show utc time instead local time with timezone.
## Long story short
in web_.log.py:
```
    def _format_t(request: BaseRequest,
                  response: StreamResponse,
                  time: float) -> str:
        now = datetime.datetime.utcnow()
        start_time = now - datetime.timedelta(seconds=time)
        return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')
```
the logged time is fixed and is a utc time, not a local time. there's not a easy way to setting it.

## Expected behaviour

```
INFO:aiohttp.access:127.0.0.1 [18/Jun/2019:04:56:22 -8]
```
## Actual behaviour

```
INFO:aiohttp.access:127.0.0.1 [18/Jun/2019:04:56:22 +0000]
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/web_log.py`
Content:
```
1 import datetime
2 import functools
3 import logging
4 import os
5 import re
6 from collections import namedtuple
7 from typing import Callable, Dict, Iterable, List, Tuple  # noqa
8 
9 from .abc import AbstractAccessLogger
10 from .web_request import BaseRequest
11 from .web_response import StreamResponse
12 
13 KeyMethod = namedtuple('KeyMethod', 'key method')
14 
15 
16 class AccessLogger(AbstractAccessLogger):
17     """Helper object to log access.
18 
19     Usage:
20         log = logging.getLogger("spam")
21         log_format = "%a %{User-Agent}i"
22         access_logger = AccessLogger(log, log_format)
23         access_logger.log(request, response, time)
24 
25     Format:
26         %%  The percent sign
27         %a  Remote IP-address (IP-address of proxy if using reverse proxy)
28         %t  Time when the request was started to process
29         %P  The process ID of the child that serviced the request
30         %r  First line of request
31         %s  Response status code
32         %b  Size of response in bytes, including HTTP headers
33         %T  Time taken to serve the request, in seconds
34         %Tf Time taken to serve the request, in seconds with floating fraction
35             in .06f format
36         %D  Time taken to serve the request, in microseconds
37         %{FOO}i  request.headers['FOO']
38         %{FOO}o  response.headers['FOO']
39         %{FOO}e  os.environ['FOO']
40 
41     """
42     LOG_FORMAT_MAP = {
43         'a': 'remote_address',
44         't': 'request_start_time',
45         'P': 'process_id',
46         'r': 'first_request_line',
47         's': 'response_status',
48         'b': 'response_size',
49         'T': 'request_time',
50         'Tf': 'request_time_frac',
51         'D': 'request_time_micro',
52         'i': 'request_header',
53         'o': 'response_header',
54     }
55 
56     LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"'
57     FORMAT_RE = re.compile(r'%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)')
58     CLEANUP_RE = re.compile(r'(%[^s])')
59     _FORMAT_CACHE = {}  # type: Dict[str, Tuple[str, List[KeyMethod]]]
60 
61     def __init__(self, logger: logging.Logger,
62                  log_format: str=LOG_FORMAT) -> None:
63         """Initialise the logger.
64 
65         logger is a logger object to be used for logging.
66         log_format is a string with apache compatible log format description.
67 
68         """
69         super().__init__(logger, log_format=log_format)
70 
71         _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format)
72         if not _compiled_format:
73             _compiled_format = self.compile_format(log_format)
74             AccessLogger._FORMAT_CACHE[log_format] = _compiled_format
75 
76         self._log_format, self._methods = _compiled_format
77 
78     def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]:
79         """Translate log_format into form usable by modulo formatting
80 
81         All known atoms will be replaced with %s
82         Also methods for formatting of those atoms will be added to
83         _methods in appropriate order
84 
85         For example we have log_format = "%a %t"
86         This format will be translated to "%s %s"
87         Also contents of _methods will be
88         [self._format_a, self._format_t]
89         These method will be called and results will be passed
90         to translated string format.
91 
92         Each _format_* method receive 'args' which is list of arguments
93         given to self.log
94 
95         Exceptions are _format_e, _format_i and _format_o methods which
96         also receive key name (by functools.partial)
97 
98         """
99         # list of (key, method) tuples, we don't use an OrderedDict as users
100         # can repeat the same key more than once
101         methods = list()
102 
103         for atom in self.FORMAT_RE.findall(log_format):
104             if atom[1] == '':
105                 format_key1 = self.LOG_FORMAT_MAP[atom[0]]
106                 m = getattr(AccessLogger, '_format_%s' % atom[0])
107                 key_method = KeyMethod(format_key1, m)
108             else:
109                 format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1])
110                 m = getattr(AccessLogger, '_format_%s' % atom[2])
111                 key_method = KeyMethod(format_key2,
112                                        functools.partial(m, atom[1]))
113 
114             methods.append(key_method)
115 
116         log_format = self.FORMAT_RE.sub(r'%s', log_format)
117         log_format = self.CLEANUP_RE.sub(r'%\1', log_format)
118         return log_format, methods
119 
120     @staticmethod
121     def _format_i(key: str,
122                   request: BaseRequest,
123                   response: StreamResponse,
124                   time: float) -> str:
125         if request is None:
126             return '(no headers)'
127 
128         # suboptimal, make istr(key) once
129         return request.headers.get(key, '-')
130 
131     @staticmethod
132     def _format_o(key: str,
133                   request: BaseRequest,
134                   response: StreamResponse,
135                   time: float) -> str:
136         # suboptimal, make istr(key) once
137         return response.headers.get(key, '-')
138 
139     @staticmethod
140     def _format_a(request: BaseRequest,
141                   response: StreamResponse,
142                   time: float) -> str:
143         if request is None:
144             return '-'
145         ip = request.remote
146         return ip if ip is not None else '-'
147 
148     @staticmethod
149     def _format_t(request: BaseRequest,
150                   response: StreamResponse,
151                   time: float) -> str:
152         now = datetime.datetime.utcnow()
153         start_time = now - datetime.timedelta(seconds=time)
154         return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')
155 
156     @staticmethod
157     def _format_P(request: BaseRequest,
158                   response: StreamResponse,
159                   time: float) -> str:
160         return "<%s>" % os.getpid()
161 
162     @staticmethod
163     def _format_r(request: BaseRequest,
164                   response: StreamResponse,
165                   time: float) -> str:
166         if request is None:
167             return '-'
168         return '%s %s HTTP/%s.%s' % (request.method, request.path_qs,
169                                      request.version.major,
170                                      request.version.minor)
171 
172     @staticmethod
173     def _format_s(request: BaseRequest,
174                   response: StreamResponse,
175                   time: float) -> int:
176         return response.status
177 
178     @staticmethod
179     def _format_b(request: BaseRequest,
180                   response: StreamResponse,
181                   time: float) -> int:
182         return response.body_length
183 
184     @staticmethod
185     def _format_T(request: BaseRequest,
186                   response: StreamResponse,
187                   time: float) -> str:
188         return str(round(time))
189 
190     @staticmethod
191     def _format_Tf(request: BaseRequest,
192                    response: StreamResponse,
193                    time: float) -> str:
194         return '%06f' % time
195 
196     @staticmethod
197     def _format_D(request: BaseRequest,
198                   response: StreamResponse,
199                   time: float) -> str:
200         return str(round(time * 1000000))
201 
202     def _format_line(self,
203                      request: BaseRequest,
204                      response: StreamResponse,
205                      time: float) -> Iterable[Tuple[str,
206                                                     Callable[[BaseRequest,
207                                                               StreamResponse,
208                                                               float],
209                                                              str]]]:
210         return [(key, method(request, response, time))
211                 for key, method in self._methods]
212 
213     def log(self,
214             request: BaseRequest,
215             response: StreamResponse,
216             time: float) -> None:
217         try:
218             fmt_info = self._format_line(request, response, time)
219 
220             values = list()
221             extra = dict()
222             for key, value in fmt_info:
223                 values.append(value)
224 
225                 if key.__class__ is str:
226                     extra[key] = value
227                 else:
228                     k1, k2 = key
229                     dct = extra.get(k1, {})
230                     dct[k2] = value  # type: ignore
231                     extra[k1] = dct  # type: ignore
232 
233             self.logger.info(self._log_format % tuple(values), extra=extra)
234         except Exception:
235             self.logger.exception("Error in logging")
236
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/aiohttp/web_log.py b/aiohttp/web_log.py
--- a/aiohttp/web_log.py
+++ b/aiohttp/web_log.py
@@ -4,6 +4,7 @@
 import os
 import re
 from collections import namedtuple
+from time import timezone
 from typing import Callable, Dict, Iterable, List, Tuple  # noqa
 
 from .abc import AbstractAccessLogger
@@ -149,9 +150,10 @@
     def _format_t(request: BaseRequest,
                   response: StreamResponse,
                   time: float) -> str:
-        now = datetime.datetime.utcnow()
+        tz = datetime.timezone(datetime.timedelta(seconds=-timezone))
+        now = datetime.datetime.now(tz)
         start_time = now - datetime.timedelta(seconds=time)
-        return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')
+        return start_time.strftime('[%d/%b/%Y:%H:%M:%S %z]')
 
     @staticmethod
     def _format_P(request: BaseRequest,

{"golden_diff": "diff --git a/aiohttp/web_log.py b/aiohttp/web_log.py\n--- a/aiohttp/web_log.py\n+++ b/aiohttp/web_log.py\n@@ -4,6 +4,7 @@\n import os\n import re\n from collections import namedtuple\n+from time import timezone\n from typing import Callable, Dict, Iterable, List, Tuple  # noqa\n \n from .abc import AbstractAccessLogger\n@@ -149,9 +150,10 @@\n     def _format_t(request: BaseRequest,\n                   response: StreamResponse,\n                   time: float) -> str:\n-        now = datetime.datetime.utcnow()\n+        tz = datetime.timezone(datetime.timedelta(seconds=-timezone))\n+        now = datetime.datetime.now(tz)\n         start_time = now - datetime.timedelta(seconds=time)\n-        return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')\n+        return start_time.strftime('[%d/%b/%Y:%H:%M:%S %z]')\n \n     @staticmethod\n     def _format_P(request: BaseRequest,\n", "issue": "web access log show utc time instead local time with timezone.\n## Long story short\r\nin web_.log.py:\r\n```\r\n    def _format_t(request: BaseRequest,\r\n                  response: StreamResponse,\r\n                  time: float) -> str:\r\n        now = datetime.datetime.utcnow()\r\n        start_time = now - datetime.timedelta(seconds=time)\r\n        return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')\r\n```\r\nthe logged time is fixed and is a utc time, not a local time. there's not a easy way to setting it.\r\n\r\n## Expected behaviour\r\n\r\n```\r\nINFO:aiohttp.access:127.0.0.1 [18/Jun/2019:04:56:22 -8]\r\n```\r\n## Actual behaviour\r\n\r\n```\r\nINFO:aiohttp.access:127.0.0.1 [18/Jun/2019:04:56:22 +0000]\r\n```\n", "before_files": [{"content": "import datetime\nimport functools\nimport logging\nimport os\nimport re\nfrom collections import namedtuple\nfrom typing import Callable, Dict, Iterable, List, Tuple  # noqa\n\nfrom .abc import AbstractAccessLogger\nfrom .web_request import BaseRequest\nfrom .web_response import StreamResponse\n\nKeyMethod = namedtuple('KeyMethod', 'key method')\n\n\nclass AccessLogger(AbstractAccessLogger):\n    \"\"\"Helper object to log access.\n\n    Usage:\n        log = logging.getLogger(\"spam\")\n        log_format = \"%a %{User-Agent}i\"\n        access_logger = AccessLogger(log, log_format)\n        access_logger.log(request, response, time)\n\n    Format:\n        %%  The percent sign\n        %a  Remote IP-address (IP-address of proxy if using reverse proxy)\n        %t  Time when the request was started to process\n        %P  The process ID of the child that serviced the request\n        %r  First line of request\n        %s  Response status code\n        %b  Size of response in bytes, including HTTP headers\n        %T  Time taken to serve the request, in seconds\n        %Tf Time taken to serve the request, in seconds with floating fraction\n            in .06f format\n        %D  Time taken to serve the request, in microseconds\n        %{FOO}i  request.headers['FOO']\n        %{FOO}o  response.headers['FOO']\n        %{FOO}e  os.environ['FOO']\n\n    \"\"\"\n    LOG_FORMAT_MAP = {\n        'a': 'remote_address',\n        't': 'request_start_time',\n        'P': 'process_id',\n        'r': 'first_request_line',\n        's': 'response_status',\n        'b': 'response_size',\n        'T': 'request_time',\n        'Tf': 'request_time_frac',\n        'D': 'request_time_micro',\n        'i': 'request_header',\n        'o': 'response_header',\n    }\n\n    LOG_FORMAT = '%a %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"'\n    FORMAT_RE = re.compile(r'%(\\{([A-Za-z0-9\\-_]+)\\}([ioe])|[atPrsbOD]|Tf?)')\n    CLEANUP_RE = re.compile(r'(%[^s])')\n    _FORMAT_CACHE = {}  # type: Dict[str, Tuple[str, List[KeyMethod]]]\n\n    def __init__(self, logger: logging.Logger,\n                 log_format: str=LOG_FORMAT) -> None:\n        \"\"\"Initialise the logger.\n\n        logger is a logger object to be used for logging.\n        log_format is a string with apache compatible log format description.\n\n        \"\"\"\n        super().__init__(logger, log_format=log_format)\n\n        _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format)\n        if not _compiled_format:\n            _compiled_format = self.compile_format(log_format)\n            AccessLogger._FORMAT_CACHE[log_format] = _compiled_format\n\n        self._log_format, self._methods = _compiled_format\n\n    def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]:\n        \"\"\"Translate log_format into form usable by modulo formatting\n\n        All known atoms will be replaced with %s\n        Also methods for formatting of those atoms will be added to\n        _methods in appropriate order\n\n        For example we have log_format = \"%a %t\"\n        This format will be translated to \"%s %s\"\n        Also contents of _methods will be\n        [self._format_a, self._format_t]\n        These method will be called and results will be passed\n        to translated string format.\n\n        Each _format_* method receive 'args' which is list of arguments\n        given to self.log\n\n        Exceptions are _format_e, _format_i and _format_o methods which\n        also receive key name (by functools.partial)\n\n        \"\"\"\n        # list of (key, method) tuples, we don't use an OrderedDict as users\n        # can repeat the same key more than once\n        methods = list()\n\n        for atom in self.FORMAT_RE.findall(log_format):\n            if atom[1] == '':\n                format_key1 = self.LOG_FORMAT_MAP[atom[0]]\n                m = getattr(AccessLogger, '_format_%s' % atom[0])\n                key_method = KeyMethod(format_key1, m)\n            else:\n                format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1])\n                m = getattr(AccessLogger, '_format_%s' % atom[2])\n                key_method = KeyMethod(format_key2,\n                                       functools.partial(m, atom[1]))\n\n            methods.append(key_method)\n\n        log_format = self.FORMAT_RE.sub(r'%s', log_format)\n        log_format = self.CLEANUP_RE.sub(r'%\\1', log_format)\n        return log_format, methods\n\n    @staticmethod\n    def _format_i(key: str,\n                  request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '(no headers)'\n\n        # suboptimal, make istr(key) once\n        return request.headers.get(key, '-')\n\n    @staticmethod\n    def _format_o(key: str,\n                  request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        # suboptimal, make istr(key) once\n        return response.headers.get(key, '-')\n\n    @staticmethod\n    def _format_a(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '-'\n        ip = request.remote\n        return ip if ip is not None else '-'\n\n    @staticmethod\n    def _format_t(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        now = datetime.datetime.utcnow()\n        start_time = now - datetime.timedelta(seconds=time)\n        return start_time.strftime('[%d/%b/%Y:%H:%M:%S +0000]')\n\n    @staticmethod\n    def _format_P(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return \"<%s>\" % os.getpid()\n\n    @staticmethod\n    def _format_r(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '-'\n        return '%s %s HTTP/%s.%s' % (request.method, request.path_qs,\n                                     request.version.major,\n                                     request.version.minor)\n\n    @staticmethod\n    def _format_s(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> int:\n        return response.status\n\n    @staticmethod\n    def _format_b(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> int:\n        return response.body_length\n\n    @staticmethod\n    def _format_T(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return str(round(time))\n\n    @staticmethod\n    def _format_Tf(request: BaseRequest,\n                   response: StreamResponse,\n                   time: float) -> str:\n        return '%06f' % time\n\n    @staticmethod\n    def _format_D(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return str(round(time * 1000000))\n\n    def _format_line(self,\n                     request: BaseRequest,\n                     response: StreamResponse,\n                     time: float) -> Iterable[Tuple[str,\n                                                    Callable[[BaseRequest,\n                                                              StreamResponse,\n                                                              float],\n                                                             str]]]:\n        return [(key, method(request, response, time))\n                for key, method in self._methods]\n\n    def log(self,\n            request: BaseRequest,\n            response: StreamResponse,\n            time: float) -> None:\n        try:\n            fmt_info = self._format_line(request, response, time)\n\n            values = list()\n            extra = dict()\n            for key, value in fmt_info:\n                values.append(value)\n\n                if key.__class__ is str:\n                    extra[key] = value\n                else:\n                    k1, k2 = key\n                    dct = extra.get(k1, {})\n                    dct[k2] = value  # type: ignore\n                    extra[k1] = dct  # type: ignore\n\n            self.logger.info(self._log_format % tuple(values), extra=extra)\n        except Exception:\n            self.logger.exception(\"Error in logging\")\n", "path": "aiohttp/web_log.py"}], "after_files": [{"content": "import datetime\nimport functools\nimport logging\nimport os\nimport re\nfrom collections import namedtuple\nfrom time import timezone\nfrom typing import Callable, Dict, Iterable, List, Tuple  # noqa\n\nfrom .abc import AbstractAccessLogger\nfrom .web_request import BaseRequest\nfrom .web_response import StreamResponse\n\nKeyMethod = namedtuple('KeyMethod', 'key method')\n\n\nclass AccessLogger(AbstractAccessLogger):\n    \"\"\"Helper object to log access.\n\n    Usage:\n        log = logging.getLogger(\"spam\")\n        log_format = \"%a %{User-Agent}i\"\n        access_logger = AccessLogger(log, log_format)\n        access_logger.log(request, response, time)\n\n    Format:\n        %%  The percent sign\n        %a  Remote IP-address (IP-address of proxy if using reverse proxy)\n        %t  Time when the request was started to process\n        %P  The process ID of the child that serviced the request\n        %r  First line of request\n        %s  Response status code\n        %b  Size of response in bytes, including HTTP headers\n        %T  Time taken to serve the request, in seconds\n        %Tf Time taken to serve the request, in seconds with floating fraction\n            in .06f format\n        %D  Time taken to serve the request, in microseconds\n        %{FOO}i  request.headers['FOO']\n        %{FOO}o  response.headers['FOO']\n        %{FOO}e  os.environ['FOO']\n\n    \"\"\"\n    LOG_FORMAT_MAP = {\n        'a': 'remote_address',\n        't': 'request_start_time',\n        'P': 'process_id',\n        'r': 'first_request_line',\n        's': 'response_status',\n        'b': 'response_size',\n        'T': 'request_time',\n        'Tf': 'request_time_frac',\n        'D': 'request_time_micro',\n        'i': 'request_header',\n        'o': 'response_header',\n    }\n\n    LOG_FORMAT = '%a %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"'\n    FORMAT_RE = re.compile(r'%(\\{([A-Za-z0-9\\-_]+)\\}([ioe])|[atPrsbOD]|Tf?)')\n    CLEANUP_RE = re.compile(r'(%[^s])')\n    _FORMAT_CACHE = {}  # type: Dict[str, Tuple[str, List[KeyMethod]]]\n\n    def __init__(self, logger: logging.Logger,\n                 log_format: str=LOG_FORMAT) -> None:\n        \"\"\"Initialise the logger.\n\n        logger is a logger object to be used for logging.\n        log_format is a string with apache compatible log format description.\n\n        \"\"\"\n        super().__init__(logger, log_format=log_format)\n\n        _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format)\n        if not _compiled_format:\n            _compiled_format = self.compile_format(log_format)\n            AccessLogger._FORMAT_CACHE[log_format] = _compiled_format\n\n        self._log_format, self._methods = _compiled_format\n\n    def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]:\n        \"\"\"Translate log_format into form usable by modulo formatting\n\n        All known atoms will be replaced with %s\n        Also methods for formatting of those atoms will be added to\n        _methods in appropriate order\n\n        For example we have log_format = \"%a %t\"\n        This format will be translated to \"%s %s\"\n        Also contents of _methods will be\n        [self._format_a, self._format_t]\n        These method will be called and results will be passed\n        to translated string format.\n\n        Each _format_* method receive 'args' which is list of arguments\n        given to self.log\n\n        Exceptions are _format_e, _format_i and _format_o methods which\n        also receive key name (by functools.partial)\n\n        \"\"\"\n        # list of (key, method) tuples, we don't use an OrderedDict as users\n        # can repeat the same key more than once\n        methods = list()\n\n        for atom in self.FORMAT_RE.findall(log_format):\n            if atom[1] == '':\n                format_key1 = self.LOG_FORMAT_MAP[atom[0]]\n                m = getattr(AccessLogger, '_format_%s' % atom[0])\n                key_method = KeyMethod(format_key1, m)\n            else:\n                format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1])\n                m = getattr(AccessLogger, '_format_%s' % atom[2])\n                key_method = KeyMethod(format_key2,\n                                       functools.partial(m, atom[1]))\n\n            methods.append(key_method)\n\n        log_format = self.FORMAT_RE.sub(r'%s', log_format)\n        log_format = self.CLEANUP_RE.sub(r'%\\1', log_format)\n        return log_format, methods\n\n    @staticmethod\n    def _format_i(key: str,\n                  request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '(no headers)'\n\n        # suboptimal, make istr(key) once\n        return request.headers.get(key, '-')\n\n    @staticmethod\n    def _format_o(key: str,\n                  request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        # suboptimal, make istr(key) once\n        return response.headers.get(key, '-')\n\n    @staticmethod\n    def _format_a(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '-'\n        ip = request.remote\n        return ip if ip is not None else '-'\n\n    @staticmethod\n    def _format_t(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        tz = datetime.timezone(datetime.timedelta(seconds=-timezone))\n        now = datetime.datetime.now(tz)\n        start_time = now - datetime.timedelta(seconds=time)\n        return start_time.strftime('[%d/%b/%Y:%H:%M:%S %z]')\n\n    @staticmethod\n    def _format_P(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return \"<%s>\" % os.getpid()\n\n    @staticmethod\n    def _format_r(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        if request is None:\n            return '-'\n        return '%s %s HTTP/%s.%s' % (request.method, request.path_qs,\n                                     request.version.major,\n                                     request.version.minor)\n\n    @staticmethod\n    def _format_s(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> int:\n        return response.status\n\n    @staticmethod\n    def _format_b(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> int:\n        return response.body_length\n\n    @staticmethod\n    def _format_T(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return str(round(time))\n\n    @staticmethod\n    def _format_Tf(request: BaseRequest,\n                   response: StreamResponse,\n                   time: float) -> str:\n        return '%06f' % time\n\n    @staticmethod\n    def _format_D(request: BaseRequest,\n                  response: StreamResponse,\n                  time: float) -> str:\n        return str(round(time * 1000000))\n\n    def _format_line(self,\n                     request: BaseRequest,\n                     response: StreamResponse,\n                     time: float) -> Iterable[Tuple[str,\n                                                    Callable[[BaseRequest,\n                                                              StreamResponse,\n                                                              float],\n                                                             str]]]:\n        return [(key, method(request, response, time))\n                for key, method in self._methods]\n\n    def log(self,\n            request: BaseRequest,\n            response: StreamResponse,\n            time: float) -> None:\n        try:\n            fmt_info = self._format_line(request, response, time)\n\n            values = list()\n            extra = dict()\n            for key, value in fmt_info:\n                values.append(value)\n\n                if key.__class__ is str:\n                    extra[key] = value\n                else:\n                    k1, k2 = key\n                    dct = extra.get(k1, {})\n                    dct[k2] = value  # type: ignore\n                    extra[k1] = dct  # type: ignore\n\n            self.logger.info(self._log_format % tuple(values), extra=extra)\n        except Exception:\n            self.logger.exception(\"Error in logging\")\n", "path": "aiohttp/web_log.py"}]}