我们正在使用https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker FastAPI 并且能够使用 gunicorn 日志文件自定义我们的日志记录。
但是,我们无法更改文档访问日志中定义的 %(message)s 属性的详细信息 - https://docs.gunicorn.org/en/stable/settings.html#accesslog。
我们在下面收到一个错误 postet,密钥未知。之前有人问过类似的问题,并收到了很多赞成票。 gunicorn 日志配置 access_log_format
我们做错了什么?
#start.sh
# Start Gunicorn
exec gunicorn -k uvicorn.workers.UvicornWorker -c "$GUNICORN_CONF" "$APP_MODULE" --log-config "/logging.conf"
Run Code Online (Sandbox Code Playgroud)
[loggers]
keys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access
[handlers]
keys=console, error_file, access_file, access_filegunicorn
[formatters]
keys=generic, access, accessgunicorn
[logger_root]
level=INFO
handlers=console
propagate=1
[logger_gunicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=gunicorn.error
[logger_gunicorn.access]
level=INFO
handlers=access_filegunicorn
propagate=0
qualname=gunicorn.access
[logger_uvicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=uvicorn.error
[logger_uvicorn.access]
level=INFO
handlers=access_file
propagate=0
qualname=uvicorn.access
[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_error_file]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_access_file]
class=StreamHandler
formatter=access
args=(sys.stdout, )
[handler_access_filegunicorn]
class=StreamHandler
formatter=accessgunicorn
args=(sys.stdout, )
[formatter_generic]
format=[%(levelname)s]: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=logging.Formatter
[formatter_access]
format=[%(levelname)s]: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=logging.Formatter
[formatter_accessgunicorn]
format=[%(levelname)s]: '{"remote_ip":"%(h)s","session_id":"%({X-Session-Id}i)s","status":"%(s)s","request_method":"%(m)s","request_path":"%(U)s","request_querystring":"%(q)s","request_timetaken":"%(D)s","response_length":"%(B)s", "remote_addr": "%(h)s"}'
datefmt=%Y-%m-%dT%H:%M:%S
class=logging.Formatter
Run Code Online (Sandbox Code Playgroud)
Message: '%s - "%s %s HTTP/%s" %d'
Arguments: ('213.3.14.24:53374', 'GET', '/v1/docs', '1.1', 200)
--- Logging error ---
Traceback (most recent call last):
File "/usr/local/lib/python3.7/logging/__init__.py", line 1025, in emit
msg = self.format(record)
File "/usr/local/lib/python3.7/logging/__init__.py", line 869, in format
return fmt.format(record)
File "/usr/local/lib/python3.7/logging/__init__.py", line 611, in format
s = self.formatMessage(record)
File "/usr/local/lib/python3.7/logging/__init__.py", line 580, in formatMessage
return self._style.format(record)
File "/usr/local/lib/python3.7/logging/__init__.py", line 422, in format
return self._fmt % record.__dict__
KeyError: 'h'
Call stack:
File "/usr/local/bin/gunicorn", line 8, in <module>
sys.exit(run())
File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 58, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 228, in run
super().run()
File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 202, in run
self.manage_workers()
File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 545, in manage_workers
self.spawn_workers()
File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 616, in spawn_workers
self.spawn_worker()
File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
worker.init_process()
File "/usr/local/lib/python3.7/site-packages/uvicorn/workers.py", line 61, in init_process
super(UvicornWorker, self).init_process()
File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 140, in init_process
self.run()
File "/usr/local/lib/python3.7/site-packages/uvicorn/workers.py", line 70, in run
loop.run_until_complete(server.serve(sockets=self.sockets))
File "/usr/local/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/usr/local/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/site-packages/fastapi/applications.py", line 171, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.7/site-packages/starlette/applications.py", line 102, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py", line 78, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 550, in __call__
await route.handle(scope, receive, send)
Run Code Online (Sandbox Code Playgroud)
我在这里找到了非常有用的信息https://github.com/tiangolo/fastapi/issues/1508
我需要添加请求 datetime ,我实现的解决方案是:
@app.on_event("startup")
async def startup_event():
logger = logging.getLogger("uvicorn.access")
console_formatter = uvicorn.logging.ColourizedFormatter(
"{asctime} {levelprefix} : {message}",
style="{", use_colors=True)
logger.handlers[0].setFormatter(console_formatter)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Run Code Online (Sandbox Code Playgroud)
我们的解决方案是用 python 编写的客户记录器,在logging.conf 文件中引用
日志记录配置文件
[loggers]
keys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access
[handlers]
keys=console, error_file, access_file, accesscustom
[formatters]
keys=generic, access, AccessFormatter
[logger_root]
level=INFO
handlers=console
propagate=1
[logger_gunicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=gunicorn.error
[logger_gunicorn.access]
level=INFO
handlers=accesscustom
propagate=0
qualname=gunicorn.access
[logger_uvicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=uvicorn.error
[logger_uvicorn.access]
level=INFO
handlers=accesscustom
propagate=0
qualname=uvicorn.access
[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_error_file]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_access_file]
class=StreamHandler
formatter=access
args=(sys.stdout, )
[handler_accesscustom]
class=StreamHandler
formatter=AccessFormatter
args=(sys.stdout, )
[formatter_generic]
format=%(levelname)s: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=uvicorn.logging.DefaultFormatter
[formatter_access]
format=%(levelname)s: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=customlogger.CustomFormatter
[formatter_AccessFormatter]
format={"event":"access_log","ip":"%(h)s","status":"%(s)s","method":"%(m)s","path":"%(U)s","referer":"%(f)s","x_session_id":"%(x-session-id)s","x_google_id":"%(x-google-id)s","x_server_time":"%(x-server-time)s","agent":"%(a)s"}
datefmt=%Y-%m-%dT%H:%M:%S
class=customlogger.CustomFormatter
Run Code Online (Sandbox Code Playgroud)
自定义记录器.py
[loggers]
keys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access
[handlers]
keys=console, error_file, access_file, accesscustom
[formatters]
keys=generic, access, AccessFormatter
[logger_root]
level=INFO
handlers=console
propagate=1
[logger_gunicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=gunicorn.error
[logger_gunicorn.access]
level=INFO
handlers=accesscustom
propagate=0
qualname=gunicorn.access
[logger_uvicorn.error]
level=INFO
handlers=error_file
propagate=0
qualname=uvicorn.error
[logger_uvicorn.access]
level=INFO
handlers=accesscustom
propagate=0
qualname=uvicorn.access
[handler_console]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_error_file]
class=StreamHandler
formatter=generic
args=(sys.stdout, )
[handler_access_file]
class=StreamHandler
formatter=access
args=(sys.stdout, )
[handler_accesscustom]
class=StreamHandler
formatter=AccessFormatter
args=(sys.stdout, )
[formatter_generic]
format=%(levelname)s: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=uvicorn.logging.DefaultFormatter
[formatter_access]
format=%(levelname)s: %(message)s
datefmt=%Y-%m-%dT%H:%M:%S
class=customlogger.CustomFormatter
[formatter_AccessFormatter]
format={"event":"access_log","ip":"%(h)s","status":"%(s)s","method":"%(m)s","path":"%(U)s","referer":"%(f)s","x_session_id":"%(x-session-id)s","x_google_id":"%(x-google-id)s","x_server_time":"%(x-server-time)s","agent":"%(a)s"}
datefmt=%Y-%m-%dT%H:%M:%S
class=customlogger.CustomFormatter
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4017 次 |
| 最近记录: |