@@ -22,7 +22,10 @@ class FluentRecordFormatter(logging.Formatter, object):
22
22
23
23
Best used with server storing data in an ElasticSearch cluster for example.
24
24
25
- :param fmt: a dict with format string as values to map to provided keys.
25
+ :param fmt: a dict or a callable with format string as values to map to provided keys.
26
+ If callable, should accept a single argument `LogRecord` and return a dict,
27
+ and have a field `usesTime` that is callable and return a bool as would
28
+ `FluentRecordFormatter.usesTime`
26
29
:param datefmt: strftime()-compatible date/time format string.
27
30
:param style: '%', '{' or '$' (used only with Python 3.2 or above)
28
31
:param fill_missing_fmt_key: if True, do not raise a KeyError if the format
@@ -32,7 +35,7 @@ class FluentRecordFormatter(logging.Formatter, object):
32
35
:param exclude_attrs: switches this formatter into a mode where all attributes
33
36
except the ones specified by `exclude_attrs` are logged with the record as is.
34
37
If `None`, operates as before, otherwise `fmt` is ignored.
35
- Can be a `list`, `tuple` or a `set` .
38
+ Can be an iterable .
36
39
"""
37
40
38
41
def __init__ (self , fmt = None , datefmt = None , style = '%' , fill_missing_fmt_key = False , format_json = True ,
@@ -63,12 +66,22 @@ def __init__(self, fmt=None, datefmt=None, style='%', fill_missing_fmt_key=False
63
66
if exclude_attrs is not None :
64
67
self ._exc_attrs = set (exclude_attrs )
65
68
self ._fmt_dict = None
69
+ self ._formatter = self ._format_by_exclusion
70
+ self .usesTime = super (FluentRecordFormatter , self ).usesTime
66
71
else :
67
72
self ._exc_attrs = None
68
73
if not fmt :
69
74
self ._fmt_dict = basic_fmt_dict
75
+ self ._formatter = self ._format_by_dict
76
+ self .usesTime = self ._format_by_dict_uses_time
70
77
else :
71
- self ._fmt_dict = fmt
78
+ if hasattr (fmt , "__call__" ):
79
+ self ._formatter = fmt
80
+ self .usesTime = fmt .usesTime
81
+ else :
82
+ self ._fmt_dict = fmt
83
+ self ._formatter = self ._format_by_dict
84
+ self .usesTime = self ._format_by_dict_uses_time
72
85
73
86
if format_json :
74
87
self ._format_msg = self ._format_msg_json
@@ -90,37 +103,13 @@ def format(self, record):
90
103
record .hostname = self .hostname
91
104
92
105
# Apply format
93
- data = {}
94
- if self ._exc_attrs is not None :
95
- for key , value in record .__dict__ .items ():
96
- if key not in self ._exc_attrs :
97
- data [key ] = value
98
- else :
99
- for key , value in self ._fmt_dict .items ():
100
- try :
101
- if self .__style :
102
- value = self .__style (value ).format (record )
103
- else :
104
- value = value % record .__dict__
105
- except KeyError as exc :
106
- value = None
107
- if not self .fill_missing_fmt_key :
108
- raise exc
109
-
110
- data [key ] = value
106
+ data = self ._formatter (record )
111
107
112
108
self ._structuring (data , record )
113
109
return data
114
110
115
111
def usesTime (self ):
116
- if self ._exc_attrs is not None :
117
- return super (FluentRecordFormatter , self ).usesTime ()
118
- else :
119
- if self .__style :
120
- search = self .__style .asctime_search
121
- else :
122
- search = "%(asctime)"
123
- return any ([value .find (search ) >= 0 for value in self ._fmt_dict .values ()])
112
+ """This method is substituted on construction based on settings for performance reasons"""
124
113
125
114
def _structuring (self , data , record ):
126
115
""" Melds `msg` into `data`.
@@ -153,6 +142,36 @@ def _format_msg_json(self, record, msg):
153
142
def _format_msg_default (self , record , msg ):
154
143
return {'message' : record .getMessage ()}
155
144
145
+ def _format_by_exclusion (self , record ):
146
+ data = {}
147
+ for key , value in record .__dict__ .items ():
148
+ if key not in self ._exc_attrs :
149
+ data [key ] = value
150
+ return data
151
+
152
+ def _format_by_dict (self , record ):
153
+ data = {}
154
+ for key , value in self ._fmt_dict .items ():
155
+ try :
156
+ if self .__style :
157
+ value = self .__style (value ).format (record )
158
+ else :
159
+ value = value % record .__dict__
160
+ except KeyError as exc :
161
+ value = None
162
+ if not self .fill_missing_fmt_key :
163
+ raise exc
164
+
165
+ data [key ] = value
166
+ return data
167
+
168
+ def _format_by_dict_uses_time (self ):
169
+ if self .__style :
170
+ search = self .__style .asctime_search
171
+ else :
172
+ search = "%(asctime)"
173
+ return any ([value .find (search ) >= 0 for value in self ._fmt_dict .values ()])
174
+
156
175
@staticmethod
157
176
def _add_dic (data , dic ):
158
177
for key , value in dic .items ():
0 commit comments