Skip to content

Commit e3875fc

Browse files
authored
Don't de-dot ecs.version (#118)
* ecs: stop de-dotting ecs.version * Bump supported version up to 3.12
1 parent e6993eb commit e3875fc

File tree

10 files changed

+38
-20
lines changed

10 files changed

+38
-20
lines changed

.github/workflows/periodic.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
timeout-minutes: 10
1616
strategy:
1717
matrix:
18-
python: [ '3.7', '3.8', '3.9', '3.10' ]
18+
python: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ]
1919
fail-fast: false
2020
steps:
2121
- uses: actions/checkout@v4

.github/workflows/test-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
timeout-minutes: 5
2020
strategy:
2121
matrix:
22-
python: [ '3.7', '3.8', '3.9', '3.10' ]
22+
python: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ]
2323
fail-fast: false
2424
steps:
2525
- run: 'echo "No build required"'

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
timeout-minutes: 10
4242
strategy:
4343
matrix:
44-
python: [ '3.7', '3.8', '3.9', '3.10' ]
44+
python: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12' ]
4545
fail-fast: false
4646
steps:
4747
- uses: actions/checkout@v4

ecs_logging/_stdlib.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,12 @@ def format_to_ecs(self, record):
209209
continue
210210
value = extractors[field](record)
211211
if value is not None:
212-
merge_dicts(de_dot(field, value), result)
212+
# special case ecs.version that should not be de-dotted
213+
if field == "ecs.version":
214+
field_dict = {field: value}
215+
else:
216+
field_dict = de_dot(field, value)
217+
merge_dicts(field_dict, result)
213218

214219
available = record.__dict__
215220

ecs_logging/_structlog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def format_to_ecs(self, event_dict):
5555
else:
5656
event_dict["error"] = {"stack_trace": stack_trace}
5757

58-
event_dict.setdefault("ecs", {}).setdefault("version", ECS_VERSION)
58+
event_dict.setdefault("ecs.version", ECS_VERSION)
5959
return event_dict
6060

6161
def _json_dumps(self, value):

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def tests_impl(session):
3636
)
3737

3838

39-
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"])
39+
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"])
4040
def test(session):
4141
tests_impl(session)
4242

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ classifiers = [
1818
"Programming Language :: Python :: 3.8",
1919
"Programming Language :: Python :: 3.9",
2020
"Programming Language :: Python :: 3.10",
21+
"Programming Language :: Python :: 3.11",
22+
"Programming Language :: Python :: 3.12",
2123
"Topic :: System :: Logging",
2224
"License :: OSI Approved :: Apache Software License"
2325
]

tests/test_apm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def test_elasticapm_structlog_log_correlation_ecs_fields(spec_validator, apm):
4949
ecs = json.loads(spec_validator(stream.getvalue().rstrip()))
5050
ecs.pop("@timestamp")
5151
assert ecs == {
52-
"ecs": {"version": "1.6.0"},
52+
"ecs.version": "1.6.0",
5353
"log.level": "info",
5454
"message": "test message",
5555
"span": {"id": span_id},
@@ -84,7 +84,7 @@ def test_elastic_apm_stdlib_no_filter_log_correlation_ecs_fields(apm):
8484

8585
ecs = json.loads(stream.getvalue().rstrip())
8686
assert ecs == {
87-
"ecs": {"version": "1.6.0"},
87+
"ecs.version": "1.6.0",
8888
"log.level": "info",
8989
"log": {
9090
"logger": "apm-logger",
@@ -128,7 +128,7 @@ def test_elastic_apm_stdlib_with_filter_log_correlation_ecs_fields(apm):
128128

129129
ecs = json.loads(stream.getvalue().rstrip())
130130
assert ecs == {
131-
"ecs": {"version": "1.6.0"},
131+
"ecs.version": "1.6.0",
132132
"log.level": "info",
133133
"log": {
134134
"logger": "apm-logger",
@@ -175,7 +175,7 @@ def test_elastic_apm_stdlib_exclude_fields(apm):
175175

176176
ecs = json.loads(stream.getvalue().rstrip())
177177
assert ecs == {
178-
"ecs": {"version": "1.6.0"},
178+
"ecs.version": "1.6.0",
179179
"log.level": "info",
180180
"log": {
181181
"logger": "apm-logger",

tests/test_stdlib_formatter.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def test_record_formatted(spec_validator):
5151
formatter = ecs_logging.StdlibFormatter(exclude_fields=["process"])
5252

5353
assert spec_validator(formatter.format(make_record())) == (
54-
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs":{"version":"1.6.0"},'
54+
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs.version":"1.6.0",'
5555
'"log":{"logger":"logger-name","origin":{"file":{"line":10,"name":"file.py"},"function":"test_function"},'
5656
'"original":"1: hello"}}'
5757
)
@@ -63,7 +63,7 @@ def test_extra_global_is_merged(spec_validator):
6363
)
6464

6565
assert spec_validator(formatter.format(make_record())) == (
66-
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs":{"version":"1.6.0"},'
66+
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs.version":"1.6.0",'
6767
'"environment":"dev",'
6868
'"log":{"logger":"logger-name","origin":{"file":{"line":10,"name":"file.py"},"function":"test_function"},'
6969
'"original":"1: hello"}}'
@@ -80,7 +80,7 @@ def format_to_ecs(self, record):
8080
formatter = CustomFormatter(exclude_fields=["process"])
8181
assert spec_validator(formatter.format(make_record())) == (
8282
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello",'
83-
'"custom":"field","ecs":{"version":"1.6.0"},"log":{"logger":"logger-name","origin":'
83+
'"custom":"field","ecs.version":"1.6.0","log":{"logger":"logger-name","origin":'
8484
'{"file":{"line":10,"name":"file.py"},"function":"test_function"},"original":"1: hello"}}'
8585
)
8686

@@ -94,7 +94,7 @@ def test_can_be_set_on_handler():
9494

9595
assert stream.getvalue() == (
9696
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello",'
97-
'"ecs":{"version":"1.6.0"},"log":{"logger":"logger-name","origin":{"file":{"line":10,'
97+
'"ecs.version":"1.6.0","log":{"logger":"logger-name","origin":{"file":{"line":10,'
9898
'"name":"file.py"},"function":"test_function"},"original":"1: hello"}}\n'
9999
)
100100

@@ -127,7 +127,7 @@ def test_extra_is_merged(time, logger):
127127
assert isinstance(ecs["log"]["origin"]["file"].pop("line"), int)
128128
assert ecs == {
129129
"@timestamp": "2020-03-20T16:16:37.187Z",
130-
"ecs": {"version": "1.6.0"},
130+
"ecs.version": "1.6.0",
131131
"log.level": "info",
132132
"log": {
133133
"logger": logger.name,
@@ -254,8 +254,6 @@ def test_stack_trace_limit_types_and_values():
254254
"exclude_fields",
255255
[
256256
"process",
257-
"ecs",
258-
"ecs.version",
259257
"log",
260258
"log.level",
261259
"message",
@@ -279,6 +277,19 @@ def test_exclude_fields(exclude_fields):
279277
assert field_path[-1] not in obj
280278

281279

280+
@pytest.mark.parametrize(
281+
"exclude_fields",
282+
[
283+
"ecs.version",
284+
],
285+
)
286+
def test_exclude_fields_not_dedotted(exclude_fields):
287+
formatter = ecs_logging.StdlibFormatter(exclude_fields=[exclude_fields])
288+
ecs = formatter.format_to_ecs(make_record())
289+
for entry in exclude_fields:
290+
assert entry not in ecs
291+
292+
282293
def test_exclude_fields_empty_json_object():
283294
"""Assert that if all JSON objects attributes are excluded then the object doesn't appear."""
284295
formatter = ecs_logging.StdlibFormatter(
@@ -350,7 +361,7 @@ def test_apm_data_conflicts(spec_validator):
350361
formatter = ecs_logging.StdlibFormatter(exclude_fields=["process"])
351362

352363
assert spec_validator(formatter.format(record)) == (
353-
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs":{"version":"1.6.0"},'
364+
'{"@timestamp":"2020-03-20T14:12:46.123Z","log.level":"debug","message":"1: hello","ecs.version":"1.6.0",'
354365
'"log":{"logger":"logger-name","origin":{"file":{"line":10,"name":"file.py"},"function":"test_function"},'
355366
'"original":"1: hello"},"service":{"environment":"dev","name":"myapp","version":"1.0.0"}}'
356367
)

tests/test_structlog_formatter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def test_event_dict_formatted(time, spec_validator, event_dict):
6666
'{"@timestamp":"2020-03-20T16:16:37.187Z","log.level":"debug",'
6767
'"message":"test message",'
6868
'"baz":"<NotSerializable>",'
69-
'"ecs":{"version":"1.6.0"},'
69+
'"ecs.version":"1.6.0",'
7070
'"foo":"bar",'
7171
'"log":{"logger":"logger-name"}}'
7272
)
@@ -90,7 +90,7 @@ def test_can_be_set_as_processor(time, spec_validator):
9090
assert spec_validator(stream.getvalue()) == (
9191
'{"@timestamp":"2020-03-20T16:16:37.187Z","log.level":"debug",'
9292
'"message":"test message","custom":"key","dot":{"ted":1},'
93-
'"ecs":{"version":"1.6.0"}}\n'
93+
'"ecs.version":"1.6.0"}\n'
9494
)
9595

9696

0 commit comments

Comments
 (0)