certlib-log 1.0.0b1__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 (37) hide show
  1. certlib_log-1.0.0b1/.gitattributes +1 -0
  2. certlib_log-1.0.0b1/.github/workflows/release.yml +42 -0
  3. certlib_log-1.0.0b1/.github/workflows/test.yml +46 -0
  4. certlib_log-1.0.0b1/.github/workflows/various_checks.yml +64 -0
  5. certlib_log-1.0.0b1/.gitignore +59 -0
  6. certlib_log-1.0.0b1/.pytest.toml +7 -0
  7. certlib_log-1.0.0b1/.readthedocs.yaml +16 -0
  8. certlib_log-1.0.0b1/CHANGELOG.md +18 -0
  9. certlib_log-1.0.0b1/LICENSE.txt +29 -0
  10. certlib_log-1.0.0b1/MANIFEST.in +3 -0
  11. certlib_log-1.0.0b1/PKG-INFO +223 -0
  12. certlib_log-1.0.0b1/README.md +140 -0
  13. certlib_log-1.0.0b1/dev/dev-requirements.in +9 -0
  14. certlib_log-1.0.0b1/dev/dev-requirements.txt +246 -0
  15. certlib_log-1.0.0b1/dev-install.bash +82 -0
  16. certlib_log-1.0.0b1/dev-regen-with-upgrade.bash +3 -0
  17. certlib_log-1.0.0b1/dev-regen.bash +65 -0
  18. certlib_log-1.0.0b1/docs/doc-requirements.in +4 -0
  19. certlib_log-1.0.0b1/docs/doc-requirements.txt +623 -0
  20. certlib_log-1.0.0b1/docs/doc-src/changelog.md +18 -0
  21. certlib_log-1.0.0b1/docs/doc-src/guide.md +8 -0
  22. certlib_log-1.0.0b1/docs/doc-src/index.md +140 -0
  23. certlib_log-1.0.0b1/docs/doc-src/reference.md +121 -0
  24. certlib_log-1.0.0b1/docs/doc-src/stylesheets/extra.css +19 -0
  25. certlib_log-1.0.0b1/docs/mkdocs.yml +74 -0
  26. certlib_log-1.0.0b1/pyproject.toml +76 -0
  27. certlib_log-1.0.0b1/setup.cfg +4 -0
  28. certlib_log-1.0.0b1/src/certlib/log.py +3676 -0
  29. certlib_log-1.0.0b1/src/certlib/py.typed +0 -0
  30. certlib_log-1.0.0b1/src/certlib_log.egg-info/PKG-INFO +223 -0
  31. certlib_log-1.0.0b1/src/certlib_log.egg-info/SOURCES.txt +35 -0
  32. certlib_log-1.0.0b1/src/certlib_log.egg-info/dependency_links.txt +1 -0
  33. certlib_log-1.0.0b1/src/certlib_log.egg-info/requires.txt +55 -0
  34. certlib_log-1.0.0b1/src/certlib_log.egg-info/top_level.txt +1 -0
  35. certlib_log-1.0.0b1/tests/test-requirements.in +1 -0
  36. certlib_log-1.0.0b1/tests/test-requirements.txt +83 -0
  37. certlib_log-1.0.0b1/tests/test_certlib_log.py +5758 -0
@@ -0,0 +1 @@
1
+ .git_archival.txt export-subst
@@ -0,0 +1,42 @@
1
+ name: "Release new certlib.log version"
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ call-test-workflow:
9
+ uses: ./.github/workflows/test.yml
10
+
11
+ call-various-checks-workflow:
12
+ uses: ./.github/workflows/various_checks.yml
13
+
14
+ build-and-publish:
15
+ needs:
16
+ - call-test-workflow
17
+ - call-various-checks-workflow
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v6
24
+ with:
25
+ python-version: '3.x'
26
+
27
+ - name: Install build dependencies
28
+ run: |
29
+ python3 -m pip install --upgrade pip
30
+ python3 -m pip install --upgrade build
31
+
32
+ - name: Build
33
+ run: |
34
+ python3 -m build
35
+
36
+ - name: Publish to PyPi
37
+ uses: pypa/gh-action-pypi-publish@v1.14.0
38
+ with:
39
+ user: __token__
40
+ password: ${{ secrets.pypi_password }}
41
+ print-hash: true
42
+ verbose: true
@@ -0,0 +1,46 @@
1
+ # This workflow is based on the "Python package" one. It will install test dependencies and run tests.
2
+ # See also: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python.
3
+
4
+ name: "Run certlib.log's tests"
5
+
6
+ on:
7
+ push:
8
+ branches: [ "main" ]
9
+ pull_request:
10
+ branches: [ "main" ]
11
+ workflow_call:
12
+ workflow_dispatch:
13
+
14
+ jobs:
15
+ prepare-and-test:
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version:
21
+ - "3.10"
22
+ - "3.11"
23
+ - "3.12"
24
+ - "3.13"
25
+ - "3.14"
26
+ - "3.15-dev"
27
+ - "pypy3.10"
28
+ - "pypy3.11"
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+
32
+ - name: Set up Python ${{ matrix.python-version }}
33
+ uses: actions/setup-python@v6
34
+ with:
35
+ python-version: ${{ matrix.python-version }}
36
+ cache: 'pip'
37
+ cache-dependency-path: tests/test-requirements.txt
38
+
39
+ - name: Install test dependencies
40
+ run: |
41
+ python3 -m pip install --upgrade pip
42
+ python3 -m pip install --use-pep517 -r tests/test-requirements.txt
43
+
44
+ - name: Test with pytest
45
+ run: |
46
+ pytest
@@ -0,0 +1,64 @@
1
+ name: "Various checks related to certlib.log"
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+ workflow_call:
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ type-checks:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version:
18
+ - "3.10"
19
+ - "3.15-dev"
20
+
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v6
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+ cache: 'pip'
29
+ cache-dependency-path: dev/dev-requirements.txt
30
+
31
+ - name: Install "for development", with "dev" dependencies
32
+ run: |
33
+ ./dev-install.bash
34
+
35
+ - name: Type check the library with mypy
36
+ run: |
37
+ ./dev/venv/bin/python3 -m mypy -p certlib.log
38
+
39
+ - name: Type check the tests with mypy
40
+ run: |
41
+ ./dev/venv/bin/python3 -m mypy ./tests/test_certlib_log.py
42
+
43
+ docs-building-check:
44
+ runs-on: ubuntu-latest
45
+
46
+ steps:
47
+ - uses: actions/checkout@v6
48
+
49
+ - name: Set up Python
50
+ uses: actions/setup-python@v6
51
+ with:
52
+ # (3.12 is currently used in `.readthedocs.yaml`)
53
+ python-version: '3.12'
54
+ cache: 'pip'
55
+ cache-dependency-path: docs/doc-requirements.txt
56
+
57
+ - name: Install doc dependencies
58
+ run: |
59
+ python3 -m pip install --upgrade pip
60
+ python3 -m pip install --use-pep517 -r docs/doc-requirements.txt
61
+
62
+ - name: Build docs
63
+ run: |
64
+ mkdocs build --config-file docs/mkdocs.yml --strict
@@ -0,0 +1,59 @@
1
+ __pycache__/
2
+ *.py[codz]
3
+ *$py.class
4
+ *~
5
+
6
+ /docs/site/
7
+
8
+ .env
9
+ .envrc
10
+ .venv
11
+ .venv-temporary-*
12
+ ENV/
13
+ env.bak/
14
+ env/
15
+ venv.bak/
16
+ venv/
17
+
18
+ *.cover
19
+ *.egg-info/
20
+ *.py.cover
21
+ .Python
22
+ .cache
23
+ .coverage
24
+ .coverage.*
25
+ .dir-locals.el
26
+ .dmypy.json
27
+ .emacs.desktop
28
+ .emacs.desktop.lock
29
+ .hypothesis/
30
+ .idea/
31
+ .ipynb_checkpoints
32
+ .mypy_cache/
33
+ .nox/
34
+ .pypirc
35
+ .pyre/
36
+ .pytest_cache/
37
+ .python-version
38
+ .pytype/
39
+ .ropeproject
40
+ .ruff_cache/
41
+ .spyderproject
42
+ .spyproject
43
+ .tox/
44
+ .vscode/
45
+ MANIFEST
46
+ __pypackages__/
47
+ build/
48
+ cover/
49
+ coverage.xml
50
+ dist/
51
+ dmypy.json
52
+ htmlcov/
53
+ ipython_config.py
54
+ nosetests.xml
55
+ pip-delete-this-directory.txt
56
+ pip-log.txt
57
+ profile_default/
58
+ sdist/
59
+ wheels/
@@ -0,0 +1,7 @@
1
+ [pytest]
2
+ minversion = "9.0"
3
+ addopts = ["-ra", "--doctest-modules"]
4
+ testpaths = [
5
+ "src/certlib",
6
+ "tests",
7
+ ]
@@ -0,0 +1,16 @@
1
+ # https://docs.readthedocs.io/en/stable/config-file/v2.html
2
+
3
+ version: 2
4
+
5
+ build:
6
+ os: ubuntu-24.04
7
+ tools:
8
+ python: "3.12"
9
+
10
+ mkdocs:
11
+ configuration: docs/mkdocs.yml
12
+ fail_on_warning: true
13
+
14
+ python:
15
+ install:
16
+ - requirements: docs/doc-requirements.txt
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. The
4
+ format is based (to a large extent) on [Keep a Changelog](https://keepachangelog.com/).
5
+
6
+ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ The entire *public API* is documented in the [API Reference](https://certlib-log.readthedocs.io/en/latest/reference/)
8
+ (with the proviso that *neither* any exception messages *nor* any source
9
+ code available there via the `<> Source code...` elements are part of the
10
+ *public API*).
11
+
12
+
13
+ ## [Unreleased] (2026-XX-XX)
14
+
15
+ - TBD...
16
+
17
+
18
+ [Unreleased]: https://github.com/CERT-Polska/certlib-log/compare/initial-commit...main
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, CERT Polska.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,3 @@
1
+ # Exclude `.git_archival.txt` from sdist builds to avoid setuptools-scm warnings
2
+ # (see: https://setuptools-scm.readthedocs.io/en/latest/usage/#git-archives).
3
+ exclude .git_archival.txt
@@ -0,0 +1,223 @@
1
+ Metadata-Version: 2.4
2
+ Name: certlib-log
3
+ Version: 1.0.0b1
4
+ Summary: A library extending the standard logging toolbox (e.g., facilitating structured logging with minimal fuss).
5
+ Maintainer-email: Jan Kaliszewski <jan.kaliszewski@cert.pl>
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/CERT-Polska/certlib-log
8
+ Project-URL: Documentation, https://certlib-log.readthedocs.io/
9
+ Project-URL: Repository, https://github.com/CERT-Polska/certlib-log.git
10
+ Project-URL: Issues, https://github.com/CERT-Polska/certlib-log/issues
11
+ Project-URL: Changelog, https://github.com/CERT-Polska/certlib-log/blob/main/CHANGELOG.md
12
+ Keywords: logging,structured logging,formatting,library
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Programming Language :: Python :: 3.15
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Logging
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE.txt
28
+ Provides-Extra: dev
29
+ Requires-Dist: ast-serialize==0.3.0; extra == "dev"
30
+ Requires-Dist: babel==2.18.0; extra == "dev"
31
+ Requires-Dist: backrefs==7.0; extra == "dev"
32
+ Requires-Dist: black==26.3.1; extra == "dev"
33
+ Requires-Dist: build==1.5.0; extra == "dev"
34
+ Requires-Dist: certifi==2026.4.22; extra == "dev"
35
+ Requires-Dist: charset-normalizer==3.4.7; extra == "dev"
36
+ Requires-Dist: click==8.3.3; extra == "dev"
37
+ Requires-Dist: colorama==0.4.6; extra == "dev"
38
+ Requires-Dist: exceptiongroup==1.3.1; extra == "dev"
39
+ Requires-Dist: ghp-import==2.1.0; extra == "dev"
40
+ Requires-Dist: griffelib==2.0.2; extra == "dev"
41
+ Requires-Dist: idna==3.13; extra == "dev"
42
+ Requires-Dist: iniconfig==2.3.0; extra == "dev"
43
+ Requires-Dist: jinja2==3.1.6; extra == "dev"
44
+ Requires-Dist: librt==0.10.0; extra == "dev"
45
+ Requires-Dist: markdown==3.10.2; extra == "dev"
46
+ Requires-Dist: markupsafe==3.0.3; extra == "dev"
47
+ Requires-Dist: mergedeep==1.3.4; extra == "dev"
48
+ Requires-Dist: mkdocs==1.6.1; extra == "dev"
49
+ Requires-Dist: mkdocs-autorefs==1.4.4; extra == "dev"
50
+ Requires-Dist: mkdocs-get-deps==0.2.2; extra == "dev"
51
+ Requires-Dist: mkdocs-material==9.7.6; extra == "dev"
52
+ Requires-Dist: mkdocs-material-extensions==1.3.1; extra == "dev"
53
+ Requires-Dist: mkdocstrings==1.0.4; extra == "dev"
54
+ Requires-Dist: mkdocstrings-python==2.0.3; extra == "dev"
55
+ Requires-Dist: mypy==2.0.0; extra == "dev"
56
+ Requires-Dist: mypy-extensions==1.1.0; extra == "dev"
57
+ Requires-Dist: packaging==26.2; extra == "dev"
58
+ Requires-Dist: paginate==0.5.7; extra == "dev"
59
+ Requires-Dist: pathspec==1.1.1; extra == "dev"
60
+ Requires-Dist: pip-tools==7.5.3; extra == "dev"
61
+ Requires-Dist: platformdirs==4.9.6; extra == "dev"
62
+ Requires-Dist: pluggy==1.6.0; extra == "dev"
63
+ Requires-Dist: pygments==2.20.0; extra == "dev"
64
+ Requires-Dist: pymdown-extensions==10.21.2; extra == "dev"
65
+ Requires-Dist: pyproject-hooks==1.2.0; extra == "dev"
66
+ Requires-Dist: pytest==9.0.3; extra == "dev"
67
+ Requires-Dist: python-dateutil==2.9.0.post0; extra == "dev"
68
+ Requires-Dist: pytokens==0.4.1; extra == "dev"
69
+ Requires-Dist: pyyaml==6.0.3; extra == "dev"
70
+ Requires-Dist: pyyaml-env-tag==1.1; extra == "dev"
71
+ Requires-Dist: requests==2.33.1; extra == "dev"
72
+ Requires-Dist: setuptools-scm==10.0.5; extra == "dev"
73
+ Requires-Dist: six==1.17.0; extra == "dev"
74
+ Requires-Dist: tomli==2.4.1; extra == "dev"
75
+ Requires-Dist: typing-extensions==4.15.0; extra == "dev"
76
+ Requires-Dist: urllib3==2.7.0; extra == "dev"
77
+ Requires-Dist: vcs-versioning==1.1.1; extra == "dev"
78
+ Requires-Dist: watchdog==6.0.0; extra == "dev"
79
+ Requires-Dist: wheel==0.47.0; extra == "dev"
80
+ Requires-Dist: pip==26.1.1; extra == "dev"
81
+ Requires-Dist: setuptools==82.0.1; extra == "dev"
82
+ Dynamic: license-file
83
+
84
+ # `certlib.log`
85
+
86
+ ...is a library that extends the standard [`logging`](https://docs.python.org/3/library/logging.html)
87
+ toolset. Among other things, it makes it possible to introduce
88
+ *structured logging* with minimal fuss, and/or to start using the
89
+ modern `{}`-based style of log message formatting (gradually if
90
+ required).
91
+
92
+
93
+ ## Basic Info
94
+
95
+ - **Documentation:** [certlib-log.readthedocs.io](https://certlib-log.readthedocs.io)
96
+ - **Home page:** [github.com/CERT-Polska/certlib-log](https://github.com/CERT-Polska/certlib-log)
97
+ - **Contributing:** [github.com/CERT-Polska/certlib-log/pulls](https://github.com/CERT-Polska/certlib-log/pulls)
98
+
99
+ You can install the [`certlib.log`](https://pypi.org/project/certlib-log/)
100
+ library by running (typically, in a [*virtual environment*](https://packaging.python.org/en/latest/tutorials/installing-packages/#creating-virtual-environments))
101
+ the command: **`python3 -m pip install certlib.log`**
102
+
103
+ The library is compatible with Python 3.10 and all newer versions of
104
+ Python. It uses *only* the Python standard library, i.e., it **does
105
+ *not* depend on any third-party packages**.
106
+
107
+
108
+ ## Examples
109
+
110
+ ### Configuring *Structured Logging* and *Auto-Makers*
111
+
112
+ ```python
113
+ import logging.config
114
+
115
+ logging.config.dictConfig({
116
+ "formatters": {
117
+ "structured": {
118
+ "()": "certlib.log.StructuredLogsFormatter",
119
+ "defaults": {
120
+ # Each key in this dict should be an *output data* key.
121
+ # Each value should specify the respective *default value*.
122
+ "system": "MyExample",
123
+ "component": "MyAPI",
124
+ "component_type": "web"
125
+ },
126
+ "auto_makers": {
127
+ # Each key in this dict should be an *output data* key.
128
+ # Each value should specify an *argumentless callable*
129
+ # (for example, the `get()` method of some `ContextVar`).
130
+ "client_ip": "myexample.myapi.client_ip_context_var.get",
131
+ "nano_time": "time.time_ns"
132
+ }
133
+ }
134
+ },
135
+ "handlers": {
136
+ "stderr": {
137
+ "class": "logging.StreamHandler",
138
+ "stream": "ext://sys.stderr",
139
+ "formatter": "structured"
140
+ }
141
+ },
142
+ "root": {
143
+ "level": "INFO",
144
+ "handlers": ["stderr"]
145
+ },
146
+ "disable_existing_loggers": False,
147
+ "version": 1
148
+ })
149
+ ```
150
+
151
+ ### Logging Stuff With *`{}`-Formatted Text Message* or *No Text Message*
152
+
153
+ ```python
154
+ import datetime as dt
155
+ import ipaddress
156
+ import logging
157
+ from certlib.log import xm # Note: `xm` is short for `ExtendedMessage`
158
+
159
+ logger = logging.getLogger(__name__)
160
+
161
+ ...
162
+
163
+ def example_with_text_message_formatting(city, humidity, error_summary=None):
164
+ if error_summary:
165
+ logger.error(xm(
166
+ 'An error occurred: {!r}', error_summary,
167
+ exc_info=True, stack_info=True, stacklevel=2,
168
+ ))
169
+
170
+ logger.warning(xm('Humidity in {} is {:.1%}', city, humidity))
171
+
172
+ logger.info(xm(
173
+ # (Here: making use of `datetime`-specific format codes...)
174
+ 'Today is day #{today:%j} of the year {today:%Y}',
175
+ today=dt.date.today(),
176
+
177
+ # Arbitrary data items can also be given (which is especially
178
+ # useful when `certlib.log.StructuredLogsFormatter` is in use).
179
+ some_extra_item=42,
180
+ other_arbitrary_stuff={'foo': [
181
+ {'my-ip': ipaddress.IPv4Address('192.168.0.1')},
182
+ dt.time(12, 59),
183
+ ]},
184
+ ))
185
+
186
+ def example_with_no_text(temperature, pressure, debug_data_dict, calm=True):
187
+ # (The possibility to focus on pure data, *without* the need
188
+ # to pass any *text-message*-related arguments, is especially
189
+ # handy when `certlib.log.StructuredLogsFormatter` is in use.)
190
+
191
+ if calm:
192
+ logger.info(xm(
193
+ # Just data:
194
+ temperature=temperature,
195
+ pressure=pressure,
196
+ ))
197
+ else:
198
+ logger.error(xm(
199
+ # Just data:
200
+ temperature=temperature,
201
+ pressure=pressure,
202
+
203
+ # Special arguments:
204
+ exc_info=True,
205
+ stack_info=True,
206
+ stacklevel=2,
207
+ ))
208
+
209
+ # Single dict providing data is also OK:
210
+ logger.debug(xm(debug_data_dict))
211
+ ```
212
+
213
+ You can find more examples in the [User's Guide](https://certlib-log.readthedocs.io/en/latest/guide/).
214
+
215
+
216
+ ## Copyright and License
217
+
218
+ Copyright (c) 2026, [CERT Polska](https://cert.pl/en/). All rights reserved.
219
+
220
+ The [`certlib.log`](https://github.com/CERT-Polska/certlib-log) library
221
+ is free software; you can redistribute and/or modify it under the terms
222
+ of the *BSD 3-Clause "New" or "Revised" License* (see the [`LICENSE.txt`](https://github.com/CERT-Polska/certlib-log/blob/main/LICENSE.txt)
223
+ file in the source code repository).
@@ -0,0 +1,140 @@
1
+ # `certlib.log`
2
+
3
+ ...is a library that extends the standard [`logging`](https://docs.python.org/3/library/logging.html)
4
+ toolset. Among other things, it makes it possible to introduce
5
+ *structured logging* with minimal fuss, and/or to start using the
6
+ modern `{}`-based style of log message formatting (gradually if
7
+ required).
8
+
9
+
10
+ ## Basic Info
11
+
12
+ - **Documentation:** [certlib-log.readthedocs.io](https://certlib-log.readthedocs.io)
13
+ - **Home page:** [github.com/CERT-Polska/certlib-log](https://github.com/CERT-Polska/certlib-log)
14
+ - **Contributing:** [github.com/CERT-Polska/certlib-log/pulls](https://github.com/CERT-Polska/certlib-log/pulls)
15
+
16
+ You can install the [`certlib.log`](https://pypi.org/project/certlib-log/)
17
+ library by running (typically, in a [*virtual environment*](https://packaging.python.org/en/latest/tutorials/installing-packages/#creating-virtual-environments))
18
+ the command: **`python3 -m pip install certlib.log`**
19
+
20
+ The library is compatible with Python 3.10 and all newer versions of
21
+ Python. It uses *only* the Python standard library, i.e., it **does
22
+ *not* depend on any third-party packages**.
23
+
24
+
25
+ ## Examples
26
+
27
+ ### Configuring *Structured Logging* and *Auto-Makers*
28
+
29
+ ```python
30
+ import logging.config
31
+
32
+ logging.config.dictConfig({
33
+ "formatters": {
34
+ "structured": {
35
+ "()": "certlib.log.StructuredLogsFormatter",
36
+ "defaults": {
37
+ # Each key in this dict should be an *output data* key.
38
+ # Each value should specify the respective *default value*.
39
+ "system": "MyExample",
40
+ "component": "MyAPI",
41
+ "component_type": "web"
42
+ },
43
+ "auto_makers": {
44
+ # Each key in this dict should be an *output data* key.
45
+ # Each value should specify an *argumentless callable*
46
+ # (for example, the `get()` method of some `ContextVar`).
47
+ "client_ip": "myexample.myapi.client_ip_context_var.get",
48
+ "nano_time": "time.time_ns"
49
+ }
50
+ }
51
+ },
52
+ "handlers": {
53
+ "stderr": {
54
+ "class": "logging.StreamHandler",
55
+ "stream": "ext://sys.stderr",
56
+ "formatter": "structured"
57
+ }
58
+ },
59
+ "root": {
60
+ "level": "INFO",
61
+ "handlers": ["stderr"]
62
+ },
63
+ "disable_existing_loggers": False,
64
+ "version": 1
65
+ })
66
+ ```
67
+
68
+ ### Logging Stuff With *`{}`-Formatted Text Message* or *No Text Message*
69
+
70
+ ```python
71
+ import datetime as dt
72
+ import ipaddress
73
+ import logging
74
+ from certlib.log import xm # Note: `xm` is short for `ExtendedMessage`
75
+
76
+ logger = logging.getLogger(__name__)
77
+
78
+ ...
79
+
80
+ def example_with_text_message_formatting(city, humidity, error_summary=None):
81
+ if error_summary:
82
+ logger.error(xm(
83
+ 'An error occurred: {!r}', error_summary,
84
+ exc_info=True, stack_info=True, stacklevel=2,
85
+ ))
86
+
87
+ logger.warning(xm('Humidity in {} is {:.1%}', city, humidity))
88
+
89
+ logger.info(xm(
90
+ # (Here: making use of `datetime`-specific format codes...)
91
+ 'Today is day #{today:%j} of the year {today:%Y}',
92
+ today=dt.date.today(),
93
+
94
+ # Arbitrary data items can also be given (which is especially
95
+ # useful when `certlib.log.StructuredLogsFormatter` is in use).
96
+ some_extra_item=42,
97
+ other_arbitrary_stuff={'foo': [
98
+ {'my-ip': ipaddress.IPv4Address('192.168.0.1')},
99
+ dt.time(12, 59),
100
+ ]},
101
+ ))
102
+
103
+ def example_with_no_text(temperature, pressure, debug_data_dict, calm=True):
104
+ # (The possibility to focus on pure data, *without* the need
105
+ # to pass any *text-message*-related arguments, is especially
106
+ # handy when `certlib.log.StructuredLogsFormatter` is in use.)
107
+
108
+ if calm:
109
+ logger.info(xm(
110
+ # Just data:
111
+ temperature=temperature,
112
+ pressure=pressure,
113
+ ))
114
+ else:
115
+ logger.error(xm(
116
+ # Just data:
117
+ temperature=temperature,
118
+ pressure=pressure,
119
+
120
+ # Special arguments:
121
+ exc_info=True,
122
+ stack_info=True,
123
+ stacklevel=2,
124
+ ))
125
+
126
+ # Single dict providing data is also OK:
127
+ logger.debug(xm(debug_data_dict))
128
+ ```
129
+
130
+ You can find more examples in the [User's Guide](https://certlib-log.readthedocs.io/en/latest/guide/).
131
+
132
+
133
+ ## Copyright and License
134
+
135
+ Copyright (c) 2026, [CERT Polska](https://cert.pl/en/). All rights reserved.
136
+
137
+ The [`certlib.log`](https://github.com/CERT-Polska/certlib-log) library
138
+ is free software; you can redistribute and/or modify it under the terms
139
+ of the *BSD 3-Clause "New" or "Revised" License* (see the [`LICENSE.txt`](https://github.com/CERT-Polska/certlib-log/blob/main/LICENSE.txt)
140
+ file in the source code repository).
@@ -0,0 +1,9 @@
1
+ -r ../docs/doc-requirements.txt
2
+ -r ../tests/test-requirements.txt
3
+ build
4
+ mypy
5
+ pip
6
+ pip-tools
7
+ setuptools>=80
8
+ setuptools-scm[simple]>=9.2
9
+ wheel