This commit is contained in:
John Lancaster
2026-06-18 22:06:40 -05:00
parent 6c5fda9c3a
commit e78383be1f
24 changed files with 0 additions and 0 deletions
@@ -0,0 +1,97 @@
---
name: python-logging-dictconfig
description: 'Set up idiomatic Python logging with logging.config.dictConfig. Use when creating or refactoring logging setup, standardizing handlers/formatters, and enforcing centralized config.'
argument-hint: 'Target context (single script, package, FastAPI app, or CLI) and desired log destinations'
---
# Idiomatic Python Logging with dictConfig
Use this skill to produce a minimal, centralized logging setup using `logging.config.dictConfig`.
Load references only when needed:
- Python logging overview and hierarchy: [./references/python-logging-docs.md](./references/python-logging-docs.md)
## When to Use
- A project configures logging ad hoc with `basicConfig` across multiple modules.
- You need one canonical logging configuration for app startup.
- You need consistent formatting and levels across console/file handlers.
- You want library modules to use named loggers without configuring logging themselves.
## Inputs To Collect
1. Runtime type: script, library, web app, worker, CLI.
2. Destinations: stdout only, file only, or both.
3. Desired default level: `INFO`, `DEBUG`, etc.
4. Whether third-party loggers should be tuned (for example `uvicorn`, `sqlalchemy`).
If missing, assume:
- stdout handler
- human-readable formatter
- root level `INFO`
- `disable_existing_loggers: False`
## Procedure
1. Define a single `LOGGING` dictionary in one startup-oriented module (for example `logging_config.py`).
2. Include `version: 1` and set `disable_existing_loggers: False` unless there is a specific reason to silence existing loggers.
3. Define formatters first, then handlers, then logger routing (`root` and optional named `loggers`).
4. Use `logging.config.dictConfig(LOGGING)` exactly once during application startup.
5. In all modules, get loggers via `logger = logging.getLogger(__name__)` and never call `basicConfig`.
6. Keep libraries configuration-free: libraries should emit logs, applications decide routing.
7. Verify behavior with a quick smoke check at multiple levels (`DEBUG`, `INFO`, `WARNING`, `ERROR`).
## Minimal Baseline Template
```python
# logging_config.py
from logging.config import dictConfig
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"standard": {
"format": "%(asctime)s %(levelname)s %(name)s: %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "INFO",
"formatter": "standard",
"stream": "ext://sys.stdout",
}
},
"root": {
"level": "INFO",
"handlers": ["console"],
},
}
def configure_logging() -> None:
dictConfig(LOGGING)
```
```python
# app startup
from .logging_config import configure_logging
configure_logging()
```
```python
# any module
import logging
logger = logging.getLogger(__name__)
logger.info("module initialized")
```
## Completion Checks
1. `dictConfig` is called once at startup, not per module.
2. No `basicConfig` calls remain.
3. Modules use `getLogger(__name__)`.
4. Logs appear at expected level and destination.
5. Third-party logger noise is intentionally configured or left at defaults.
## Branching Guidance
- If structured logs are required: switch formatter output to JSON while keeping `dictConfig` topology unchanged.
- If both console and file output are needed: add a file handler and attach it to `root`.
- If a specific framework logger is too noisy: add a named logger override under `loggers`.
@@ -0,0 +1,18 @@
# Python Logging References
Use these official Python docs when applying this skill.
## Core Documentation
- Logging HOWTO: https://docs.python.org/3/howto/logging.html
- Logging Cookbook: https://docs.python.org/3/howto/logging-cookbook.html
- logging API reference: https://docs.python.org/3/library/logging.html
- logging.config reference: https://docs.python.org/3/library/logging.config.html
## dictConfig-Specific
- Dictionary schema details (`version`, formatters, handlers, loggers, root): https://docs.python.org/3/library/logging.config.html#logging-config-dictschema
- `logging.config.dictConfig` function: https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
## Practical Notes
- Prefer app-level centralized config with one startup call to `dictConfig`.
- In modules, use `logging.getLogger(__name__)`.
- Avoid calling `basicConfig` in libraries or scattered modules.