Skip to content

Commit 06e64e9

Browse files
authored
Merge pull request #203 from FragileTech/extra
Add support for `extra` in structured mode
2 parents f00c40c + a16d014 commit 06e64e9

5 files changed

Lines changed: 21 additions & 16 deletions

File tree

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ The logging setup supports two main modes:
2727
To initialize logging in your application, call the `setup()` function. You can specify whether to enable structured logging or use the default human-readable format.
2828

2929
```python
30-
from my_logging_module import setup
30+
from flogging import flogging
3131

3232
# Initialize logging
33-
setup(level="INFO", structured=False) # Human-readable format
33+
flogging.setup(level="INFO", structured=False) # Human-readable format
3434

3535
# Enable structured logging for production
36-
setup(level="INFO", structured=True)
36+
flogging.setup(level="INFO", structured=True)
3737
```
3838

3939
#### Parameters for `setup()`
@@ -99,10 +99,10 @@ Example structured log output:
9999
In structured logging mode, you can attach additional context to each log message by calling `set_context()`. This context is logged alongside the usual fields, allowing you to track custom metadata.
100100

101101
```python
102-
from my_logging_module import set_context
102+
from flogging import flogging
103103

104104
# Set custom context
105-
set_context({"user_id": "12345", "transaction_id": "abcde"})
105+
flogging.set_context({"user_id": "12345", "transaction_id": "abcde"})
106106

107107
# The custom context will now appear in each structured log message
108108
```
@@ -112,10 +112,11 @@ set_context({"user_id": "12345", "transaction_id": "abcde"})
112112
When logging large messages (e.g., serialized data or files), the `log_multipart()` function compresses and splits the message into smaller chunks to prevent issues with log size limits.
113113

114114
```python
115-
from my_logging_module import log_multipart
115+
import logging
116+
from flogging import flogging
116117

117118
# Log a large message
118-
log_multipart(logging.getLogger(), b"Large data to be logged")
119+
flogging.log_multipart(logging.getLogger(), b"Large data to be logged")
119120
```
120121

121122
This function will automatically split the message and log each chunk, ensuring the entire message is captured.
@@ -140,9 +141,9 @@ You can further customize the format by modifying the `AwesomeFormatter` class,
140141
To enforce standards in your logging messages, such as preventing trailing dots in log messages, the module provides the `check_trailing_dot()` decorator. This can be applied to logging functions to raise an error if a message ends with a dot:
141142

142143
```python
143-
from my_logging_module import check_trailing_dot
144+
from flogging import flogging
144145

145-
@check_trailing_dot
146+
@flogging.check_trailing_dot
146147
def log_message(record):
147148
# Your custom logging logic
148149
pass
@@ -166,7 +167,7 @@ Here's a full example of how to use structured logging with command-line configu
166167
```python
167168
import argparse
168169
import logging
169-
from flogging import add_logging_args, set_context, setup
170+
from flogging.flogging import add_logging_args, set_context, setup
170171

171172
# Initialize logging
172173
setup(level="INFO", structured=False) # Human-readable format

flogging/flogging.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ class StructuredHandler(logging.Handler):
189189

190190
"""logging handler for structured logging."""
191191

192+
default_fields = set(logging.LogRecord("", logging.NOTSET, "", 1, "msg", (), None).__dict__)
193+
192194
def __init__(
193195
self, level=logging.NOTSET, level_from_msg: Callable[[str], str | None] | None = None
194196
):
@@ -219,6 +221,7 @@ def emit(self, record: logging.LogRecord): # noqa: PLR0912
219221
"thread": reduce_thread_id(record.thread),
220222
"name": record.name,
221223
}
224+
obj.update((k, getattr(record, k)) for k in record.__dict__.keys() - self.default_fields)
222225
try:
223226
rank = os.environ["RANK"]
224227
except KeyError:

flogging/tests/test_main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import pytest
22

33

4-
def test_main():
4+
@pytest.mark.parametrize("structured", [True, False])
5+
def test_main(structured):
56
from flogging.flogging import setup as setup_logging
67

7-
setup_logging(level="info", structured=False)
8+
setup_logging(level="info", structured=structured)

flogging/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""Current version of the project. Do not modify manually."""
2-
__version__ = "0.0.25"
2+
__version__ = "1.0.0"

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
version=version.__version__,
2222
license="MIT",
2323
author="fragiletech",
24-
author_email="",
24+
author_email="gmarkhor@gmail.com",
2525
url="",
26-
keywords=["Machine learning", "artificial intelligence"],
26+
keywords=["logging"],
2727
tests_require=["pytest>=5.3.5", "hypothesis>=5.6.0"],
2828
extras_require={},
2929
install_requires=["xxhash"],
3030
package_data={"": ["README.md"]},
3131
classifiers=[
32-
"Development Status :: 3 - Alpha",
32+
"Development Status :: 5 - Production/Stable",
3333
"Intended Audience :: Developers",
3434
"License :: OSI Approved :: MIT License",
3535
"Programming Language :: Python :: 3.10",

0 commit comments

Comments
 (0)