Skip to content
This repository was archived by the owner on Apr 3, 2023. It is now read-only.

Commit fb66d40

Browse files
oschulzSamgkreuzer
authored andcommitted
static and dynamic extra fields can get extra prefix. All standard fields are defined at one place.
1 parent 4bfab25 commit fb66d40

File tree

2 files changed

+25
-50
lines changed

2 files changed

+25
-50
lines changed

logstash_async/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Constants:
2626
# maximum number of events to be updated within one SQLite statement
2727
FORMATTER_RECORD_FIELD_SKIP_LIST = [
2828
'args', 'asctime', 'created', 'exc_info', 'exc_text', 'filename', 'funcName',
29-
'id', 'levelname', 'levelno', 'lineno', 'module',
29+
'id', 'levelname', 'levelno', 'lineno', 'message','module',
3030
'msecs', 'msg', 'pathname', 'process',
3131
'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName']
3232
# fields to be set on the top-level of a Logstash event/message, do not modify this

logstash_async/formatter.py

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
from logstash_async.constants import constants
1515

16-
1716
try:
1817
import json
1918
except ImportError:
@@ -83,27 +82,29 @@ def format(self, record):
8382
'process_id': record.process,
8483
'program': self._program_name,
8584
'type': self._message_type,
85+
'func_name': record.funcName,
86+
'line': record.lineno,
87+
'logger_name': record.name,
88+
'thread_name': record.threadName,
8689
}
8790
if self._metadata:
8891
message['@metadata'] = self._metadata
8992
if self._tags:
9093
message['tags'] = self._tags
9194

95+
if record.exc_info:
96+
message.update({'stack_trace', self._format_exception(record.exc_info)})
97+
9298
# record fields
93-
record_fields = self._get_record_fields(record)
94-
message.update(record_fields)
95-
# prepare dynamic extra fields
96-
extra_fields = self._get_extra_fields(record)
99+
dynamic_extra_fields = self._get_record_fields(record)
100+
message.update(dynamic_extra_fields)
101+
# prepare static extra fields
102+
self._format_extra_fields()
103+
message.update(self._extra)
97104
# remove all fields to be excluded
98-
self._remove_excluded_fields(message, extra_fields)
99-
# wrap extra fields in configurable namespace
100-
if self._extra_prefix:
101-
message[self._extra_prefix] = extra_fields
102-
else:
103-
message.update(extra_fields)
104105

105106
# move existing extra record fields into the configured prefix
106-
self._move_extra_record_fields_to_prefix(message)
107+
# self._move_extra_record_fields_to_prefix(message)
107108

108109
return self._serialize(message)
109110

@@ -114,6 +115,7 @@ def _format_timestamp(self, time_):
114115

115116
# ----------------------------------------------------------------------
116117
def _get_record_fields(self, record):
118+
117119
def value_repr(value):
118120
easy_types = (type(None), bool, str, int, float)
119121

@@ -133,25 +135,21 @@ def value_repr(value):
133135
fields = {}
134136

135137
for key, value in record.__dict__.items():
136-
fields[key] = value_repr(value)
138+
if key not in constants.FORMATTER_RECORD_FIELD_SKIP_LIST:
139+
if self._extra_prefix and key not in constants.FORMATTER_LOGSTASH_MESSAGE_FIELD_LIST:
140+
key = self._extra_prefix + "." + key
141+
fields[key] = value_repr(value)
137142
return fields
138143

139144
# ----------------------------------------------------------------------
140-
def _get_extra_fields(self, record):
141-
extra_fields = {
142-
'func_name': record.funcName,
143-
'line': record.lineno,
144-
'logger_name': record.name,
145-
'process_name': record.processName,
146-
'thread_name': record.threadName,
147-
}
145+
def _format_extra_fields(self):
148146
# static extra fields
149147
if self._extra:
150-
extra_fields.update(self._extra)
151-
# exceptions
152-
if record.exc_info:
153-
extra_fields['stack_trace'] = self._format_exception(record.exc_info)
154-
return extra_fields
148+
if self._extra_prefix:
149+
extra_fields_with_prefix = {}
150+
for key in self._extra:
151+
extra_fields_with_prefix[self._extra_prefix + "." + key] = self._extra[key]
152+
self._extra = extra_fields_with_prefix
155153

156154
# ----------------------------------------------------------------------
157155
def _format_exception(self, exc_info):
@@ -163,29 +161,6 @@ def _format_exception(self, exc_info):
163161
stack_trace = ''
164162
return stack_trace
165163

166-
# ----------------------------------------------------------------------
167-
def _remove_excluded_fields(self, message, extra_fields):
168-
for fields in (message, extra_fields):
169-
for field_name in list(fields):
170-
if field_name in constants.FORMATTER_RECORD_FIELD_SKIP_LIST:
171-
del fields[field_name]
172-
173-
# ----------------------------------------------------------------------
174-
def _move_extra_record_fields_to_prefix(self, message):
175-
"""
176-
Anythng added by the "extra" keyword in the logging call will be moved into the
177-
configured "extra" prefix. This way the event in Logstash will be clean and any extras
178-
will be paired together in the configured extra prefix.
179-
If not extra prefix is configured, the message will be kept as is.
180-
"""
181-
if not self._extra_prefix:
182-
return # early out if no prefix is configured
183-
184-
field_skip_list = constants.FORMATTER_LOGSTASH_MESSAGE_FIELD_LIST + [self._extra_prefix]
185-
for key in list(message):
186-
if key not in field_skip_list:
187-
message[self._extra_prefix][key] = message.pop(key)
188-
189164
# ----------------------------------------------------------------------
190165
def _serialize(self, message):
191166
return json.dumps(message, ensure_ascii=self._ensure_ascii)

0 commit comments

Comments
 (0)