8000 Merge pull request #73 from sleongkoan/introduce-flexible-record-form… · fluent/fluent-logger-python@8f71787 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f71787

Browse files
authored
Merge pull request #73 from sleongkoan/introduce-flexible-record-formatter
Introduce flexible record formatter
2 parents 456581f + 268c6a7 commit 8f71787

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

fluent/handler.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ class FluentRecordFormatter(logging.Formatter, object):
2323
Best used with server storing data in an ElasticSearch cluster for example.
2424
2525
:param fmt: a dict with format string as values to map to provided keys.
26+
:param datefmt: strftime()-compatible date/time format string.
27+
:param style: (NOT USED)
28+
:param fill_missing_fmt_key: if True, do not raise a KeyError if the format
29+
key is not found. Put None if not found.s
2630
"""
27-
def __init__(self, fmt=None, datefmt=None, style='%'):
31+
def __init__(self, fmt=None, datefmt=None, style='%', fill_missing_fmt_key=False):
2832
super(FluentRecordFormatter, self).__init__(None, datefmt)
2933

3034
if not fmt:
@@ -38,6 +42,8 @@ def __init__(self, fmt=None, datefmt=None, style='%'):
3842

3943
self.hostname = socket.gethostname()
4044

45+
self.fill_missing_fmt_key = fill_missing_fmt_key
46+
4147
def format(self, record):
4248
# Only needed for python2.6
4349
if sys.version_info[0:2] <= (2, 6) and self.usesTime():
@@ -47,9 +53,18 @@ def format(self, record):
4753
super(FluentRecordFormatter, self).format(record)
4854
# Add ours
4955
record.hostname = self.hostname
56+
5057
# Apply format
51-
data = dict([(key, value % record.__dict__)
52-
for key, value in self._fmt_dict.items()])
58+
data = {}
59+
for key, value in self._fmt_dict.items():
60+
try:
61+
value = value % record.__dict__
62+
except KeyError as exc:
63+
value = None
64+
if not self.fill_missing_fmt_key:
65+
raise exc
66+
67+
data[key] = value
5368

5469
self._structuring(data, record)
5570
return data

tests/test_handler.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,48 @@ def test_custom_fmt(self):
6262
self.assertTrue('lineno' in data[0][2])
6363
self.assertTrue('emitted_at' in data[0][2])
6464

65+
def test_custom_field_raise_exception(self):
66+
handler = fluent.handler.FluentHandler('app.follow', port=self._port)
67+
68+
logging.basicConfig(level=logging.INFO)
69+
log = logging.getLogger('fluent.test')
70+
handler.setFormatter(
71+
fluent.handler.FluentRecordFormatter(fmt={
72+
'name': '%(name)s',
73+
'custom_field': '%(custom_field)s'
74+
})
75+
)
76+
log.addHandler(handler)
77+
with self.assertRaises(KeyError):
78+
log.info({'sample': 'value'})
79+
log.removeHandler(handler)
80+
handler.close()
81+
82+
def test_custom_field_fill_missing_fmt_key_is_true(self):
83+
handler = fluent.handler.FluentHandler('app.follow', port=self._port)
84+
85+
logging.basicConfig(level=logging.INFO)
86+
log = logging.getLogger('fluent.test')
87+
handler.setFormatter(
88+
fluent.handler.FluentRecordFormatter(fmt={
89+
'name': '%(name)s',
90+
'custom_field': '%(custom_field)s'
91+
},
92+
fill_missing_fmt_key=True
93+
)
94+
)
95+
log.addHandler(handler)
96+
log.info({'sample': 'value'})
97+
log.removeHandler(handler)
98+
handler.close()
99+
100+
data = self.get_data()
101+
self.assertTrue('name' in data[0][2])
102+
self.assertEqual('fluent.test', data[0][2]['name'])
103+
self.assertTrue('custom_field' in data[0][2])
104+
# field defaults to none if not in log record
105+
self.assertIsNone(data[0][2]['custom_field'])
106+
65107
def test_json_encoded_message(self):
66108
handler = fluent.handler.FluentHandler('app.follow', port=self._port)
67109

0 commit comments

Comments
 (0)
0