You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/logging.md
+11-20Lines changed: 11 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,6 +13,9 @@ See [environment variable reference](environment.md).
13
13
- inboard's logging configuration logic is located in [`logging_conf.py`](https://github.com/br3ndonland/inboard/blob/HEAD/inboard/logging_conf.py). By default, inboard will load the `LOGGING_CONFIG` dictionary in this module. The dictionary was named for consistency with [Uvicorn's logging configuration dictionary](https://github.com/encode/uvicorn/blob/HEAD/uvicorn/config.py).
14
14
- When running Uvicorn alone, logging is configured programmatically from within the [`start.py` start script](https://github.com/br3ndonland/inboard/blob/HEAD/inboard/start.py), by passing the `LOGGING_CONFIG` dictionary to `uvicorn.run()`.
15
15
- When running Gunicorn with the Uvicorn worker, the logging configuration dictionary is specified within the [`gunicorn_conf.py`](https://github.com/br3ndonland/inboard/blob/HEAD/inboard/gunicorn_conf.py) configuration file.
16
+
- The Gunicorn Uvicorn worker has been updated to remove handlers from `uvicorn.error` and `uvicorn.access` and instead propagate those log records to the root logger. This avoids duplicate records and ensures the root handler applies the configured formatter and filters.
17
+
- The Uvicorn worker class originally disabled propagation because it resulted in duplicate logs if enabled ([encode/uvicorn#614](https://github.com/encode/uvicorn/issues/614), [encode/uvicorn#623](https://github.com/encode/uvicorn/pull/623)). As the [docs](https://docs.python.org/3/library/logging.html#logging.Logger.propagate) on `logging.Logger.propagate` explain, "If you attach a handler to a logger _and_ one or more of its ancestors, it may emit the same record multiple times."
18
+
- Instead of disabling propagation and keeping Gunicorn handlers set on the logger, another solution is to remove the Gunicorn handlers and enable propagation so the root logger can manage all logs ([br3ndonland/inboard#131](https://github.com/br3ndonland/inboard/discussions/131)).
16
19
17
20
## Filtering log messages
18
21
@@ -128,7 +131,8 @@ If the inboard Python package is installed from PyPI, the logging configuration
128
131
"()": "package.custom_logging.MyFormatterClass",
129
132
}
130
133
131
-
# only show access logs when running Uvicorn with LOG_LEVEL=debug
134
+
# only show access logs when running Uvicorn alone with LOG_LEVEL=debug
135
+
# Gunicorn-managed Uvicorn workers always propagate access logs to root
@@ -143,7 +147,7 @@ If the inboard Python package is installed from PyPI, the logging configuration
143
147
144
148
## Overriding the logging config
145
149
146
-
Want to override inboard's entire logging config? No problem. Set up a separate `LOGGING_CONFIG` dictionary, and pass inboard the path to the module containing the dictionary. Try something like this:
150
+
Want to override inboard's entire logging config? No problem. Set up a separate `LOGGING_CONFIG` dictionary, and pass inboard the path to the module containing the dictionary. Gunicorn-managed Uvicorn workers route `uvicorn.error` and `uvicorn.access` through the root logger, so configure the root handler with the formatter and output stream those records should use. Logger-specific Uvicorn handlers only apply when running Uvicorn without Gunicorn. Try something like this:
147
151
148
152
!!! example "Example of a complete custom logging config"
149
153
@@ -161,11 +165,7 @@ Want to override inboard's entire logging config? No problem. Set up a separate
0 commit comments