{"html_url": "https://github.com/simonw/datasette/issues/1175#issuecomment-754696725", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1175", "id": 754696725, "node_id": "MDEyOklzc3VlQ29tbWVudDc1NDY5NjcyNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-01-05T15:12:30Z", "updated_at": "2021-01-05T15:12:30Z", "author_association": "OWNER", "body": "Some tips here: https://github.com/tiangolo/fastapi/issues/78", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 779156520, "label": "Use structlog for logging"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1175#issuecomment-762488336", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1175", "id": 762488336, "node_id": "MDEyOklzc3VlQ29tbWVudDc2MjQ4ODMzNg==", "user": {"value": 758858, "label": "hannseman"}, "created_at": "2021-01-18T21:59:28Z", "updated_at": "2021-01-18T22:00:31Z", "author_association": "NONE", "body": "I encountered your issue when trying to find a solution and came up with the following, maybe it can help.\r\n\r\n```python\r\nimport logging.config\r\nfrom typing import Tuple\r\n\r\nimport structlog\r\nimport uvicorn\r\n\r\nfrom example.config import settings\r\n\r\nshared_processors: Tuple[structlog.types.Processor, ...] = (\r\n structlog.contextvars.merge_contextvars,\r\n structlog.stdlib.add_logger_name,\r\n structlog.stdlib.add_log_level,\r\n structlog.processors.TimeStamper(fmt=\"iso\"),\r\n)\r\n\r\nlogging_config = {\r\n \"version\": 1,\r\n \"disable_existing_loggers\": False,\r\n \"formatters\": {\r\n \"json\": {\r\n \"()\": structlog.stdlib.ProcessorFormatter,\r\n \"processor\": structlog.processors.JSONRenderer(),\r\n \"foreign_pre_chain\": shared_processors,\r\n },\r\n \"console\": {\r\n \"()\": structlog.stdlib.ProcessorFormatter,\r\n \"processor\": structlog.dev.ConsoleRenderer(),\r\n \"foreign_pre_chain\": shared_processors,\r\n },\r\n **uvicorn.config.LOGGING_CONFIG[\"formatters\"],\r\n },\r\n \"handlers\": {\r\n \"default\": {\r\n \"level\": \"DEBUG\",\r\n \"class\": \"logging.StreamHandler\",\r\n \"formatter\": \"json\" if not settings.debug else \"console\",\r\n },\r\n \"uvicorn.access\": {\r\n \"level\": \"INFO\",\r\n \"class\": \"logging.StreamHandler\",\r\n \"formatter\": \"access\",\r\n },\r\n \"uvicorn.default\": {\r\n \"level\": \"INFO\",\r\n \"class\": \"logging.StreamHandler\",\r\n \"formatter\": \"default\",\r\n },\r\n },\r\n \"loggers\": {\r\n \"\": {\"handlers\": [\"default\"], \"level\": \"INFO\"},\r\n \"uvicorn.error\": {\r\n \"handlers\": [\"default\" if not settings.debug else \"uvicorn.default\"],\r\n \"level\": \"INFO\",\r\n \"propagate\": False,\r\n },\r\n \"uvicorn.access\": {\r\n \"handlers\": [\"default\" if not settings.debug else \"uvicorn.access\"],\r\n \"level\": \"INFO\",\r\n \"propagate\": False,\r\n },\r\n },\r\n}\r\n\r\n\r\ndef setup_logging() -> None:\r\n structlog.configure(\r\n processors=[\r\n structlog.stdlib.filter_by_level,\r\n *shared_processors,\r\n structlog.stdlib.PositionalArgumentsFormatter(),\r\n structlog.processors.StackInfoRenderer(),\r\n structlog.processors.format_exc_info,\r\n structlog.stdlib.ProcessorFormatter.wrap_for_formatter,\r\n ],\r\n context_class=dict,\r\n logger_factory=structlog.stdlib.LoggerFactory(),\r\n wrapper_class=structlog.stdlib.AsyncBoundLogger,\r\n cache_logger_on_first_use=True,\r\n )\r\n logging.config.dictConfig(logging_config)\r\n```\r\n\r\nAnd then it'll be run on the startup event:\r\n```python\r\n@app.on_event(\"startup\")\r\nasync def startup_event() -> None:\r\n setup_logging()\r\n```\r\n\r\nIt depends on a setting called `debug` which controls if it should output the regular uvicorn logging or json. ", "reactions": "{\"total_count\": 15, \"+1\": 7, \"-1\": 0, \"laugh\": 1, \"hooray\": 1, \"confused\": 0, \"heart\": 5, \"rocket\": 1, \"eyes\": 0}", "issue": {"value": 779156520, "label": "Use structlog for logging"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1175#issuecomment-984569477", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1175", "id": 984569477, "node_id": "IC_kwDOBm6k_c46r1aF", "user": {"value": 24821294, "label": "AnkitKundariya"}, "created_at": "2021-12-02T12:09:30Z", "updated_at": "2021-12-02T12:09:30Z", "author_association": "NONE", "body": "@hannseman \r\nI have tried the above suggestion given by you but somehow I'm getting the below error.\r\n\r\n_note : I'm running my application with Docker._\r\n\r\n`app_1 | {\"event\": \"Exception in ASGI application\\n\", \"exc_info\": [\"\", \"RuntimeError('no running event loop')\", \"\"], \"logger\": \"uvicorn.error\", \"level\": \"error\", \"timestamp\": \"2021-12-02T12:06:36.011448Z\"}\r\n`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 779156520, "label": "Use structlog for logging"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1175#issuecomment-1195442266", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1175", "id": 1195442266, "node_id": "IC_kwDOBm6k_c5HQQBa", "user": {"value": 8523191, "label": "RamiAwar"}, "created_at": "2022-07-26T12:52:10Z", "updated_at": "2022-07-26T12:52:10Z", "author_association": "NONE", "body": "I'm using this in a separate FastAPI app, worked perfectly when I changed the AsyncBoundLogger to BoundLogger only.\r\n\r\nAlso for some reason, I'm now getting some logs surfacing from internal packages, like Elasticsearch. But don't have time to deal with that now.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 779156520, "label": "Use structlog for logging"}, "performed_via_github_app": null}