mixin-logging 0.5.0__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.
- mixin_logging-0.5.0/.github/workflows/ci.yml +46 -0
- mixin_logging-0.5.0/.github/workflows/cleanup-guard.yml +63 -0
- mixin_logging-0.5.0/.github/workflows/dto-strict.yml +37 -0
- mixin_logging-0.5.0/.github/workflows/no-ai-attribution.yml +73 -0
- mixin_logging-0.5.0/.github/workflows/publish.yml +35 -0
- mixin_logging-0.5.0/.github/workflows/ruff.yml +29 -0
- mixin_logging-0.5.0/.gitignore +132 -0
- mixin_logging-0.5.0/CHANGELOG.md +121 -0
- mixin_logging-0.5.0/CODE_OF_CONDUCT.md +31 -0
- mixin_logging-0.5.0/CONTRIBUTING.md +66 -0
- mixin_logging-0.5.0/LICENSE +201 -0
- mixin_logging-0.5.0/PKG-INFO +731 -0
- mixin_logging-0.5.0/README.md +684 -0
- mixin_logging-0.5.0/SECURITY.md +21 -0
- mixin_logging-0.5.0/docs/RELEASE_NOTES_0.2.0.md +122 -0
- mixin_logging-0.5.0/docs/RELEASE_NOTES_0.3.0.md +70 -0
- mixin_logging-0.5.0/docs/apps/adapters/README.md +114 -0
- mixin_logging-0.5.0/docs/apps/adapters/aiohttp.md +70 -0
- mixin_logging-0.5.0/docs/apps/adapters/asgi.md +331 -0
- mixin_logging-0.5.0/docs/apps/adapters/botocore.md +76 -0
- mixin_logging-0.5.0/docs/apps/adapters/celery.md +126 -0
- mixin_logging-0.5.0/docs/apps/adapters/cloud.md +121 -0
- mixin_logging-0.5.0/docs/apps/adapters/diagrams.md +653 -0
- mixin_logging-0.5.0/docs/apps/adapters/graphql.md +100 -0
- mixin_logging-0.5.0/docs/apps/adapters/grpc.md +96 -0
- mixin_logging-0.5.0/docs/apps/adapters/httpx.md +148 -0
- mixin_logging-0.5.0/docs/apps/adapters/proposed-adapters.md +55 -0
- mixin_logging-0.5.0/docs/apps/adapters/requests.md +74 -0
- mixin_logging-0.5.0/docs/apps/adapters/stdlib.md +158 -0
- mixin_logging-0.5.0/docs/apps/adapters/urllib3.md +64 -0
- mixin_logging-0.5.0/docs/apps/adapters/websocket.md +77 -0
- mixin_logging-0.5.0/docs/apps/adapters/wsgi.md +136 -0
- mixin_logging-0.5.0/docs/apps/context/correlation.md +250 -0
- mixin_logging-0.5.0/docs/apps/context/diagrams.md +142 -0
- mixin_logging-0.5.0/docs/apps/decorators/diagrams.md +122 -0
- mixin_logging-0.5.0/docs/apps/decorators/logged.md +310 -0
- mixin_logging-0.5.0/docs/apps/mixin/mixin.md +174 -0
- mixin_logging-0.5.0/docs/apps/security-audit.md +353 -0
- mixin_logging-0.5.0/docs/architecture/architecture.md +352 -0
- mixin_logging-0.5.0/docs/audits/2026-05-27-wsgi-adapter-security-audit.md +270 -0
- mixin_logging-0.5.0/docs/audits/2026-05-28-httpx-adapter-security-audit.md +223 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-asgi-adapter-security-audit.md +317 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-botocore-adapter-security-audit.md +171 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-celery-adapter-security-audit.md +174 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-cloud-adapter-security-audit.md +222 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-requests-adapter-security-audit.md +187 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-restructure-conformance-security-audit.md +504 -0
- mixin_logging-0.5.0/docs/audits/2026-06-04-stdlib-adapter-security-audit.md +191 -0
- mixin_logging-0.5.0/docs/audits/2026-06-09-standards-sweep-round2-security-audit.md +381 -0
- mixin_logging-0.5.0/docs/audits/2026-06-09-standards-sweep-security-audit.md +355 -0
- mixin_logging-0.5.0/docs/audits/2026-06-19-aiohttp-adapter-security-audit.md +209 -0
- mixin_logging-0.5.0/docs/audits/2026-06-19-graphql-adapter-security-audit.md +193 -0
- mixin_logging-0.5.0/docs/audits/2026-06-19-grpc-adapter-security-audit.md +176 -0
- mixin_logging-0.5.0/docs/audits/2026-06-19-urllib3-adapter-security-audit.md +191 -0
- mixin_logging-0.5.0/docs/audits/2026-06-19-websocket-adapter-security-audit.md +221 -0
- mixin_logging-0.5.0/docs/reviews/2026-05-27-wsgi-adapter-review.md +376 -0
- mixin_logging-0.5.0/docs/reviews/2026-05-28-httpx-adapter-review.md +204 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-asgi-adapter-review.md +309 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-botocore-adapter-review.md +222 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-celery-adapter-review.md +228 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-cloud-adapter-review.md +242 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-requests-adapter-review.md +234 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-restructure-conformance-review.md +255 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-04-stdlib-adapter-review.md +194 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-09-standards-sweep-review.md +251 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-09-standards-sweep-round2-review.md +289 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-19-aiohttp-adapter-review.md +238 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-19-graphql-adapter-review.md +228 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-19-grpc-adapter-review.md +250 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-19-urllib3-adapter-review.md +224 -0
- mixin_logging-0.5.0/docs/reviews/2026-06-19-websocket-adapter-review.md +247 -0
- mixin_logging-0.5.0/mixin_logging/__init__.py +35 -0
- mixin_logging-0.5.0/mixin_logging/adapters/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/aiohttp/__init__.py +13 -0
- mixin_logging-0.5.0/mixin_logging/adapters/aiohttp/aiohttp_client.py +33 -0
- mixin_logging-0.5.0/mixin_logging/adapters/aiohttp/aiohttp_objects.py +43 -0
- mixin_logging-0.5.0/mixin_logging/adapters/asgi/__init__.py +23 -0
- mixin_logging-0.5.0/mixin_logging/adapters/asgi/asgi_client.py +60 -0
- mixin_logging-0.5.0/mixin_logging/adapters/asgi/asgi_objects.py +69 -0
- mixin_logging-0.5.0/mixin_logging/adapters/botocore/__init__.py +18 -0
- mixin_logging-0.5.0/mixin_logging/adapters/botocore/botocore_client.py +36 -0
- mixin_logging-0.5.0/mixin_logging/adapters/botocore/botocore_objects.py +41 -0
- mixin_logging-0.5.0/mixin_logging/adapters/celery/__init__.py +13 -0
- mixin_logging-0.5.0/mixin_logging/adapters/celery/celery_client.py +48 -0
- mixin_logging-0.5.0/mixin_logging/adapters/celery/celery_objects.py +41 -0
- mixin_logging-0.5.0/mixin_logging/adapters/cloud/__init__.py +11 -0
- mixin_logging-0.5.0/mixin_logging/adapters/cloud/cloud_client.py +22 -0
- mixin_logging-0.5.0/mixin_logging/adapters/cloud/cloud_objects.py +68 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/aiohttp.py +34 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/asgi.py +54 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/botocore.py +43 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/celery.py +40 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/cloud.py +58 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/graphql.py +14 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/grpc.py +32 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/httpx.py +40 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/requests.py +34 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/stdlib.py +20 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/urllib3.py +34 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/websocket.py +46 -0
- mixin_logging-0.5.0/mixin_logging/adapters/constants/wsgi.py +34 -0
- mixin_logging-0.5.0/mixin_logging/adapters/graphql/__init__.py +13 -0
- mixin_logging-0.5.0/mixin_logging/adapters/graphql/graphql_client.py +19 -0
- mixin_logging-0.5.0/mixin_logging/adapters/graphql/graphql_objects.py +27 -0
- mixin_logging-0.5.0/mixin_logging/adapters/grpc/__init__.py +15 -0
- mixin_logging-0.5.0/mixin_logging/adapters/grpc/grpc_client.py +28 -0
- mixin_logging-0.5.0/mixin_logging/adapters/grpc/grpc_objects.py +44 -0
- mixin_logging-0.5.0/mixin_logging/adapters/httpx/__init__.py +19 -0
- mixin_logging-0.5.0/mixin_logging/adapters/httpx/httpx_client.py +36 -0
- mixin_logging-0.5.0/mixin_logging/adapters/httpx/httpx_objects.py +51 -0
- mixin_logging-0.5.0/mixin_logging/adapters/requests/__init__.py +13 -0
- mixin_logging-0.5.0/mixin_logging/adapters/requests/requests_client.py +36 -0
- mixin_logging-0.5.0/mixin_logging/adapters/requests/requests_objects.py +41 -0
- mixin_logging-0.5.0/mixin_logging/adapters/stdlib/__init__.py +9 -0
- mixin_logging-0.5.0/mixin_logging/adapters/stdlib/stdlib_client.py +28 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/__init__.py +0 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_aiohttp/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_aiohttp/conftest.py +35 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_aiohttp/test_aiohttp_client.py +89 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_aiohttp/test_aiohttp_objects.py +105 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_asgi/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_asgi/conftest.py +248 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_asgi/test_asgi_client.py +221 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_asgi/test_asgi_objects.py +228 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_botocore/__init__.py +0 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_botocore/conftest.py +33 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_botocore/test_botocore_client.py +120 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_botocore/test_botocore_objects.py +103 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_celery/__init__.py +0 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_celery/conftest.py +35 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_celery/test_celery_client.py +201 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_celery/test_celery_objects.py +118 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_cloud/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_cloud/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_cloud/test_cloud_client.py +201 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_cloud/test_cloud_extraction.py +245 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_cloud/test_cloud_objects.py +94 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_graphql/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_graphql/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_graphql/test_graphql_client.py +59 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_graphql/test_graphql_objects.py +44 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_grpc/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_grpc/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_grpc/test_grpc_client.py +175 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_grpc/test_grpc_objects.py +173 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_httpx/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_httpx/conftest.py +33 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_httpx/test_httpx_client.py +112 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_httpx/test_httpx_objects.py +98 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_requests/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_requests/conftest.py +34 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_requests/test_requests_client.py +149 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_requests/test_requests_objects.py +110 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_stdlib/__init__.py +0 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_stdlib/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_stdlib/test_stdlib_client.py +244 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_urllib3/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_urllib3/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_urllib3/test_urllib3_client.py +231 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_urllib3/test_urllib3_objects.py +110 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_websocket/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_websocket/conftest.py +151 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_websocket/test_websocket_client.py +172 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_websocket/test_websocket_objects.py +169 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_wsgi/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_wsgi/conftest.py +116 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_wsgi/test_wsgi_client.py +171 -0
- mixin_logging-0.5.0/mixin_logging/adapters/tests/test_wsgi/test_wsgi_objects.py +75 -0
- mixin_logging-0.5.0/mixin_logging/adapters/urllib3/__init__.py +13 -0
- mixin_logging-0.5.0/mixin_logging/adapters/urllib3/urllib3_client.py +30 -0
- mixin_logging-0.5.0/mixin_logging/adapters/urllib3/urllib3_objects.py +43 -0
- mixin_logging-0.5.0/mixin_logging/adapters/websocket/__init__.py +15 -0
- mixin_logging-0.5.0/mixin_logging/adapters/websocket/websocket_client.py +38 -0
- mixin_logging-0.5.0/mixin_logging/adapters/websocket/websocket_objects.py +50 -0
- mixin_logging-0.5.0/mixin_logging/adapters/wsgi/__init__.py +25 -0
- mixin_logging-0.5.0/mixin_logging/adapters/wsgi/wsgi_client.py +57 -0
- mixin_logging-0.5.0/mixin_logging/adapters/wsgi/wsgi_objects.py +52 -0
- mixin_logging-0.5.0/mixin_logging/common/__init__.py +7 -0
- mixin_logging-0.5.0/mixin_logging/common/constants/__init__.py +7 -0
- mixin_logging-0.5.0/mixin_logging/common/constants/public_api.py +24 -0
- mixin_logging-0.5.0/mixin_logging/common/constants/tests.py +129 -0
- mixin_logging-0.5.0/mixin_logging/common/tests/__init__.py +5 -0
- mixin_logging-0.5.0/mixin_logging/common/tests/conftest.py +17 -0
- mixin_logging-0.5.0/mixin_logging/common/tests/test_public_api.py +96 -0
- mixin_logging-0.5.0/mixin_logging/common/tests/test_record_collector.py +97 -0
- mixin_logging-0.5.0/mixin_logging/common/utils/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/common/utils/record_collector.py +20 -0
- mixin_logging-0.5.0/mixin_logging/config/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/config/_version.py +3 -0
- mixin_logging-0.5.0/mixin_logging/context/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/context/constants/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/context/constants/correlation.py +22 -0
- mixin_logging-0.5.0/mixin_logging/context/correlation/__init__.py +19 -0
- mixin_logging-0.5.0/mixin_logging/context/correlation/correlation_client.py +40 -0
- mixin_logging-0.5.0/mixin_logging/context/correlation/correlation_objects.py +17 -0
- mixin_logging-0.5.0/mixin_logging/context/tests/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/context/tests/test_correlation/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/context/tests/test_correlation/conftest.py +20 -0
- mixin_logging-0.5.0/mixin_logging/context/tests/test_correlation/test_correlation_client.py +102 -0
- mixin_logging-0.5.0/mixin_logging/context/tests/test_correlation/test_correlation_objects.py +44 -0
- mixin_logging-0.5.0/mixin_logging/decorators/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/decorators/constants/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/decorators/constants/decorators.py +42 -0
- mixin_logging-0.5.0/mixin_logging/decorators/logged/__init__.py +15 -0
- mixin_logging-0.5.0/mixin_logging/decorators/logged/logged_client.py +65 -0
- mixin_logging-0.5.0/mixin_logging/decorators/logged/logged_objects.py +29 -0
- mixin_logging-0.5.0/mixin_logging/decorators/tests/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/decorators/tests/test_logged/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/decorators/tests/test_logged/conftest.py +59 -0
- mixin_logging-0.5.0/mixin_logging/decorators/tests/test_logged/test_logged_client.py +213 -0
- mixin_logging-0.5.0/mixin_logging/decorators/tests/test_logged/test_logged_objects.py +32 -0
- mixin_logging-0.5.0/mixin_logging/mixin/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/mixin/mixin.py +52 -0
- mixin_logging-0.5.0/mixin_logging/mixin/tests/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/mixin/tests/test_mixin/__init__.py +1 -0
- mixin_logging-0.5.0/mixin_logging/mixin/tests/test_mixin/conftest.py +43 -0
- mixin_logging-0.5.0/mixin_logging/mixin/tests/test_mixin/test_mixin.py +242 -0
- mixin_logging-0.5.0/mixin_logging/py.typed +0 -0
- mixin_logging-0.5.0/pyproject.toml +124 -0
- mixin_logging-0.5.0/pyrightconfig.json +5 -0
- mixin_logging-0.5.0/uv.lock +1661 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.11", "3.12"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: astral-sh/setup-uv@v4
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
- name: Install Python
|
|
27
|
+
run: uv python install ${{ matrix.python-version }}
|
|
28
|
+
- name: Sync dependencies
|
|
29
|
+
run: uv sync --all-extras
|
|
30
|
+
- name: Test
|
|
31
|
+
run: uv run pytest -v --cov --cov-fail-under=95
|
|
32
|
+
|
|
33
|
+
mypy:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: astral-sh/setup-uv@v4
|
|
38
|
+
with:
|
|
39
|
+
enable-cache: true
|
|
40
|
+
- name: Install Python 3.12
|
|
41
|
+
run: uv python install 3.12
|
|
42
|
+
- name: Sync dependencies
|
|
43
|
+
run: uv sync --all-extras
|
|
44
|
+
- name: Type-check
|
|
45
|
+
run: uv run mypy mixin_logging/
|
|
46
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Cleanup Guard
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
adapter-documentation:
|
|
8
|
+
name: Verify all adapters have audit and review docs
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- name: Check adapter documentation completeness
|
|
13
|
+
run: |
|
|
14
|
+
set -e
|
|
15
|
+
|
|
16
|
+
echo "Checking that all adapter packages have audit and review documentation..."
|
|
17
|
+
|
|
18
|
+
ADAPTERS_DIR="mixin_logging/adapters"
|
|
19
|
+
AUDITS_DIR="docs/audits"
|
|
20
|
+
REVIEWS_DIR="docs/reviews"
|
|
21
|
+
|
|
22
|
+
if [ ! -d "$ADAPTERS_DIR" ]; then
|
|
23
|
+
echo "ERROR: Adapters directory not found: $ADAPTERS_DIR"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Find all adapter directories (exclude non-adapter dirs like constants, tests, __pycache__)
|
|
28
|
+
ADAPTERS=$(find "$ADAPTERS_DIR" -maxdepth 1 -type d ! -name "__pycache__" ! -name "tests" ! -name "constants" ! -name "adapters" ! -path "$ADAPTERS_DIR")
|
|
29
|
+
|
|
30
|
+
MISSING_DOCS=0
|
|
31
|
+
|
|
32
|
+
for adapter_dir in $ADAPTERS; do
|
|
33
|
+
adapter_name=$(basename "$adapter_dir")
|
|
34
|
+
|
|
35
|
+
# Skip if no adapter files (empty directory)
|
|
36
|
+
if [ -z "$(find "$adapter_dir" -maxdepth 1 -type f -name "*.py")" ]; then
|
|
37
|
+
continue
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
audit_file=$(find "$AUDITS_DIR" -name "*$adapter_name*audit*" 2>/dev/null | head -1)
|
|
41
|
+
review_file=$(find "$REVIEWS_DIR" -name "*$adapter_name*review*" 2>/dev/null | head -1)
|
|
42
|
+
|
|
43
|
+
if [ -z "$audit_file" ]; then
|
|
44
|
+
echo "FAIL: Adapter '$adapter_name' missing audit doc in $AUDITS_DIR"
|
|
45
|
+
MISSING_DOCS=$((MISSING_DOCS + 1))
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if [ -z "$review_file" ]; then
|
|
49
|
+
echo "FAIL: Adapter '$adapter_name' missing review doc in $REVIEWS_DIR"
|
|
50
|
+
MISSING_DOCS=$((MISSING_DOCS + 1))
|
|
51
|
+
fi
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
if [ $MISSING_DOCS -gt 0 ]; then
|
|
55
|
+
echo ""
|
|
56
|
+
echo "ERROR: $MISSING_DOCS adapter(s) missing documentation."
|
|
57
|
+
echo "Each adapter under mixin_logging/adapters/<name>/ must have:"
|
|
58
|
+
echo " - docs/audits/*<name>*audit*.md"
|
|
59
|
+
echo " - docs/reviews/*<name>*review*.md"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo "✓ All adapter packages have corresponding audit and review docs."
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: dto-strict
|
|
2
|
+
|
|
3
|
+
# DTO-discipline lint (frozen+slots, facade-ban, R001-R006). Per-repo copy of
|
|
4
|
+
# the canonical gate; runs on the root-layout package. Empty baseline at
|
|
5
|
+
# v0.2.0 (clean rebuild — 0 violations).
|
|
6
|
+
# Lint step: whole package (native test-file exemption via R007/R008 rules).
|
|
7
|
+
# LOC-cap step: source dirs only (test density exempt from cap per review record).
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
pull_request:
|
|
11
|
+
push:
|
|
12
|
+
branches: [main]
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
lint:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: astral-sh/setup-uv@v4
|
|
27
|
+
with:
|
|
28
|
+
enable-cache: true
|
|
29
|
+
- name: Install Python 3.12
|
|
30
|
+
run: uv python install 3.12
|
|
31
|
+
- name: Run dto-strict
|
|
32
|
+
run: uvx --python 3.12 dto-strict@0.3.0 mixin_logging/ --format github
|
|
33
|
+
- name: Check LOC cap
|
|
34
|
+
run: |
|
|
35
|
+
for dir in mixin_logging/adapters/{aiohttp,asgi,botocore,celery,cloud,constants,graphql,grpc,httpx,requests,stdlib,urllib3,websocket,wsgi} mixin_logging/common/{constants,utils} mixin_logging/config mixin_logging/context/{constants,correlation} mixin_logging/decorators/{constants,logged} mixin_logging/mixin; do
|
|
36
|
+
uvx --python 3.12 dto-strict@0.3.0 loc-cap "$dir"
|
|
37
|
+
done
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: Attribution Gate
|
|
2
|
+
|
|
3
|
+
# Server-side enforcement: rejects pushes/PRs whose commit messages contain
|
|
4
|
+
# Claude/Anthropic attribution. Catches GitHub squash-merge propagation that
|
|
5
|
+
# bypasses local commit-msg, pre-push, and PreToolUse hooks.
|
|
6
|
+
#
|
|
7
|
+
# Per-repo copy of the canonical attribution gate.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
pull_request:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
pull-requests: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
scan:
|
|
19
|
+
name: Scan commit messages for attribution
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout (full history)
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Determine commit range
|
|
28
|
+
id: range
|
|
29
|
+
env:
|
|
30
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
31
|
+
PR_BASE: ${{ github.event.pull_request.base.sha }}
|
|
32
|
+
PR_HEAD: ${{ github.event.pull_request.head.sha }}
|
|
33
|
+
PUSH_BEFORE: ${{ github.event.before }}
|
|
34
|
+
PUSH_AFTER: ${{ github.event.after }}
|
|
35
|
+
run: |
|
|
36
|
+
set -euo pipefail
|
|
37
|
+
if [ "$EVENT_NAME" = "pull_request" ]; then
|
|
38
|
+
BASE="$PR_BASE"
|
|
39
|
+
HEAD="$PR_HEAD"
|
|
40
|
+
else
|
|
41
|
+
BASE="$PUSH_BEFORE"
|
|
42
|
+
HEAD="$PUSH_AFTER"
|
|
43
|
+
if [ "$BASE" = "0000000000000000000000000000000000000000" ] || [ -z "$BASE" ]; then
|
|
44
|
+
git fetch origin main:refs/remotes/origin/main 2>/dev/null || true
|
|
45
|
+
BASE=$(git merge-base origin/main "$HEAD" 2>/dev/null || git rev-list --max-parents=0 "$HEAD" | tail -1)
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
echo "base=$BASE" >> "$GITHUB_OUTPUT"
|
|
49
|
+
echo "head=$HEAD" >> "$GITHUB_OUTPUT"
|
|
50
|
+
|
|
51
|
+
- name: Scan for Claude/Anthropic attribution
|
|
52
|
+
env:
|
|
53
|
+
BASE: ${{ steps.range.outputs.base }}
|
|
54
|
+
HEAD: ${{ steps.range.outputs.head }}
|
|
55
|
+
PATTERN: 'co-authored-by.*(claude|anthropic)|generated with claude|@claude|noreply@anthropic|🤖'
|
|
56
|
+
run: |
|
|
57
|
+
set -uo pipefail
|
|
58
|
+
OFFENDING=""
|
|
59
|
+
for sha in $(git rev-list "$BASE..$HEAD"); do
|
|
60
|
+
MSG=$(git log -1 --pretty=format:"%B" "$sha")
|
|
61
|
+
if echo "$MSG" | grep -qiE "$PATTERN"; then
|
|
62
|
+
AUTHOR=$(git log -1 --pretty=format:"%an" "$sha")
|
|
63
|
+
SUBJECT=$(git log -1 --pretty=format:"%s" "$sha")
|
|
64
|
+
OFFENDING="${OFFENDING} ${sha:0:8} | author=${AUTHOR} | ${SUBJECT}"$'\n'
|
|
65
|
+
fi
|
|
66
|
+
done
|
|
67
|
+
if [ -n "$OFFENDING" ]; then
|
|
68
|
+
echo "::error::Claude/Anthropic attribution detected in commit messages"
|
|
69
|
+
echo "Offending commits in range $BASE..$HEAD:"
|
|
70
|
+
printf '%s' "$OFFENDING"
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
echo "OK: no attribution detected in $BASE..$HEAD"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
name: Build + publish
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi # second-layer GitHub deployment-environment gate
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write # OIDC trusted publisher
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.12'
|
|
24
|
+
|
|
25
|
+
- name: Install build deps
|
|
26
|
+
run: python -m pip install --upgrade build
|
|
27
|
+
|
|
28
|
+
- name: Build sdist + wheel
|
|
29
|
+
run: python -m build
|
|
30
|
+
|
|
31
|
+
- name: Verify artifacts
|
|
32
|
+
run: python -m pip install --upgrade twine && python -m twine check dist/*
|
|
33
|
+
|
|
34
|
+
- name: Publish to PyPI
|
|
35
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Ruff
|
|
2
|
+
|
|
3
|
+
# Ruff lint + format check. Pinned to 0.15.14 to match local version.
|
|
4
|
+
# Format drift was previously undetected; this gate prevents future drift.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
pull_request:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
ruff:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: astral-sh/setup-uv@v4
|
|
24
|
+
with:
|
|
25
|
+
enable-cache: true
|
|
26
|
+
- name: Ruff lint
|
|
27
|
+
run: uvx ruff@0.15.14 check mixin_logging/
|
|
28
|
+
- name: Ruff format check
|
|
29
|
+
run: uvx ruff@0.15.14 format --check mixin_logging/
|
|
@@ -0,0 +1,132 @@
|
|
|
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
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
*.py,cover
|
|
49
|
+
.hypothesis/
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
local_settings.py
|
|
59
|
+
db.sqlite3
|
|
60
|
+
db.sqlite3-journal
|
|
61
|
+
|
|
62
|
+
# Flask stuff:
|
|
63
|
+
instance/
|
|
64
|
+
.webassets-cache
|
|
65
|
+
|
|
66
|
+
# Scrapy stuff:
|
|
67
|
+
.scrapy
|
|
68
|
+
|
|
69
|
+
# Sphinx documentation
|
|
70
|
+
docs/_build/
|
|
71
|
+
|
|
72
|
+
# PyBuilder
|
|
73
|
+
target/
|
|
74
|
+
|
|
75
|
+
# Jupyter Notebook
|
|
76
|
+
.ipynb_checkpoints
|
|
77
|
+
|
|
78
|
+
# IPython
|
|
79
|
+
profile_default/
|
|
80
|
+
ipython_config.py
|
|
81
|
+
|
|
82
|
+
# pyenv
|
|
83
|
+
.python-version
|
|
84
|
+
|
|
85
|
+
# pipenv
|
|
86
|
+
Pipfile.lock
|
|
87
|
+
|
|
88
|
+
# PEP 582
|
|
89
|
+
__pypackages__/
|
|
90
|
+
|
|
91
|
+
# Celery stuff
|
|
92
|
+
celerybeat-schedule
|
|
93
|
+
celerybeat.pid
|
|
94
|
+
|
|
95
|
+
# SageMath parsed files
|
|
96
|
+
*.sage.py
|
|
97
|
+
|
|
98
|
+
# Environments
|
|
99
|
+
.env
|
|
100
|
+
.venv
|
|
101
|
+
env/
|
|
102
|
+
venv/
|
|
103
|
+
ENV/
|
|
104
|
+
env.bak/
|
|
105
|
+
venv.bak/
|
|
106
|
+
|
|
107
|
+
# Spyder project settings
|
|
108
|
+
.spyderproject
|
|
109
|
+
.spyproject
|
|
110
|
+
|
|
111
|
+
# Rope project settings
|
|
112
|
+
.ropeproject
|
|
113
|
+
|
|
114
|
+
# mkdocs documentation
|
|
115
|
+
/site
|
|
116
|
+
|
|
117
|
+
# mypy
|
|
118
|
+
.mypy_cache/
|
|
119
|
+
.dmypy.json
|
|
120
|
+
dmypy.json
|
|
121
|
+
|
|
122
|
+
# Pyre type checker
|
|
123
|
+
.pyre/
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# IDE
|
|
127
|
+
.vscode/
|
|
128
|
+
.idea/
|
|
129
|
+
*.swp
|
|
130
|
+
*.swo
|
|
131
|
+
*~
|
|
132
|
+
.DS_Store
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.5.0] - 2026-07-06
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Package rename: logging-mixin to mixin-logging**: Following the govtech OSS suite category-first naming convention (`<category>-<name>`). Distribution name on PyPI changes from `logging-mixin` to `mixin-logging`. Import root changes from `logging_mixin` to `mixin_logging`. The old `logging-mixin` distribution stays live on PyPI for backward compatibility; old pins continue to work.
|
|
15
|
+
- **All public symbols remain unchanged**: `LoggingMixin`, `@logged`, correlation ID API (`set_correlation_id`, `get_correlation_id`, `clear_correlation_id`), and all 13 adapters retain their names and signatures. Only the module path changes.
|
|
16
|
+
- **Version bump to 0.5.0**: Minor version bump reflects the rename; code content is identical to v0.4.0.
|
|
17
|
+
|
|
18
|
+
### Migration Guide
|
|
19
|
+
|
|
20
|
+
Update your imports:
|
|
21
|
+
```python
|
|
22
|
+
# Old (v0.4.0)
|
|
23
|
+
from logging_mixin import LoggingMixin
|
|
24
|
+
|
|
25
|
+
# New (v0.5.0+)
|
|
26
|
+
from mixin_logging import LoggingMixin
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Update your dependency pin:
|
|
30
|
+
```bash
|
|
31
|
+
# Old
|
|
32
|
+
uv add logging-mixin
|
|
33
|
+
|
|
34
|
+
# New
|
|
35
|
+
uv add mixin-logging
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## [0.3.0] - 2026-06-10
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **Public API surface**: Explicit `PUBLIC_API` export from top-level package with lockstep conformance test. `LoggingMixin`, `CorrelationIdInjector`, and adapter middleware classes available directly from `logging_mixin`. Sub-package constants surfaced via `logging_mixin.constants.<adapter>`.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- **Standards-conformance sweep**: Unified constants organization and semantic-literal extraction across all adapters and common modules. Canonical docstring-format section headers and deep extraction to dedicated constants modules. Integration with `dto-strict` v0.2.2+ for dataclass configuration and metadata validation.
|
|
47
|
+
- **Docstring and naming conformance**: Package-wide consistency in documentation and parameter naming. All public methods, classes, and packages now start with imperative action verbs. One-line verb-phrase docstrings and scoped module docstrings for semantic clarity.
|
|
48
|
+
- **Publish workflow trigger**: Release workflow now triggered by version-tag push instead of release-branch. Chore/release-* branch pattern deprecated.
|
|
49
|
+
|
|
50
|
+
## [0.4.0] - 2026-06-29
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **5 new correlation-ID adapters**: Extended adapter suite from 8 to 13 for broader protocol coverage:
|
|
55
|
+
- **aiohttp Adapter** (`logging_mixin/adapters/aiohttp/`): Outbound `aiohttp.ClientSession` instrumentation. Injects `X-Correlation-ID` header via `TraceConfig` on every request.
|
|
56
|
+
- **urllib3 Adapter** (`logging_mixin/adapters/urllib3/`): Outbound `urllib3.PoolManager` instrumentation. Injects `X-Correlation-ID` header on every request via `urlopen()` override.
|
|
57
|
+
- **gRPC Adapter** (`logging_mixin/adapters/grpc/`): Inbound gRPC server interceptor. Extracts correlation ID from invocation metadata; auto-generates fallback. Sets context for handler execution.
|
|
58
|
+
- **WebSocket Adapter** (`logging_mixin/adapters/websocket/`): Inbound ASGI WebSocket middleware. Extracts correlation ID from handshake headers; auto-generates fallback. Sets context for WebSocket connection lifecycle.
|
|
59
|
+
- **GraphQL Adapter** (`logging_mixin/adapters/graphql/`): Resolver-context injector. Reads correlation ID from upstream context (set by ASGI/WSGI); exposes via resolver context dict.
|
|
60
|
+
|
|
61
|
+
- **Optional dependency extras**: Added 3 new extras for the new adapters:
|
|
62
|
+
- `[aiohttp]`: aiohttp client instrumentation
|
|
63
|
+
- `[urllib3]`: urllib3 client instrumentation
|
|
64
|
+
- `[grpc]`: gRPC server instrumentation (requires `grpcio`)
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **Canonical import-idiom enforcement**: Applied `ruff isort` + `PLC0414` (redundant-self-aliases) to standardize imports across adapters. Removed self-referential re-exports in adapter `__init__` files (PR #51).
|
|
69
|
+
- **LOC-cap scoping refinement**: Adjusted line-count enforcement to target source code only, excluding tests. Configuration in `[tool.dto-strict.loc-cap]` remains (hard_cap=300, soft_target=200), but scope now focuses on maintainability of production code (PR #50).
|
|
70
|
+
- **Documentation improvements**: Extensive docs refresh: adapter table expansion, correlation semantics clarification, FAQ additions, version sweep across README and guides. Code of Conduct alignment with Contributor Covenant 2.1 (PR #44, #47).
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- **Publish workflow trigger**: Corrected publish.yml to fire on GitHub Release published (suite standard), not on push to main. Prevents accidental PyPI uploads from merge commits (PR #49).
|
|
75
|
+
- **Pyright editor integration**: Added `venv` binding in pyrightconfig.json for editor type-server resolution, enabling accurate type hints in VS Code (PR #48).
|
|
76
|
+
|
|
77
|
+
## [0.2.0] - 2026-06-05
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- **Complete correlation-ID adapter suite**: 8 adapters for end-to-end correlation ID propagation across the full request/response lifecycle:
|
|
82
|
+
- **ASGI Adapter** (`logging_mixin/adapters/asgi/`): FastAPI, Starlette, Quart, and other ASGI frameworks. `AsgiCorrelation` value object extracts or generates correlation ID from ASGI request scope. `CorrelationIdMiddleware` propagates across request lifecycle. Input validation via `_is_safe()` rejects control characters (`\r\n\0`), enforces max length (128 bytes), guards against invalid UTF-8. Response header injection automatically echoes correlation ID.
|
|
83
|
+
- **WSGI Adapter** (`logging_mixin/adapters/wsgi/`): Django, Flask, Pyramid, and other WSGI frameworks. Inbound middleware extraction + response header injection.
|
|
84
|
+
- **HTTPX Adapter** (`logging_mixin/adapters/httpx/`): Outbound `httpx.Client` and async `httpx.AsyncClient` instrumentation. Injects `X-Correlation-ID` on every request.
|
|
85
|
+
- **Requests Adapter** (`logging_mixin/adapters/requests/`): Outbound `requests.Session` instrumentation via `CorrelationHTTPAdapter`. Injects `X-Correlation-ID` on every request.
|
|
86
|
+
- **Botocore Adapter** (`logging_mixin/adapters/botocore/`): AWS SDK instrumentation. Injects `X-Correlation-ID` into all AWS service calls via event system hooks.
|
|
87
|
+
- **Celery Adapter** (`logging_mixin/adapters/celery/`): Task-boundary propagation via Celery signals (publish → prerun → postrun). Maintains correlation ID across async task execution.
|
|
88
|
+
- **Stdlib Adapter** (`logging_mixin/adapters/stdlib/`): `logging.Filter` implementation. Stamps `correlation_id` on every `LogRecord` automatically.
|
|
89
|
+
- **Cloud Adapter** (`logging_mixin/adapters/cloud/`): Inbound AWS Lambda event extraction. Supports API Gateway, ALB, SQS, SNS, EventBridge, and top-level direct-invoke. Auto-generates fallback correlation ID if not present.
|
|
90
|
+
|
|
91
|
+
- **ASGI Adapter Robustness Hardening**: Input validation and defensive decoding to prevent log/header injection and resource exhaustion:
|
|
92
|
+
- CRLF injection and log injection prevention via `_is_safe()`: rejects control characters (`\r\n\0`), enforces 128-byte max length, and requires non-empty values.
|
|
93
|
+
- UTF-8 decoding safety: try-except guard on header decoding; invalid UTF-8 triggers UUID4 fallback rather than crash.
|
|
94
|
+
- Empty-string rejection: validation guards against semantic invariant violation (empty correlation IDs).
|
|
95
|
+
- Type-safe header iteration: defensive handling of ASGI header byte-tuples; malformed headers skipped gracefully.
|
|
96
|
+
|
|
97
|
+
- **Optional-dependency extras**: Added explicit package extras for all adapter dependencies:
|
|
98
|
+
- `[httpx]`: HTTPX client instrumentation
|
|
99
|
+
- `[requests]`: Requests client instrumentation
|
|
100
|
+
- `[celery]`: Celery task propagation
|
|
101
|
+
- `[botocore]`: AWS SDK instrumentation
|
|
102
|
+
- `[all]`: Installs all adapter dependencies at once (convenience extra)
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- **Dependency management**: Adopted `uv` for faster, more predictable lock-file generation. Committed `uv.lock`; CI migrated to `astral-sh/setup-uv@v4`.
|
|
107
|
+
- **Python version requirement**: Dropped Python 3.10 support. Now requires Python >=3.11 (3.11 and 3.12 supported).
|
|
108
|
+
- **Package layout**: Root-layout restructure: `logging_mixin/adapters/` package with 8 specialized adapter modules (objects/ + client/ split per adapter type).
|
|
109
|
+
- **LOC-cap CI gate**: Automated line-count enforcement via `dto-strict loc-cap` subcommand; vendored `scripts/check_loc_cap.py` removed. Configuration in `[tool.dto-strict.loc-cap]` (hard_cap=300, soft_target=200).
|
|
110
|
+
|
|
111
|
+
### Removed
|
|
112
|
+
|
|
113
|
+
- **Python 3.10 classifier**: Dropped from supported versions in `pyproject.toml`.
|
|
114
|
+
|
|
115
|
+
## [0.1.0] - 2026-05-15
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
|
|
119
|
+
- Initial release.
|
|
120
|
+
- Core logging mixin infrastructure.
|
|
121
|
+
- Correlation ID context management.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## My Commitment
|
|
4
|
+
|
|
5
|
+
I maintain this project solo, and I am committed to keeping it a welcoming space for everyone who participates in issues, pull requests, and discussions. I pledge to treat every participant with respect and dignity, regardless of age, body size, caste, disability, ethnicity, sex characteristics, gender, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity and orientation, or any other dimension of diversity.
|
|
6
|
+
|
|
7
|
+
## Standards
|
|
8
|
+
|
|
9
|
+
Behavior that keeps this a positive space:
|
|
10
|
+
|
|
11
|
+
- Welcoming and inclusive language
|
|
12
|
+
- Respect for differing viewpoints and experiences
|
|
13
|
+
- Gracefully accepting constructive criticism
|
|
14
|
+
- Focusing on what is best for the project
|
|
15
|
+
- Empathy toward other participants
|
|
16
|
+
|
|
17
|
+
Behavior I will not accept:
|
|
18
|
+
|
|
19
|
+
- Harassment or insulting or derogatory comments
|
|
20
|
+
- Personal attacks
|
|
21
|
+
- Public or private harassment
|
|
22
|
+
- Publishing someone's private information without consent
|
|
23
|
+
- Conduct that could reasonably be considered inappropriate
|
|
24
|
+
|
|
25
|
+
## Enforcement
|
|
26
|
+
|
|
27
|
+
Report unacceptable behavior to me through GitHub, either by opening an issue or, where discretion is warranted, through private vulnerability reporting. I review and act on every report promptly and fairly, and I respect the privacy and security of anyone who reports.
|
|
28
|
+
|
|
29
|
+
## Attribution
|
|
30
|
+
|
|
31
|
+
This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to logging-mixin!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
- Python 3.11 or later
|
|
9
|
+
- [uv](https://docs.astral.sh/uv/) for dependency management
|
|
10
|
+
|
|
11
|
+
### Local Setup
|
|
12
|
+
|
|
13
|
+
1. Clone the repository:
|
|
14
|
+
```bash
|
|
15
|
+
git clone https://github.com/jekhator/logging-mixin.git
|
|
16
|
+
cd logging-mixin
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Install dependencies and all optional extras:
|
|
20
|
+
```bash
|
|
21
|
+
uv sync --all-extras
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. Verify the setup by running tests:
|
|
25
|
+
```bash
|
|
26
|
+
uv run pytest
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Running Tests
|
|
30
|
+
|
|
31
|
+
Execute the full test suite:
|
|
32
|
+
```bash
|
|
33
|
+
uv run pytest
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For coverage report:
|
|
37
|
+
```bash
|
|
38
|
+
uv run pytest --cov=logging_mixin
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Linting and Code Style
|
|
42
|
+
|
|
43
|
+
Format and lint your code before committing:
|
|
44
|
+
```bash
|
|
45
|
+
uv run ruff check --fix .
|
|
46
|
+
uv run ruff format .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Submitting Changes
|
|
50
|
+
|
|
51
|
+
1. Create a feature branch from `main`
|
|
52
|
+
2. Make your changes with clear, focused commits
|
|
53
|
+
3. Add tests for new functionality
|
|
54
|
+
4. Ensure all tests pass: `uv run pytest`
|
|
55
|
+
5. Ensure linting passes: `uv run ruff check .`
|
|
56
|
+
6. Push your branch and open a pull request against `main`
|
|
57
|
+
|
|
58
|
+
## Pull Request Requirements
|
|
59
|
+
|
|
60
|
+
All pull requests must:
|
|
61
|
+
- Pass all CI checks (tests, linting, type checks)
|
|
62
|
+
- Include tests for new code
|
|
63
|
+
- Update documentation if needed
|
|
64
|
+
- Have clear commit messages
|
|
65
|
+
|
|
66
|
+
Thank you for contributing!
|