unclogger 0.2.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.
- unclogger-0.2.1/.gitignore +202 -0
- unclogger-0.2.1/.readthedocs.yaml +22 -0
- unclogger-0.2.1/CONTRIBUTE.md +54 -0
- unclogger-0.2.1/PKG-INFO +49 -0
- unclogger-0.2.1/README.md +26 -0
- unclogger-0.2.1/docs/assets/plunger-favicon.png +0 -0
- unclogger-0.2.1/docs/assets/plunger-logo.png +0 -0
- unclogger-0.2.1/docs/index.md +175 -0
- unclogger-0.2.1/docs/reference.md +41 -0
- unclogger-0.2.1/justfile +52 -0
- unclogger-0.2.1/mkdocs.yml +50 -0
- unclogger-0.2.1/pyproject.toml +143 -0
- unclogger-0.2.1/release-notes/0.1.0.md +1 -0
- unclogger-0.2.1/release-notes/0.1.1.md +1 -0
- unclogger-0.2.1/release-notes/0.1.2.md +3 -0
- unclogger-0.2.1/release-notes/0.2.0.md +4 -0
- unclogger-0.2.1/release-notes/0.2.1.md +1 -0
- unclogger-0.2.1/tests/__init__.py +0 -0
- unclogger-0.2.1/tests/conftest.py +12 -0
- unclogger-0.2.1/tests/logger/__init__.py +0 -0
- unclogger-0.2.1/tests/logger/clean_data/__init__.py +0 -0
- unclogger-0.2.1/tests/logger/clean_data/conftest.py +57 -0
- unclogger-0.2.1/tests/logger/clean_data/test_clean_fields.py +116 -0
- unclogger-0.2.1/tests/logger/clean_data/test_hash_fields.py +47 -0
- unclogger-0.2.1/tests/logger/test_context.py +86 -0
- unclogger-0.2.1/tests/logger/test_logging.py +129 -0
- unclogger-0.2.1/tests/logger/test_processors.py +50 -0
- unclogger-0.2.1/tests/logger/test_set_level.py +36 -0
- unclogger-0.2.1/tests/test_defaults.py +32 -0
- unclogger-0.2.1/tox.ini +23 -0
- unclogger-0.2.1/unclogger/__init__.py +11 -0
- unclogger-0.2.1/unclogger/defaults.py +39 -0
- unclogger-0.2.1/unclogger/logger.py +107 -0
- unclogger-0.2.1/unclogger/processors.py +28 -0
|
@@ -0,0 +1,202 @@
|
|
|
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_NUMBER/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
pip-wheel-metadata/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*-coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py,cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
test-reports/
|
|
56
|
+
|
|
57
|
+
# Various testing files
|
|
58
|
+
.mutmut-cache
|
|
59
|
+
|
|
60
|
+
# Translations
|
|
61
|
+
*.mo
|
|
62
|
+
*.pot
|
|
63
|
+
|
|
64
|
+
# Django stuff:
|
|
65
|
+
*.log
|
|
66
|
+
local_settings.py
|
|
67
|
+
db.sqlite3
|
|
68
|
+
db.sqlite3-journal
|
|
69
|
+
|
|
70
|
+
# Flask stuff:
|
|
71
|
+
instance/
|
|
72
|
+
.webassets-cache
|
|
73
|
+
|
|
74
|
+
# Scrapy stuff:
|
|
75
|
+
.scrapy
|
|
76
|
+
|
|
77
|
+
# Sphinx documentation
|
|
78
|
+
docs/_build/
|
|
79
|
+
|
|
80
|
+
# PyBuilder
|
|
81
|
+
target/
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
.ipynb
|
|
86
|
+
|
|
87
|
+
# IPython
|
|
88
|
+
profile_default/
|
|
89
|
+
ipython_config.py
|
|
90
|
+
|
|
91
|
+
# pyenv
|
|
92
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
93
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
94
|
+
.python-version
|
|
95
|
+
|
|
96
|
+
# lock files
|
|
97
|
+
# According to pypa/pipenv#598, it is recommended to include the lock file in version control.
|
|
98
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
99
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
100
|
+
# install all needed dependencies.
|
|
101
|
+
#Pipfile.lock
|
|
102
|
+
poetry.lock
|
|
103
|
+
requirements.txt
|
|
104
|
+
requirements.in
|
|
105
|
+
pdm.lock
|
|
106
|
+
uv.lock
|
|
107
|
+
|
|
108
|
+
# other tools
|
|
109
|
+
.pdm-python
|
|
110
|
+
.pdm-build
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.envrc
|
|
125
|
+
.venv
|
|
126
|
+
env/
|
|
127
|
+
venv/
|
|
128
|
+
ENV/
|
|
129
|
+
env.bak/
|
|
130
|
+
venv.bak/
|
|
131
|
+
|
|
132
|
+
# Spyder project settings
|
|
133
|
+
.spyderproject
|
|
134
|
+
.spyproject
|
|
135
|
+
|
|
136
|
+
# Rope project settings
|
|
137
|
+
.ropeproject
|
|
138
|
+
|
|
139
|
+
# mkdocs documentation
|
|
140
|
+
/site
|
|
141
|
+
|
|
142
|
+
# mypy
|
|
143
|
+
.mypy_cache/
|
|
144
|
+
.dmypy.json
|
|
145
|
+
dmypy.json
|
|
146
|
+
|
|
147
|
+
# Pyre type checker
|
|
148
|
+
.pyre/
|
|
149
|
+
|
|
150
|
+
# pytype static type analyzer
|
|
151
|
+
.pytype/
|
|
152
|
+
|
|
153
|
+
# PyCharm stuff
|
|
154
|
+
.idea
|
|
155
|
+
# User-specific stuff
|
|
156
|
+
.idea/**/workspace.xml
|
|
157
|
+
.idea/**/tasks.xml
|
|
158
|
+
.idea/**/usage.statistics.xml
|
|
159
|
+
.idea/**/dictionaries
|
|
160
|
+
.idea/**/shelf
|
|
161
|
+
|
|
162
|
+
# Generated files
|
|
163
|
+
.idea/**/contentModel.xml
|
|
164
|
+
|
|
165
|
+
# Sensitive or high-churn files
|
|
166
|
+
.idea/**/dataSources/
|
|
167
|
+
.idea/**/dataSources.ids
|
|
168
|
+
.idea/**/dataSources.local.xml
|
|
169
|
+
.idea/**/sqlDataSources.xml
|
|
170
|
+
.idea/**/dynamic.xml
|
|
171
|
+
.idea/**/uiDesigner.xml
|
|
172
|
+
.idea/**/dbnavigator.xml
|
|
173
|
+
|
|
174
|
+
# Editor workspace files
|
|
175
|
+
.vscode
|
|
176
|
+
|
|
177
|
+
.testmondata
|
|
178
|
+
|
|
179
|
+
# macOS
|
|
180
|
+
.DS_Store
|
|
181
|
+
|
|
182
|
+
# Docker stuff for local dev
|
|
183
|
+
docker-compose.override.yml
|
|
184
|
+
|
|
185
|
+
.skip-hooks
|
|
186
|
+
|
|
187
|
+
tmp/
|
|
188
|
+
.ruff_cache
|
|
189
|
+
|
|
190
|
+
# run configurations
|
|
191
|
+
.run/
|
|
192
|
+
/.run/
|
|
193
|
+
|
|
194
|
+
# kube manifest
|
|
195
|
+
helm/baked_manifest.yaml
|
|
196
|
+
|
|
197
|
+
# local storage
|
|
198
|
+
_storage
|
|
199
|
+
database.json
|
|
200
|
+
|
|
201
|
+
# localstack cache
|
|
202
|
+
volume/cache
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# .readthedocs.yaml
|
|
2
|
+
# Read the Docs configuration file
|
|
3
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
4
|
+
|
|
5
|
+
# Required
|
|
6
|
+
version: 2
|
|
7
|
+
|
|
8
|
+
# Set the version of Python and other tools you might need
|
|
9
|
+
build:
|
|
10
|
+
os: ubuntu-22.04
|
|
11
|
+
tools:
|
|
12
|
+
python: "3.10"
|
|
13
|
+
|
|
14
|
+
mkdocs:
|
|
15
|
+
configuration: mkdocs.yml
|
|
16
|
+
|
|
17
|
+
python:
|
|
18
|
+
install:
|
|
19
|
+
- method: pip
|
|
20
|
+
path: .
|
|
21
|
+
extra_requirements:
|
|
22
|
+
- docs
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Contributing Guidelines
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
## Development Environment
|
|
5
|
+
|
|
6
|
+
To manage packaging and dependencies, please [install `uv` first](https://docs.astral.sh/uv/getting-started/installation/).
|
|
7
|
+
|
|
8
|
+
Tu run development scripts, please [install `just`](https://just.systems/man/en/). To display the list of all `just` commands (a.k.a. recipes), run `just`:
|
|
9
|
+
|
|
10
|
+
```shell
|
|
11
|
+
$ just
|
|
12
|
+
Available recipes:
|
|
13
|
+
help # List available recipes.
|
|
14
|
+
test # Run unit tests.
|
|
15
|
+
test-cov # Run unit tests with coverage report.
|
|
16
|
+
lint # Run linting and formating checks.
|
|
17
|
+
type # Run static typing analysis.
|
|
18
|
+
analyze # Run security checks.
|
|
19
|
+
check # Run all checks.
|
|
20
|
+
commits # Extract the latest commits
|
|
21
|
+
reformat # Reformat the code using isort and ruff.
|
|
22
|
+
docs # Serve documentation website for development purposes.
|
|
23
|
+
docs-build # Build the documentation website.
|
|
24
|
+
reqs # Extract current production requirements. Save to a file by appending `> requirements.txt`.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Development Checks
|
|
29
|
+
|
|
30
|
+
During development, the command `just check` will execute a number of checks and tests on the library codebase:
|
|
31
|
+
|
|
32
|
+
* correct dependency declarations using `deptry`
|
|
33
|
+
* code linting check using `ruff`
|
|
34
|
+
* code format check using `ruff format`
|
|
35
|
+
* documentation styling check using `pydocstyle`
|
|
36
|
+
|
|
37
|
+
The full unit test suite can be executed with `just test`.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## API Documentation
|
|
41
|
+
|
|
42
|
+
The project documentation can then be served locally by running:
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
$ just docs
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To build the static documentation site, run:
|
|
49
|
+
|
|
50
|
+
```shell
|
|
51
|
+
$ just docs-build
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This will create the HTML documentation in the `site` directory.
|
unclogger-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: unclogger
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Custom wrapper for enhanced structured logging.
|
|
5
|
+
Project-URL: Homepage, https://unclogger.readthedocs.io
|
|
6
|
+
Project-URL: Documentation, https://unclogger.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/berislavlopac/unclogger
|
|
8
|
+
Author-email: Berislav Lopac <berislav@lopac.net>
|
|
9
|
+
License: MIT
|
|
10
|
+
Requires-Python: <4.0,>=3.10
|
|
11
|
+
Requires-Dist: structlog>=24.1
|
|
12
|
+
Provides-Extra: clean
|
|
13
|
+
Requires-Dist: sanitary>=0.1.0; extra == 'clean'
|
|
14
|
+
Provides-Extra: docs
|
|
15
|
+
Requires-Dist: jinja2>=3.1.3; extra == 'docs'
|
|
16
|
+
Requires-Dist: mkapi>=1.0.14; extra == 'docs'
|
|
17
|
+
Requires-Dist: mkdocs-material>=9.5.4; extra == 'docs'
|
|
18
|
+
Requires-Dist: mkdocs>=1.3.0; extra == 'docs'
|
|
19
|
+
Requires-Dist: pymdown-extensions>=10.7; extra == 'docs'
|
|
20
|
+
Provides-Extra: sanitary
|
|
21
|
+
Requires-Dist: sanitary>=0.1.0; extra == 'sanitary'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
Unclogger
|
|
25
|
+
=========
|
|
26
|
+
|
|
27
|
+
Simple Python library for customizable structured logging.
|
|
28
|
+
|
|
29
|
+
[](https://unclogger.readthedocs.io/en/latest/?badge=latest)
|
|
30
|
+
|
|
31
|
+
## Quick Intro
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from unclogger import get_logger
|
|
35
|
+
logger = get_logger("test logger")
|
|
36
|
+
logger.info("test test", foo="abc", bar=123)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Output:
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"foo": "abc",
|
|
43
|
+
"bar": 123,
|
|
44
|
+
"event": "test test",
|
|
45
|
+
"logger": "test logger",
|
|
46
|
+
"level": "info",
|
|
47
|
+
"timestamp": "2021-02-12T22:40:07.600385Z"
|
|
48
|
+
}
|
|
49
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Unclogger
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
Simple Python library for customizable structured logging.
|
|
5
|
+
|
|
6
|
+
[](https://unclogger.readthedocs.io/en/latest/?badge=latest)
|
|
7
|
+
|
|
8
|
+
## Quick Intro
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from unclogger import get_logger
|
|
12
|
+
logger = get_logger("test logger")
|
|
13
|
+
logger.info("test test", foo="abc", bar=123)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Output:
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"foo": "abc",
|
|
20
|
+
"bar": 123,
|
|
21
|
+
"event": "test test",
|
|
22
|
+
"logger": "test logger",
|
|
23
|
+
"level": "info",
|
|
24
|
+
"timestamp": "2021-02-12T22:40:07.600385Z"
|
|
25
|
+
}
|
|
26
|
+
```
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Introduction
|
|
2
|
+
|
|
3
|
+
**Unclogger** is a simple library for customisable structured logging. It mirrors the standard Python logging library API, with a few additional functionalities.
|
|
4
|
+
|
|
5
|
+
!!! Info "Implementation detail"
|
|
6
|
+
|
|
7
|
+
Unclogger is using the [Structlog library](https://www.structlog.org) under the hood.
|
|
8
|
+
|
|
9
|
+
??? Note
|
|
10
|
+
|
|
11
|
+
The JSON messages in examples below were formatted for convenience; in practice they are sent as a single line of text.
|
|
12
|
+
|
|
13
|
+
## Structured Loggers
|
|
14
|
+
|
|
15
|
+
Unclogger creates a logger object which adds one important functionality on top of the [standard logging library](https://docs.python.org/3/library/logging.html): in addition to a textual log message, any additional values passed to logging methods as keyword arguments will be included to the log context, along with a few standard fields:
|
|
16
|
+
|
|
17
|
+
* `event`: The original textual log message.
|
|
18
|
+
* `logger`: Name of the logger instance that created the message.
|
|
19
|
+
* `level`: The [log level](https://docs.python.org/3/library/logging.html#logging-levels) of the message.
|
|
20
|
+
* `timestamp`: Time date of the message in ISO 8601 format.
|
|
21
|
+
|
|
22
|
+
The final logging context will be converted and emitted as a JSON-formatted message.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
!!! Example
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
>>> from unclogger import get_logger
|
|
29
|
+
>>> logger = get_logger("test logger")
|
|
30
|
+
>>> logger.info("test test", foo="abc", bar=123)
|
|
31
|
+
{
|
|
32
|
+
"foo": "abc",
|
|
33
|
+
"bar": 123,
|
|
34
|
+
"event": "test test",
|
|
35
|
+
"logger": "test logger",
|
|
36
|
+
"level": "info",
|
|
37
|
+
"timestamp": "2021-02-12T22:40:07.600385Z"
|
|
38
|
+
}
|
|
39
|
+
>>>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Configuration
|
|
43
|
+
|
|
44
|
+
The logger can be configured using the special attribute `config`. This can be used for configuring additional functionality.
|
|
45
|
+
|
|
46
|
+
!!! Example
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
>>> from unclogger import get_logger
|
|
50
|
+
>>> logger = get_logger("test logger")
|
|
51
|
+
>>> logger.config.foo = "foo"
|
|
52
|
+
>>> logger.config.bar = "bar"
|
|
53
|
+
>>> print(logger.config.foo)
|
|
54
|
+
foo
|
|
55
|
+
>>> print(logger.config.bar)
|
|
56
|
+
foo
|
|
57
|
+
>>> print(logger.config.baz)
|
|
58
|
+
Traceback (most recent call last):
|
|
59
|
+
File "<stdin>", line 1, in <module>
|
|
60
|
+
AttributeError: 'types.SimpleNamespace' object has no attribute 'baz'. Did you mean: 'bar'?
|
|
61
|
+
>>>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
As can be seen in the error message above, `config` is an instance of [SimpleNamespace](https://docs.python.org/3/library/types.html#types.SimpleNamespace).
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### Local Context
|
|
68
|
+
|
|
69
|
+
Each logger has a local context; values can be bound to it so they can appear in any message sent by that logger.
|
|
70
|
+
|
|
71
|
+
!!! Example
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
>>> from unclogger import get_logger
|
|
75
|
+
>>> logger = get_logger("test logger").bind(abc="def")
|
|
76
|
+
>>> logger.info("test test", foo="abc", bar=123)
|
|
77
|
+
{
|
|
78
|
+
"abc": "def",
|
|
79
|
+
"foo": "abc",
|
|
80
|
+
"bar": 123,
|
|
81
|
+
"event": "test test",
|
|
82
|
+
"logger": "test logger",
|
|
83
|
+
"level": "info", "timestamp":
|
|
84
|
+
"2021-02-12T23:04:11.743922Z"
|
|
85
|
+
}
|
|
86
|
+
>>> # let's bind some more
|
|
87
|
+
>>> import uuid
|
|
88
|
+
>>> logger = logger.bind(some_uuid=uuid.uuid4())
|
|
89
|
+
{
|
|
90
|
+
"abc": "def",
|
|
91
|
+
"some_uuid": "88227c28-f5a6-430a-bdee-9e967c6c8d13",
|
|
92
|
+
"foo": "abc",
|
|
93
|
+
"bar": 123,
|
|
94
|
+
"event": "test test",
|
|
95
|
+
"logger": "test logger",
|
|
96
|
+
"level": "info",
|
|
97
|
+
"timestamp": "2021-02-12T23:06:15.917766Z"
|
|
98
|
+
}
|
|
99
|
+
>>> # let's change a bound value
|
|
100
|
+
>>> logger = logger.bind(abc="I have a new value now")
|
|
101
|
+
>>> logger.info("test test", foo="abc", bar=123)
|
|
102
|
+
{
|
|
103
|
+
"abc": "I have a new value now",
|
|
104
|
+
"some_uuid": "88227c28-f5a6-430a-bdee-9e967c6c8d13",
|
|
105
|
+
"foo": "abc",
|
|
106
|
+
"bar": 123,
|
|
107
|
+
"event": "test test",
|
|
108
|
+
"logger": "test logger",
|
|
109
|
+
"level": "info",
|
|
110
|
+
"timestamp": "2021-02-12T23:08:21.768578Z"
|
|
111
|
+
}
|
|
112
|
+
>>>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## Global Context
|
|
117
|
+
|
|
118
|
+
The [`context_bind`](reference.md#unclogger.context_bind) function will set values in the global context, where they can be used by any logger.
|
|
119
|
+
|
|
120
|
+
!!! Example
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
>>> from unclogger import get_logger, context_bind
|
|
124
|
+
>>> # binding data before even creating a logger
|
|
125
|
+
>>> context_bind(abc="def")
|
|
126
|
+
>>> logger1 = get_logger("test logger 1")
|
|
127
|
+
>>> logger1.info("test test", foo="abc", bar=123)
|
|
128
|
+
{
|
|
129
|
+
"abc": "def",
|
|
130
|
+
"foo": "abc",
|
|
131
|
+
"bar": 123,
|
|
132
|
+
"event": "test test",
|
|
133
|
+
"logger": "test logger 1",
|
|
134
|
+
"level": "info",
|
|
135
|
+
"timestamp": "2021-02-12T22:43:48.062282Z"
|
|
136
|
+
}
|
|
137
|
+
>>> logger2 = get_logger("test logger 2")
|
|
138
|
+
>>> # a different logger can access the same data
|
|
139
|
+
>>> logger2.info("another message")
|
|
140
|
+
{
|
|
141
|
+
"abc": "def",
|
|
142
|
+
"event": "another message",
|
|
143
|
+
"logger": "test logger 2",
|
|
144
|
+
"level": "info", "timestamp":
|
|
145
|
+
"2021-02-12T22:45:05.599852Z"
|
|
146
|
+
}
|
|
147
|
+
>>>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Custom Processors
|
|
151
|
+
|
|
152
|
+
It is possible to add other `structlog` processors into the logger configuration. For example, to hide sensitive information that might be present in the logged data (using the [Sanitary](https://sanitary.readthedocs.io) library as an example):
|
|
153
|
+
|
|
154
|
+
!!! Example
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
>>> from sanitary import StructlogSanitizer
|
|
158
|
+
>>> from unclogger import add_processors, get_logger
|
|
159
|
+
>>>
|
|
160
|
+
>>> add_processors(StructlogSanitizer(keys={"password", "email"}))
|
|
161
|
+
>>>
|
|
162
|
+
>>> logger = get_logger("test logger")
|
|
163
|
+
>>> logger.info("test test", foo="abc", email="test@example.com", password="myPa55w0rd")
|
|
164
|
+
{
|
|
165
|
+
"foo": "abc",
|
|
166
|
+
"email": "********",
|
|
167
|
+
"password": "********",
|
|
168
|
+
"event": "test test",
|
|
169
|
+
"logger": "test logger",
|
|
170
|
+
"level": "info",
|
|
171
|
+
"timestamp": "2021-02-12T22:40:07.600385Z"
|
|
172
|
+
}
|
|
173
|
+
>>>
|
|
174
|
+
```
|
|
175
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## Logger
|
|
4
|
+
|
|
5
|
+
::: unclogger.get_logger
|
|
6
|
+
|
|
7
|
+
::: unclogger.context_bind
|
|
8
|
+
|
|
9
|
+
## Global Log Level Configuration
|
|
10
|
+
|
|
11
|
+
??? Example
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
>>> from unclogger import get_logger, set_level
|
|
15
|
+
>>> logger = get_logger("test logger")
|
|
16
|
+
>>> logger.info("bar")
|
|
17
|
+
{
|
|
18
|
+
"event": "bar",
|
|
19
|
+
"logger": "test logger",
|
|
20
|
+
"level": "info",
|
|
21
|
+
"timestamp": "2021-02-18T21:59:40.102272Z"
|
|
22
|
+
}
|
|
23
|
+
>>> logger.debug("bar")
|
|
24
|
+
>>> set_level("debug")
|
|
25
|
+
>>> logger.debug("bar")
|
|
26
|
+
{
|
|
27
|
+
"event": "bar",
|
|
28
|
+
"logger": "test logger",
|
|
29
|
+
"level": "debug",
|
|
30
|
+
"timestamp": "2021-02-18T22:00:09.147106Z"
|
|
31
|
+
}
|
|
32
|
+
>>> set_level("warning")
|
|
33
|
+
>>> logger.info("bar")
|
|
34
|
+
>>>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
::: unclogger.set_level
|
|
38
|
+
|
|
39
|
+
## Custom Processors
|
|
40
|
+
|
|
41
|
+
::: unclogger.processors.add_processors
|
unclogger-0.2.1/justfile
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# List available recipes.
|
|
2
|
+
help:
|
|
3
|
+
@just --list --unsorted
|
|
4
|
+
|
|
5
|
+
# Run unit tests.
|
|
6
|
+
test:
|
|
7
|
+
uv run --all-extras pytest --spec
|
|
8
|
+
|
|
9
|
+
# Run unit tests with coverage report.
|
|
10
|
+
test-cov:
|
|
11
|
+
uv run --all-extras pytest --cov --spec
|
|
12
|
+
|
|
13
|
+
# Run linting and formating checks.
|
|
14
|
+
lint:
|
|
15
|
+
uv run deptry .
|
|
16
|
+
uv run ruff format --check .
|
|
17
|
+
uv run ruff check .
|
|
18
|
+
uv run pydocstyle unclogger/
|
|
19
|
+
|
|
20
|
+
# Run static typing analysis.
|
|
21
|
+
type:
|
|
22
|
+
uv run mypy --install-types --non-interactive unclogger/
|
|
23
|
+
|
|
24
|
+
# Run security checks.
|
|
25
|
+
analyze:
|
|
26
|
+
uvx vulture --min-confidence 100 unclogger/
|
|
27
|
+
uvx radon mi --show --multi --min B unclogger/
|
|
28
|
+
|
|
29
|
+
# Run all checks.
|
|
30
|
+
check: lint type analyze
|
|
31
|
+
|
|
32
|
+
# Extract the latest commits
|
|
33
|
+
commits:
|
|
34
|
+
git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-decorate
|
|
35
|
+
|
|
36
|
+
# Reformat the code using isort and ruff.
|
|
37
|
+
[confirm]
|
|
38
|
+
reformat:
|
|
39
|
+
uv run ruff format .
|
|
40
|
+
uv run ruff check --select I --fix .
|
|
41
|
+
|
|
42
|
+
# Serve documentation website for development purposes.
|
|
43
|
+
docs:
|
|
44
|
+
uv run --extra docs mkdocs serve
|
|
45
|
+
|
|
46
|
+
# Build the documentation website.
|
|
47
|
+
docs-build:
|
|
48
|
+
uv run --extra docs mkdocs build
|
|
49
|
+
|
|
50
|
+
# Extract current production requirements. Save to a file by appending `> requirements.txt`.
|
|
51
|
+
reqs:
|
|
52
|
+
uv export --no-default-groups
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
site_name: Unclogger
|
|
2
|
+
repo_url: https://github.com/berislavlopac/unclogger
|
|
3
|
+
site_description: Simple library for customisable structured logging.
|
|
4
|
+
site_author: Berislav Lopac <berislav@lopac.net>
|
|
5
|
+
use_directory_urls: false
|
|
6
|
+
theme:
|
|
7
|
+
name: material
|
|
8
|
+
logo: assets/plunger-logo.png
|
|
9
|
+
favicon: assets/plunger-favicon.png
|
|
10
|
+
features:
|
|
11
|
+
- search.suggest
|
|
12
|
+
palette:
|
|
13
|
+
# Palette toggle for automatic mode
|
|
14
|
+
- media: "(prefers-color-scheme)"
|
|
15
|
+
toggle:
|
|
16
|
+
icon: material/brightness-auto
|
|
17
|
+
name: Switch to light mode
|
|
18
|
+
|
|
19
|
+
# Palette toggle for light mode
|
|
20
|
+
- media: "(prefers-color-scheme: light)"
|
|
21
|
+
scheme: default
|
|
22
|
+
toggle:
|
|
23
|
+
icon: material/brightness-7
|
|
24
|
+
name: Switch to dark mode
|
|
25
|
+
|
|
26
|
+
# Palette toggle for dark mode
|
|
27
|
+
- media: "(prefers-color-scheme: dark)"
|
|
28
|
+
scheme: slate
|
|
29
|
+
toggle:
|
|
30
|
+
icon: material/brightness-4
|
|
31
|
+
name: Switch to system preference
|
|
32
|
+
plugins:
|
|
33
|
+
- search
|
|
34
|
+
- mkapi
|
|
35
|
+
markdown_extensions:
|
|
36
|
+
- abbr
|
|
37
|
+
- attr_list
|
|
38
|
+
- pymdownx.details
|
|
39
|
+
- pymdownx.highlight:
|
|
40
|
+
anchor_linenums: true
|
|
41
|
+
- pymdownx.inlinehilite
|
|
42
|
+
- pymdownx.snippets
|
|
43
|
+
- pymdownx.superfences
|
|
44
|
+
- toc:
|
|
45
|
+
permalink: yes
|
|
46
|
+
- codehilite:
|
|
47
|
+
guess_lang: no
|
|
48
|
+
nav:
|
|
49
|
+
- index.md
|
|
50
|
+
- reference.md
|