Skip to content

Commit 7a4802c

Browse files
rdifrangobasepi
andauthored
Add Global context fields to StdlibFormatter (#65)
* Resolves #57 See: #57 * Update _stdlib.py Updated the type hints. * Fix lint (mypy and line length) * Update _stdlib.py * Update _stdlib.py Co-authored-by: Difrango, Ronald <ronald.difrango@fmr.com> Co-authored-by: Colton Myers <colton.myers@gmail.com>
1 parent e651685 commit 7a4802c

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

ecs_logging/_stdlib.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,16 @@ class StdlibFormatter(logging.Formatter):
7272
converter = time.gmtime
7373

7474
def __init__(
75-
self,
76-
fmt=None,
77-
datefmt=None,
78-
style="%",
79-
validate=None,
80-
stack_trace_limit=None,
81-
exclude_fields=(),
75+
self, # type: Any
76+
fmt=None, # type: Optional[str]
77+
datefmt=None, # type: Optional[str]
78+
style="%", # type: str
79+
validate=None, # type: Optional[bool]
80+
stack_trace_limit=None, # type: Optional[int]
81+
extra=None, # type: Optional[Dict[str, Any]]
82+
exclude_fields=(), # type: Sequence[str]
8283
):
83-
# type: (Any, Optional[str], Optional[str], str, Optional[bool], Optional[int], Sequence[str]) -> None
84+
# type: (...) -> None
8485
"""Initialize the ECS formatter.
8586
8687
:param int stack_trace_limit:
@@ -89,6 +90,8 @@ def __init__(
8990
Setting this to zero will suppress stack traces.
9091
This setting doesn't affect ``LogRecord.stack_info`` because
9192
this attribute is typically already pre-formatted.
93+
:param Optional[Dict[str, Any]] extra:
94+
Specifies the collection of meta-data fields to add to all records.
9295
:param Sequence[str] exclude_fields:
9396
Specifies any fields that should be suppressed from the resulting
9497
fields, expressed with dot notation::
@@ -129,6 +132,7 @@ def __init__(
129132
):
130133
raise TypeError("'exclude_fields' must be a sequence of strings")
131134

135+
self._extra = extra
132136
self._exclude_fields = frozenset(exclude_fields)
133137
self._stack_trace_limit = stack_trace_limit
134138

@@ -218,6 +222,10 @@ def format_to_ecs(self, record):
218222
# since they can be defined as 'extras={"http": {"method": "GET"}}'
219223
extra_keys = set(available).difference(self._LOGRECORD_DICT)
220224
extras = flatten_dict({key: available[key] for key in extra_keys})
225+
# Merge in any global extra's
226+
if self._extra is not None:
227+
for field, value in self._extra.items():
228+
merge_dicts(de_dot(field, value), extras)
221229

222230
# Pop all Elastic APM extras and add them
223231
# to standard tracing ECS fields.

tests/test_stdlib_formatter.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import ecs_logging
2727
from .compat import StringIO
2828

29-
3029
requires_py3 = pytest.mark.skipif(
3130
sys.version_info[0] < 3, reason="Test requires Python 3.x+"
3231
)
@@ -63,6 +62,19 @@ def test_record_formatted(spec_validator):
6362
)
6463

6564

65+
def test_extra_global_is_merged(spec_validator):
66+
formatter = ecs_logging.StdlibFormatter(
67+
exclude_fields=["process"], extra={"environment": "dev"}
68+
)
69+
70+
assert spec_validator(formatter.format(make_record())) == (
71+
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs":{"version":"1.6.0"},'
72+
'"environment":"dev",'
73+
'"log":{"logger":"logger-name","origin":{"file":{"line":10,"name":"file.py"},"function":"test_function"},'
74+
'"original":"1: hello"}}'
75+
)
76+
77+
6678
def test_can_be_overridden(spec_validator):
6779
class CustomFormatter(ecs_logging.StdlibFormatter):
6880
def format_to_ecs(self, record):

0 commit comments

Comments
 (0)