Skip to content

Commit dd61628

Browse files
authored
Merge pull request #1 from Colin-b/feature/handle_extra_parameter
Handle extra parameter
2 parents f6bb688 + d810f5e commit dd61628

9 files changed

Lines changed: 93 additions & 11 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/.idea/
2+
/logging_json.egg-info/

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 20.8b1
3+
rev: 21.9b0
44
hooks:
5-
- id: black
5+
- id: black

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ python:
33
- "3.6"
44
- "3.7"
55
- "3.8"
6-
- "3.9-dev"
6+
- "3.9"
7+
- "3.10-dev"
78
install:
89
- pip install .[testing]
910
script:
@@ -13,4 +14,4 @@ deploy:
1314
username: __token__
1415
edge: true
1516
distributions: "sdist bdist_wheel"
16-
skip_existing: true
17+
skip_existing: true

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.1.0] - 2021-10-04
10+
### Fixed
11+
- Handle `extra` logging parameter.
12+
913
## [0.0.1] - 2020-10-15
1014
### Added
1115
- Public release.
1216

13-
[Unreleased]: https://github.com/Colin-b/healthpy/compare/v0.0.1...HEAD
17+
[Unreleased]: https://github.com/Colin-b/healthpy/compare/v0.1.0...HEAD
18+
[0.1.0]: https://github.com/Colin-b/healthpy/compare/v0.0.1...v0.1.0
1419
[0.0.1]: https://github.com/Colin-b/healthpy/releases/tag/v0.0.1

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Colin Bounouar
3+
Copyright (c) 2021 Colin Bounouar
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<a href="https://travis-ci.com/Colin-b/logging_json"><img alt="Build status" src="https://api.travis-ci.com/Colin-b/logging_json.svg?branch=master"></a>
66
<a href="https://travis-ci.com/Colin-b/logging_json"><img alt="Coverage" src="https://img.shields.io/badge/coverage-100%25-brightgreen"></a>
77
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
8-
<a href="https://travis-ci.com/Colin-b/logging_json"><img alt="Number of tests" src="https://img.shields.io/badge/tests-11 passed-blue"></a>
8+
<a href="https://travis-ci.com/Colin-b/logging_json"><img alt="Number of tests" src="https://img.shields.io/badge/tests-15 passed-blue"></a>
99
<a href="https://pypi.org/project/logging_json/"><img alt="Number of downloads" src="https://img.shields.io/pypi/dm/logging_json"></a>
1010
</p>
1111

@@ -55,7 +55,7 @@ The resulting JSON dictionary will be the one you provided (with the [additional
5555
### Logging with anything else (such as a string)
5656

5757
Anything not logged using a dictionary will be handled by the standard formatter and it can result in one of the 2 output:
58-
* A JSON dictionary, if [additional fields](#adding-additional-fields-and-values) are set, with the message available in the `msg` key of the resulting JSON dictionary.
58+
* A JSON dictionary, if [additional fields](#adding-additional-fields-and-values) are set or if `extra` parameter is used while logging, with the message available in the `msg` key of the resulting JSON dictionary.
5959
* The formatted record, if no [additional fields](#adding-additional-fields-and-values) are set.
6060

6161
This handles the usual string logging as in the following:

logging_json/_formatter.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,39 @@
11
import collections
22
import json
33
import logging
4-
from typing import Any
4+
from typing import Any, Dict
5+
6+
standard_attributes = (
7+
"name",
8+
"msg",
9+
"args",
10+
"levelname",
11+
"levelno",
12+
"pathname",
13+
"filename",
14+
"module",
15+
"exc_info",
16+
"exc_text",
17+
"stack_info",
18+
"lineno",
19+
"funcName",
20+
"created",
21+
"msecs",
22+
"relativeCreated",
23+
"thread",
24+
"threadName",
25+
"processName",
26+
"process",
27+
"message",
28+
"asctime",
29+
)
30+
31+
32+
def _extra_attributes(record: logging.LogRecord) -> Dict[str, Any]:
33+
return {
34+
name: record.__dict__[name]
35+
for name in set(record.__dict__).difference(standard_attributes)
36+
}
537

638

739
def _value(record: logging.LogRecord, field_name_or_value: Any) -> Any:
@@ -17,7 +49,7 @@ def _value(record: logging.LogRecord, field_name_or_value: Any) -> Any:
1749

1850

1951
class JSONFormatter(logging.Formatter):
20-
def __init__(self, *args, fields=None, **kwargs):
52+
def __init__(self, *args, fields: Dict[str, Any] = None, **kwargs):
2153
# Allow to provide any formatter setting (useful to provide a custom date format)
2254
super().__init__(*args, **kwargs)
2355
self.fields = fields or {}
@@ -36,6 +68,8 @@ def format(self, record: logging.LogRecord):
3668
else:
3769
message["msg"] = super().formatMessage(record)
3870

71+
message.update(_extra_attributes(record))
72+
3973
if record.exc_info:
4074
message["exception"] = {
4175
"type": record.exc_info[0].__name__,

logging_json/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
# Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0)
44
# Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0)
55
# Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9)
6-
__version__ = "0.0.1"
6+
__version__ = "0.1.0"

tests/test_formatter.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ def test_str_with_args_message(caplog):
3333
assert fmt(caplog) == "message 1"
3434

3535

36+
def test_str_with_extra_message(caplog):
37+
caplog.set_level("INFO")
38+
logging.info("message 1", extra={"key1": "value 1"})
39+
assert dict_fmt(caplog) == {"msg": "message 1", "key1": "value 1"}
40+
41+
42+
def test_str_with_args_and_extra_message(caplog):
43+
caplog.set_level("INFO")
44+
logging.info("message %s", "1", extra={"key1": "value 1"})
45+
assert dict_fmt(caplog) == {"msg": "message 1", "key1": "value 1"}
46+
47+
3648
def test_dict_message_with_asctime(caplog, monkeypatch):
3749
monkeypatch.setattr(time, "time", lambda: 1599736353.0076675)
3850
caplog.set_level("INFO")
@@ -60,6 +72,15 @@ def test_str_with_args_message_with_asctime(caplog, monkeypatch):
6072
assert actual == {"msg": "message 1"}
6173

6274

75+
def test_str_with_args_and_extra_message_with_asctime(caplog, monkeypatch):
76+
monkeypatch.setattr(time, "time", lambda: 1599736353.0076675)
77+
caplog.set_level("INFO")
78+
logging.info("message %s", "1", extra={"key1": "value 1"})
79+
actual = dict_fmt(caplog, fields={"date_time": "asctime"})
80+
assert time.strptime(actual.pop("date_time"), "%Y-%m-%d %H:%M:%S,007")
81+
assert actual == {"msg": "message 1", "key1": "value 1"}
82+
83+
6384
def test_dict_message_at_exception_level(caplog):
6485
caplog.set_level("INFO")
6586
try:
@@ -159,6 +180,26 @@ def test_documented_record_attributes(caplog, monkeypatch):
159180
}
160181

161182

183+
def test_with_extra_in_fields_and_message(caplog):
184+
caplog.set_level("INFO")
185+
logging.info("message 1", extra={"key1": "value 1"})
186+
assert (
187+
dict_fmt(
188+
caplog,
189+
fields={
190+
"extra": "key1",
191+
"key2": "value 2",
192+
},
193+
)
194+
== {
195+
"extra": "value 1",
196+
"key1": "value 1",
197+
"key2": "value 2",
198+
"msg": "message 1",
199+
}
200+
)
201+
202+
162203
def fmt(caplog, *formatter_args, **formatter_kwargs) -> str:
163204
return logging_json.JSONFormatter(*formatter_args, **formatter_kwargs).format(
164205
caplog.records[0]

0 commit comments

Comments
 (0)