Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.

Commit 9e615ce

Browse files
authored
#147: Feature request: Add ECS compatibility (#148)
* #147: Feature request: Add ECS compatibility * removed map and added UT
1 parent b87736a commit 9e615ce

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/pythonjsonlogger/jsonlogger.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,23 @@
2424
'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName')
2525

2626

27-
def merge_record_extra(record: logging.LogRecord, target: Dict, reserved: Union[Dict, List]) -> Dict:
27+
28+
def merge_record_extra(record: logging.LogRecord, target: Dict, reserved: Union[Dict, List], rename_fields: Dict[str,str]) -> Dict:
2829
"""
2930
Merges extra attributes from LogRecord object into target dictionary
3031
3132
:param record: logging.LogRecord
3233
:param target: dict to update
3334
:param reserved: dict or list with reserved keys to skip
35+
:param rename_fields: an optional dict, used to rename field names in the output.
36+
Rename levelname to log.level: {'levelname': 'log.level'}
3437
"""
3538
for key, value in record.__dict__.items():
3639
# this allows to have numeric keys
3740
if (key not in reserved
3841
and not (hasattr(key, "startswith")
3942
and key.startswith('_'))):
40-
target[key] = value
43+
target[rename_fields.get(key,key)] = value
4144
return target
4245

4346

@@ -172,7 +175,7 @@ def add_fields(self, log_record: Dict[str, Any], record: logging.LogRecord, mess
172175

173176
log_record.update(self.static_fields)
174177
log_record.update(message_dict)
175-
merge_record_extra(record, log_record, reserved=self._skip_fields)
178+
merge_record_extra(record, log_record, reserved=self._skip_fields, rename_fields=self.rename_fields)
176179

177180
if self.timestamp:
178181
key = self.timestamp if type(self.timestamp) == str else 'timestamp'

tests/tests.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,28 @@ def encode_complex(z):
276276
msg = self.buffer.getvalue()
277277
self.assertEqual(msg, "{\"message\": \" message\", \"special\": [3.0, 8.0]}\n")
278278

279+
def test_rename_reserved_attrs(self):
280+
log_format = lambda x: ['%({0:s})s'.format(i) for i in x]
281+
reserved_attrs_map = {
282+
'exc_info': 'error.type',
283+
'exc_text': 'error.message',
284+
'funcName': 'log.origin.function',
285+
'levelname': 'log.level',
286+
'module': 'log.origin.file.name',
287+
'processName': 'process.name',
288+
'threadName': 'process.thread.name',
289+
'msg': 'log.message'
290+
}
291+
292+
custom_format = ' '.join(log_format(reserved_attrs_map.keys()))
293+
reserved_attrs = [_ for _ in jsonlogger.RESERVED_ATTRS if _ not in list(reserved_attrs_map.keys())]
294+
formatter = jsonlogger.JsonFormatter(custom_format, reserved_attrs=reserved_attrs, rename_fields=reserved_attrs_map)
295+
self.log_handler.setFormatter(formatter)
296+
self.log.info("message")
297+
298+
msg = self.buffer.getvalue()
299+
self.assertEqual(msg, '{"error.type": null, "error.message": null, "log.origin.function": "test_rename_reserved_attrs", "log.level": "INFO", "log.origin.file.name": "tests", "process.name": "MainProcess", "process.thread.name": "MainThread", "log.message": "message"}\n')
300+
279301

280302
if __name__ == '__main__':
281303
if len(sys.argv[1:]) > 0:

0 commit comments

Comments
 (0)