structlog-config 0.2.0__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {structlog_config-0.2.0 → structlog_config-0.4.1}/PKG-INFO +62 -8
  2. {structlog_config-0.2.0 → structlog_config-0.4.1}/README.md +55 -3
  3. {structlog_config-0.2.0 → structlog_config-0.4.1}/pyproject.toml +8 -3
  4. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/__init__.py +3 -0
  5. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/fastapi_access_logger.py +50 -13
  6. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/formatters.py +1 -0
  7. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/stdlib_logging.py +7 -1
  8. structlog_config-0.2.0/.copier-answers.yml +0 -2
  9. structlog_config-0.2.0/.envrc +0 -11
  10. structlog_config-0.2.0/.github/dependabot.yml +0 -12
  11. structlog_config-0.2.0/.github/workflows/build_and_publish.yml +0 -56
  12. structlog_config-0.2.0/.github/workflows/repo-sync.yml +0 -16
  13. structlog_config-0.2.0/.gitignore +0 -129
  14. structlog_config-0.2.0/.tool-versions +0 -3
  15. structlog_config-0.2.0/.vscode/settings.json +0 -36
  16. structlog_config-0.2.0/CHANGELOG.md +0 -53
  17. structlog_config-0.2.0/Makefile +0 -11
  18. structlog_config-0.2.0/copier.yml +0 -68
  19. structlog_config-0.2.0/tests/__init__.py +0 -0
  20. structlog_config-0.2.0/tests/capture_utils.py +0 -53
  21. structlog_config-0.2.0/tests/conftest.py +0 -129
  22. structlog_config-0.2.0/tests/test_environment.py +0 -161
  23. structlog_config-0.2.0/tests/test_fastapi_access_logger.py +0 -189
  24. structlog_config-0.2.0/tests/test_formatters.py +0 -33
  25. structlog_config-0.2.0/tests/test_import.py +0 -8
  26. structlog_config-0.2.0/tests/test_log_destination.py +0 -37
  27. structlog_config-0.2.0/tests/test_logging.py +0 -168
  28. structlog_config-0.2.0/tests/utils.py +0 -35
  29. structlog_config-0.2.0/uv.lock +0 -1695
  30. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/constants.py +0 -0
  31. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/env_config.py +0 -0
  32. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/environments.py +0 -0
  33. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/levels.py +0 -0
  34. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/packages.py +0 -0
  35. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/trace.py +0 -0
  36. {structlog_config-0.2.0 → structlog_config-0.4.1}/structlog_config/warnings.py +0 -0
@@ -1,14 +1,16 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.3
2
2
  Name: structlog-config
3
- Version: 0.2.0
3
+ Version: 0.4.1
4
4
  Summary: A comprehensive structlog configuration with sensible defaults for development and production environments, featuring context management, exception formatting, and path prettification.
5
- Project-URL: Repository, https://github.com/iloveitaly/structlog-config
5
+ Keywords: logging,structlog,json-logging,structured-logging
6
+ Author: Michael Bianco
6
7
  Author-email: Michael Bianco <mike@mikebian.co>
7
- Keywords: json-logging,logging,structlog,structured-logging
8
- Requires-Python: >=3.10
9
8
  Requires-Dist: orjson>=3.10.15
10
9
  Requires-Dist: python-decouple-typed>=3.11.0
10
+ Requires-Dist: python-ipware>=3.0.0
11
11
  Requires-Dist: structlog>=25.2.0
12
+ Requires-Python: >=3.10
13
+ Project-URL: Repository, https://github.com/iloveitaly/structlog-config
12
14
  Description-Content-Type: text/markdown
13
15
 
14
16
  # Opinionated Defaults for Structlog
@@ -30,12 +32,64 @@ Here are the main goals:
30
32
  ## Usage
31
33
 
32
34
  ```python
33
- from structlog_config import configure_logging
35
+ from structlog_config import configure_logger
36
+
37
+ log = configure_logger()
38
+
39
+ log.info("the log", key="value")
40
+ ```
41
+
42
+ ## JSON Logging for Production
43
+
44
+ JSON logging is automatically enabled in production and staging environments (`PYTHON_ENV=production` or `PYTHON_ENV=staging`):
45
+
46
+ ```python
47
+ from structlog_config import configure_logger
48
+
49
+ # Automatic JSON logging in production
50
+ log = configure_logger()
51
+ log.info("User login", user_id="123", action="login")
52
+ # Output: {"action":"login","event":"User login","level":"info","timestamp":"2025-09-24T18:03:00Z","user_id":"123"}
53
+
54
+ # Force JSON logging regardless of environment
55
+ log = configure_logger(json_logger=True)
56
+
57
+ # Force console logging regardless of environment
58
+ log = configure_logger(json_logger=False)
59
+ ```
60
+
61
+ JSON logs use [orjson](https://github.com/ijl/orjson) for performance, include sorted keys and ISO timestamps, and serialize exceptions cleanly. Note that `PYTHON_LOG_PATH` is ignored with JSON logging (stdout only).
62
+
63
+ ## TRACE Logging Level
64
+
65
+ This package adds support for a custom `TRACE` logging level (level 5) that's even more verbose than `DEBUG`. This is useful for extremely detailed debugging scenarios.
66
+
67
+ The `TRACE` level is automatically set up when you call `configure_logger()`. You can use it like any other logging level:
68
+
69
+ ```python
70
+ import logging
71
+ from structlog_config import configure_logger
72
+
73
+ log = configure_logger()
74
+
75
+ # Using structlog
76
+ log.info("This is info")
77
+ log.debug("This is debug")
78
+ log.trace("This is trace") # Most verbose
79
+
80
+ # Using stdlib logging
81
+ logging.trace("Module-level trace message")
82
+ logger = logging.getLogger(__name__)
83
+ logger.trace("Instance trace message")
84
+ ```
85
+
86
+ Set the log level to TRACE using the environment variable:
34
87
 
35
- configure_logging()
88
+ ```bash
89
+ LOG_LEVEL=TRACE
36
90
  ```
37
91
 
38
- ## Stdib Log Management
92
+ ## Stdlib Log Management
39
93
 
40
94
  By default, all stdlib loggers are:
41
95
 
@@ -17,12 +17,64 @@ Here are the main goals:
17
17
  ## Usage
18
18
 
19
19
  ```python
20
- from structlog_config import configure_logging
20
+ from structlog_config import configure_logger
21
+
22
+ log = configure_logger()
23
+
24
+ log.info("the log", key="value")
25
+ ```
26
+
27
+ ## JSON Logging for Production
28
+
29
+ JSON logging is automatically enabled in production and staging environments (`PYTHON_ENV=production` or `PYTHON_ENV=staging`):
30
+
31
+ ```python
32
+ from structlog_config import configure_logger
33
+
34
+ # Automatic JSON logging in production
35
+ log = configure_logger()
36
+ log.info("User login", user_id="123", action="login")
37
+ # Output: {"action":"login","event":"User login","level":"info","timestamp":"2025-09-24T18:03:00Z","user_id":"123"}
38
+
39
+ # Force JSON logging regardless of environment
40
+ log = configure_logger(json_logger=True)
41
+
42
+ # Force console logging regardless of environment
43
+ log = configure_logger(json_logger=False)
44
+ ```
45
+
46
+ JSON logs use [orjson](https://github.com/ijl/orjson) for performance, include sorted keys and ISO timestamps, and serialize exceptions cleanly. Note that `PYTHON_LOG_PATH` is ignored with JSON logging (stdout only).
47
+
48
+ ## TRACE Logging Level
49
+
50
+ This package adds support for a custom `TRACE` logging level (level 5) that's even more verbose than `DEBUG`. This is useful for extremely detailed debugging scenarios.
51
+
52
+ The `TRACE` level is automatically set up when you call `configure_logger()`. You can use it like any other logging level:
53
+
54
+ ```python
55
+ import logging
56
+ from structlog_config import configure_logger
57
+
58
+ log = configure_logger()
59
+
60
+ # Using structlog
61
+ log.info("This is info")
62
+ log.debug("This is debug")
63
+ log.trace("This is trace") # Most verbose
64
+
65
+ # Using stdlib logging
66
+ logging.trace("Module-level trace message")
67
+ logger = logging.getLogger(__name__)
68
+ logger.trace("Instance trace message")
69
+ ```
70
+
71
+ Set the log level to TRACE using the environment variable:
21
72
 
22
- configure_logging()
73
+ ```bash
74
+ LOG_LEVEL=TRACE
23
75
  ```
24
76
 
25
- ## Stdib Log Management
77
+ ## Stdlib Log Management
26
78
 
27
79
  By default, all stdlib loggers are:
28
80
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "structlog-config"
3
- version = "0.2.0"
3
+ version = "0.4.1"
4
4
  description = "A comprehensive structlog configuration with sensible defaults for development and production environments, featuring context management, exception formatting, and path prettification."
5
5
  keywords = ["logging", "structlog", "json-logging", "structured-logging"]
6
6
  readme = "README.md"
@@ -8,14 +8,19 @@ requires-python = ">=3.10"
8
8
  dependencies = [
9
9
  "orjson>=3.10.15",
10
10
  "python-decouple-typed>=3.11.0",
11
+ "python-ipware>=3.0.0",
11
12
  "structlog>=25.2.0",
12
13
  ]
13
14
  authors = [{ name = "Michael Bianco", email = "mike@mikebian.co" }]
14
15
  urls = { "Repository" = "https://github.com/iloveitaly/structlog-config" }
15
16
 
16
17
  [build-system]
17
- requires = ["hatchling"]
18
- build-backend = "hatchling.build"
18
+ requires = ["uv_build>=0.8.11,<0.9.0"]
19
+ build-backend = "uv_build"
20
+
21
+ [tool.uv.build-backend]
22
+ # avoids the src/ directory structure
23
+ module-root = ""
19
24
 
20
25
  [dependency-groups]
21
26
  debugging-extras = [
@@ -9,6 +9,9 @@ from structlog.processors import ExceptionRenderer
9
9
  from structlog.tracebacks import ExceptionDictTransformer
10
10
  from structlog.typing import FilteringBoundLogger
11
11
 
12
+ from structlog_config.fastapi_access_logger import (
13
+ client_ip_from_request,
14
+ )
12
15
  from structlog_config.formatters import (
13
16
  PathPrettifier,
14
17
  add_fastapi_context,
@@ -3,13 +3,16 @@ from urllib.parse import quote
3
3
 
4
4
  import structlog
5
5
  from fastapi import FastAPI
6
+ from python_ipware import IpWare
6
7
  from starlette.middleware.base import RequestResponseEndpoint
7
8
  from starlette.requests import Request
8
9
  from starlette.responses import Response
9
10
  from starlette.routing import Match, Mount
10
11
  from starlette.types import Scope
12
+ from starlette.websockets import WebSocket
11
13
 
12
14
  log = structlog.get_logger("access_log")
15
+ ipw = IpWare()
13
16
 
14
17
 
15
18
  def get_route_name(app: FastAPI, scope: Scope, prefix: str = "") -> str:
@@ -47,20 +50,40 @@ def get_path_with_query_string(scope: Scope) -> str:
47
50
  return path_with_query_string
48
51
 
49
52
 
50
- def get_client_addr(scope: Scope) -> str:
51
- """Get the client's address.
53
+ def client_ip_from_request(request: Request | WebSocket) -> str | None:
54
+ """
55
+ Get the client IP address from the request.
52
56
 
53
- Args:
54
- scope (Scope): Current context.
57
+ Headers are not case-sensitive.
55
58
 
56
- Returns:
57
- str: Client's address in the IP:PORT format.
59
+ Uses ipware library to properly extract client IP from various proxy headers.
60
+ Fallback to direct client connection if no proxy headers found.
58
61
  """
59
- client = scope.get("client")
60
- if not client:
61
- return ""
62
- ip, port = client
63
- return f"{ip}:{port}"
62
+ headers = request.headers
63
+
64
+ # TODO this seems really inefficient, we should just rewrite the ipware into this repo :/
65
+ # Convert Starlette headers to format expected by ipware (HTTP_ prefixed)
66
+ # ipware expects headers in WSGI/Django-style meta format where HTTP headers
67
+ # are prefixed with "HTTP_" and dashes become underscores.
68
+ # See: https://github.com/un33k/python-ipware/blob/main/python_ipware/python_ipware.py#L33-L40
69
+ meta_dict = {}
70
+ for name, value in headers.items():
71
+ # Convert header name to HTTP_ prefixed format
72
+ meta_key = f"HTTP_{name.upper().replace('-', '_')}"
73
+ meta_dict[meta_key] = value
74
+
75
+ # Use ipware to extract IP from headers
76
+ ip, trusted_route = ipw.get_client_ip(meta=meta_dict)
77
+ if ip:
78
+ log.debug(
79
+ "extracted client IP from headers", ip=ip, trusted_route=trusted_route
80
+ )
81
+ return str(ip)
82
+
83
+ # Fallback to direct client connection
84
+ host = request.client.host if request.client else None
85
+
86
+ return host
64
87
 
65
88
 
66
89
  # TODO we should look at the static asset logic and pull the prefix path from tha
@@ -78,13 +101,27 @@ def is_static_assets_request(scope: Scope) -> bool:
78
101
  or scope["path"].endswith(".js")
79
102
  # .map files are attempted when devtools are enabled
80
103
  or scope["path"].endswith(".js.map")
104
+ or scope["path"].endswith(".ico")
105
+ or scope["path"].endswith(".png")
106
+ or scope["path"].endswith(".jpg")
107
+ or scope["path"].endswith(".jpeg")
108
+ or scope["path"].endswith(".gif")
81
109
  )
82
110
 
83
111
 
84
112
  def add_middleware(
85
113
  app: FastAPI,
86
114
  ) -> None:
87
- """Use this method to add this middleware to your fastapi application."""
115
+ """
116
+ Add better access logging to fastapi:
117
+
118
+ >>> from structlog_config import fastapi_access_logger
119
+ >>> fastapi_access_logger.add_middleware(app)
120
+
121
+ You'll also want to disable the default uvicorn logs:
122
+
123
+ >>> uvicorn.run(..., log_config=None, access_log=False)
124
+ """
88
125
 
89
126
  @app.middleware("http")
90
127
  async def access_log_middleware(
@@ -113,7 +150,7 @@ def add_middleware(
113
150
  method=scope["method"],
114
151
  path=scope["path"],
115
152
  query=scope["query_string"].decode(),
116
- client_ip=get_client_addr(scope),
153
+ client_ip=client_ip_from_request(request),
117
154
  route=route_name,
118
155
  )
119
156
 
@@ -77,6 +77,7 @@ def pretty_traceback_exception_formatter(sio: TextIO, exc_info: ExcInfo) -> None
77
77
  from pretty_traceback.formatting import exc_to_traceback_str
78
78
 
79
79
  _, exc_value, traceback = exc_info
80
+ # TODO support local_stack_only env var support
80
81
  formatted_exception = exc_to_traceback_str(exc_value, traceback, color=not NO_COLOR)
81
82
  sio.write("\n" + formatted_exception)
82
83
 
@@ -97,8 +97,8 @@ def redirect_stdlib_loggers(json_logger: bool):
97
97
  root_logger.propagate = True
98
98
 
99
99
  # TODO there is a JSON-like format that can be used to configure loggers instead :/
100
+ # we should probably transition to using that format instead of this customized mapping
100
101
  std_logging_configuration = {
101
- # "httpcore": {},
102
102
  "httpx": {
103
103
  "levels": {
104
104
  "INFO": "WARNING",
@@ -109,6 +109,12 @@ def redirect_stdlib_loggers(json_logger: bool):
109
109
  "INFO": "WARNING",
110
110
  }
111
111
  },
112
+ # stripe INFO logs are pretty noisy by default
113
+ "stripe": {
114
+ "levels": {
115
+ "INFO": "WARNING",
116
+ }
117
+ },
112
118
  }
113
119
  """
114
120
  These loggers either:
@@ -1,2 +0,0 @@
1
- # this exact file name is required in this exact location if updates are to work
2
- {"_commit": "v0.2.1-31-gb45b358", "_src_path": "https://github.com/iloveitaly/python-package-template", "project_name": "structlog-config", "full_name": "Michael Bianco", "email": "mike@mikebian.co", "github_username": "iloveitaly"}
@@ -1,11 +0,0 @@
1
- layout uv
2
-
3
- export LOG_LEVEL=DEBUG
4
-
5
- # make sure none of the logging is unbuffered
6
- export PYTHONUNBUFFERED=1
7
-
8
- # required in order to avoid color codes in logging output for tests
9
- export NO_COLOR=1
10
-
11
- export PYTHONBREAKPOINT=pdbr.set_trace
@@ -1,12 +0,0 @@
1
- version: 2
2
-
3
- updates:
4
- - package-ecosystem: "github-actions"
5
- directory: "/"
6
- schedule:
7
- interval: "weekly"
8
-
9
- - package-ecosystem: "uv"
10
- directory: "/"
11
- schedule:
12
- interval: "weekly"
@@ -1,56 +0,0 @@
1
- name: Build and Publish to PyPI
2
- on:
3
- push:
4
- branches:
5
- - main
6
- - master
7
-
8
- permissions:
9
- contents: write
10
-
11
- env:
12
- PIP_DEFAULT_TIMEOUT: 60
13
- PIP_RETRIES: 5
14
-
15
- # required otherwise github api calls are rate limited
16
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
-
18
- jobs:
19
- matrix-test:
20
- strategy:
21
- matrix:
22
- os: [ubuntu-latest, macos-latest]
23
- python-version: ["3.13", "3.12", "3.11"]
24
- runs-on: ${{ matrix.os }}
25
- steps:
26
- - uses: actions/checkout@v4
27
- - uses: jdx/mise-action@v2
28
- - run: mise use python@${{ matrix.python-version }}
29
- - uses: iloveitaly/github-action-direnv-load-and-mask@master
30
- - run: uv sync
31
- - run: uv run pytest
32
-
33
- release-please:
34
- needs: matrix-test
35
- runs-on: ubuntu-latest
36
- outputs:
37
- release_created: ${{ steps.release.outputs.release_created }}
38
- steps:
39
- - uses: actions/checkout@v4
40
- - uses: googleapis/release-please-action@v4
41
- id: release
42
- with:
43
- release-type: python
44
- token: ${{ secrets.GH_PERSONAL_TOKEN }}
45
-
46
- build-and-publish:
47
- needs: release-please
48
- runs-on: ubuntu-latest
49
- if: ${{ needs.release-please.outputs.release_created }}
50
- steps:
51
- - uses: actions/checkout@v4
52
- - uses: jdx/mise-action@v2
53
- - uses: iloveitaly/github-action-direnv-load-and-mask@master
54
- - run: uv sync
55
- - run: uv build
56
- - run: uv publish --token ${{ secrets.PYPI_API_TOKEN }}
@@ -1,16 +0,0 @@
1
- name: Repository Metadata Sync
2
-
3
- on:
4
- push:
5
- branches: [main, master]
6
-
7
- jobs:
8
- repo_sync:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Fetching Local Repository
12
- uses: actions/checkout@v4
13
- - name: Repository Metadata Sync
14
- uses: iloveitaly/github-actions-metadata-sync@main
15
- with:
16
- TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
@@ -1,129 +0,0 @@
1
- # Byte-compiled / optimized / DLL files
2
- __pycache__/
3
- *.py[cod]
4
- *$py.class
5
-
6
- # C extensions
7
- *.so
8
-
9
- # Distribution / packaging
10
- .Python
11
- build/
12
- develop-eggs/
13
- dist/
14
- downloads/
15
- eggs/
16
- .eggs/
17
- lib/
18
- lib64/
19
- parts/
20
- sdist/
21
- var/
22
- wheels/
23
- pip-wheel-metadata/
24
- share/python-wheels/
25
- *.egg-info/
26
- .installed.cfg
27
- *.egg
28
- MANIFEST
29
-
30
- # PyInstaller
31
- # Usually these files are written by a python script from a template
32
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
- *.manifest
34
- *.spec
35
-
36
- # Installer logs
37
- pip-log.txt
38
- pip-delete-this-directory.txt
39
-
40
- # Unit test / coverage reports
41
- htmlcov/
42
- .tox/
43
- .nox/
44
- .coverage
45
- .coverage.*
46
- .cache
47
- nosetests.xml
48
- coverage.xml
49
- *.cover
50
- *.py,cover
51
- .hypothesis/
52
- .pytest_cache/
53
-
54
- # Translations
55
- *.mo
56
- *.pot
57
-
58
- # Django stuff:
59
- *.log
60
- local_settings.py
61
- db.sqlite3
62
- db.sqlite3-journal
63
-
64
- # Flask stuff:
65
- instance/
66
- .webassets-cache
67
-
68
- # Scrapy stuff:
69
- .scrapy
70
-
71
- # Sphinx documentation
72
- docs/_build/
73
-
74
- # PyBuilder
75
- target/
76
-
77
- # Jupyter Notebook
78
- .ipynb_checkpoints
79
-
80
- # IPython
81
- profile_default/
82
- ipython_config.py
83
-
84
- # pyenv
85
- .python-version
86
-
87
- # pipenv
88
- # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
- # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
- # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
- # install all needed dependencies.
92
- #Pipfile.lock
93
-
94
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
- __pypackages__/
96
-
97
- # Celery stuff
98
- celerybeat-schedule
99
- celerybeat.pid
100
-
101
- # SageMath parsed files
102
- *.sage.py
103
-
104
- # Environments
105
- .env
106
- .venv
107
- env/
108
- venv/
109
- ENV/
110
- env.bak/
111
- venv.bak/
112
-
113
- # Spyder project settings
114
- .spyderproject
115
- .spyproject
116
-
117
- # Rope project settings
118
- .ropeproject
119
-
120
- # mkdocs documentation
121
- /site
122
-
123
- # mypy
124
- .mypy_cache/
125
- .dmypy.json
126
- dmypy.json
127
-
128
- # Pyre type checker
129
- .pyre/
@@ -1,3 +0,0 @@
1
- python 3.13.2
2
- uv 0.6.6
3
- direnv 2.35.0
@@ -1,36 +0,0 @@
1
- {
2
- "[python]": {
3
- "editor.formatOnSave": true,
4
- "editor.defaultFormatter": "charliermarsh.ruff",
5
- "editor.codeActionsOnSave": {
6
- "source.fixAll": "explicit",
7
- "source.organizeImports": "explicit"
8
- },
9
- "editor.tabSize": 4
10
- },
11
- "[toml]": {
12
- "editor.formatOnSave": true,
13
- "editor.tabSize": 4
14
- },
15
- "python.analysis.autoFormatStrings": true,
16
-
17
- // for import autosuggest
18
- "python.analysis.indexing": true,
19
- "python.analysis.autoImportCompletions": true,
20
-
21
- "python.analysis.packageIndexDepths": [
22
- {
23
- "name": "",
24
- "depth": 3,
25
- "includeAllSymbols": true
26
- }
27
- ],
28
-
29
- "cSpell.words": ["openai", "httpx"],
30
-
31
- "files.exclude": {
32
- ".ruff_cache": true,
33
- ".pytest_cache": true,
34
- ".venv": true
35
- }
36
- }
@@ -1,53 +0,0 @@
1
- # Changelog
2
-
3
- ## [0.2.0](https://github.com/iloveitaly/structlog-config/compare/v0.1.0...v0.2.0) (2025-08-05)
4
-
5
-
6
- ### Features
7
-
8
- * add custom TRACE log level and logger extension ([73e0551](https://github.com/iloveitaly/structlog-config/commit/73e05513c24e8ffe986105753a9a8d4ae5f5f496))
9
- * call setup_trace in configure_logger to enable tracing ([85ee622](https://github.com/iloveitaly/structlog-config/commit/85ee622ad5647c7a97032f79cb12cee9ab6bcac1))
10
- * global level override always set on std loggers, override static overrides if lower ([a7b66ea](https://github.com/iloveitaly/structlog-config/commit/a7b66ea626829b36a46ad4f73a4f1eb5bd12ca86))
11
- * patch structlog to support custom trace log level ([35c1dca](https://github.com/iloveitaly/structlog-config/commit/35c1dca852b1d746d3538d5082d7f5a25bedc056))
12
-
13
-
14
- ### Bug Fixes
15
-
16
- * ensure TRACE log level is properly registered and utilized in logger ([87dc788](https://github.com/iloveitaly/structlog-config/commit/87dc788c661bff5daa7d6ed5416cdc0a98322278))
17
- * include .js.map in static asset request detection ([ff9bb4a](https://github.com/iloveitaly/structlog-config/commit/ff9bb4a6c9cd8bde1e9989399eeb2b4efc7d334a))
18
-
19
-
20
- ### Documentation
21
-
22
- * clarify description of PYTHONASYNCIODEBUG constant ([2e2e0e9](https://github.com/iloveitaly/structlog-config/commit/2e2e0e9c07bfe80a0ba3e3d8b7278b76619cefa4))
23
- * ipython logging adjustment ([1990a7c](https://github.com/iloveitaly/structlog-config/commit/1990a7cc130c4e30256a19caf8079a1697d137b8))
24
- * update README with detailed logging setup instructions ([746fb8f](https://github.com/iloveitaly/structlog-config/commit/746fb8f64b542c74041141d787b62ff084b10805))
25
-
26
- ## 0.1.0 (2025-04-14)
27
-
28
-
29
- ### Features
30
-
31
- * add PathPrettifier for structlog path formatting ([b54bc58](https://github.com/iloveitaly/structlog-config/commit/b54bc58ef5d896675a69d809704829b3976763b7))
32
- * add RenameField processor for log key renaming ([a07bf36](https://github.com/iloveitaly/structlog-config/commit/a07bf363aa97631978c141c7385932f76ac30398))
33
- * add structured access logging for FastAPI requests ([37d506d](https://github.com/iloveitaly/structlog-config/commit/37d506dec89fc9c0de6a548371724c2342c0bafc))
34
- * allow loggers to be configured from environment variables ([417acf1](https://github.com/iloveitaly/structlog-config/commit/417acf1b9f5c0219191486c26ccdf6959956f329))
35
- * configure loggers via env variables in env_config.py ([2b920c4](https://github.com/iloveitaly/structlog-config/commit/2b920c4b0c373aabcb6b7d31503205268308ed83))
36
- * debug log static asset requests in FastAPI logger ([d8e5ee0](https://github.com/iloveitaly/structlog-config/commit/d8e5ee01af6b4ad5027010bf459fddf55263c8fc))
37
- * determine which optional packages are installed ([7e062e2](https://github.com/iloveitaly/structlog-config/commit/7e062e2a50902ce53295730d8ad69faa387b1997))
38
- * improve CI workflow and project setup ([2338dd0](https://github.com/iloveitaly/structlog-config/commit/2338dd06ed1c044123a11f5cc08278130da31d21))
39
- * update logger config for testing and add is_pytest function ([fe579ca](https://github.com/iloveitaly/structlog-config/commit/fe579ca8c0210934ca7d85294b6d3b5a1d567c68))
40
-
41
-
42
- ### Bug Fixes
43
-
44
- * dynamically pull the LOG_LEVEL from env for testing ([0cceb7c](https://github.com/iloveitaly/structlog-config/commit/0cceb7c541bd3f2d03ccf71392ee56ba5ae7f0bd))
45
- * ensure copier uses current HEAD for updates ([20b9f9d](https://github.com/iloveitaly/structlog-config/commit/20b9f9d64f7c09d22d149162af332954cad5d070))
46
-
47
-
48
- ### Documentation
49
-
50
- * add comments to middleware and formatter functions ([bf43006](https://github.com/iloveitaly/structlog-config/commit/bf43006ad538aa9e369c9a9fa251161feee0ea77))
51
- * add FastAPI access logger section to README.md ([93c6d98](https://github.com/iloveitaly/structlog-config/commit/93c6d98e5441f6f4c5e69dc9c618dfcfb556e7f4))
52
- * elaborate on FastAPI Access Logger usage and benefits ([aa4223e](https://github.com/iloveitaly/structlog-config/commit/aa4223e9db3726d5c12e699116ab84063103765b))
53
- * update project description and keywords in pyproject.toml ([6424d8a](https://github.com/iloveitaly/structlog-config/commit/6424d8a440d474a8feb4c8ddff322b2e17241126))
@@ -1,11 +0,0 @@
1
- setup:
2
- uv venv && uv sync
3
- @echo "activate: source ./.venv/bin/activate"
4
-
5
- clean:
6
- rm -rf *.egg-info
7
- rm -rf .venv
8
-
9
- update_copier:
10
- uv tool run --with jinja2_shell_extension \
11
- copier@latest update --vcs-ref=HEAD --trust --skip-tasks --skip-answered