File tree 3 files changed +48
-2
lines changed
3 files changed +48
-2
lines changed Original file line number Diff line number Diff line change @@ -208,6 +208,25 @@ logging.basicConfig(handlers=[handler])
208
208
logging.error({" example" : True }) # at=ERROR example=yes
209
209
```
210
210
211
+ ### Default Key/Value Pairs
212
+
213
+ Instead of providing key/value pairs at each log call, you can override
214
+ the log record factory to provide defaults:
215
+
216
+ ``` py
217
+ _record_factory = logging.getLogRecordFactory()
218
+
219
+ def record_factory (* args , ** kwargs ):
220
+ record = _record_factory(* args, ** kwargs)
221
+ record.trace_id = 123
222
+ return record
223
+
224
+ logging.setLogRecordFactory(record_factory)
225
+ ```
226
+
227
+ This will cause all logs to have the ` trace_id=123 ` pair regardless of including
228
+ ` trace_id ` in keys or manually adding ` trace_id ` to the ` extra ` parameter or the ` msg ` object.
229
+
211
230
## Development
212
231
213
232
### Required Software
Original file line number Diff line number Diff line change @@ -161,8 +161,9 @@ def format(self, record: logging.LogRecord) -> str:
161
161
self .normalize_key (key ): value for key , value in record .msg .items ()
162
162
}
163
163
else :
164
- extra = self .get_extra (record )
165
- params = {"msg" : record .getMessage (), ** extra }
164
+ params = {"msg" : record .getMessage ()}
165
+
166
+ params .update (self .get_extra (record ))
166
167
167
168
tokens = []
168
169
@@ -181,6 +182,11 @@ def format(self, record: logging.LogRecord) -> str:
181
182
if key in self .mapping :
182
183
attribute = self .mapping [key ]
183
184
185
+ # If this key is in params, then skip it, because it was manually passed in
186
+ # will be added via the params system.
187
+ if attribute in params :
188
+ continue
189
+
184
190
# If the attribute doesn't exist on the log record, then skip it.
185
191
if not hasattr (record , attribute ):
186
192
continue
Original file line number Diff line number Diff line change @@ -245,3 +245,24 @@ def test_format_datefmt():
245
245
246
246
asctime = re .search (r'asctime="(.*)"' , value ).group (1 )
247
247
datetime .strptime (asctime , " %H " )
248
+
249
+
250
+ @pytest .mark .parametrize (
251
+ "record" ,
252
+ [
253
+ {"msg" : "alpha" , "levelname" : "INFO" },
254
+ {"msg" : {"msg" : "alpha" }, "levelname" : "INFO" },
255
+ ],
256
+ )
257
+ def test_extra_keys (record ):
258
+ """
259
+ When attributes are added directly to the `logging.LogRecord` object, they should
260
+ be included in the output and not be duplicated, regardless of a str or dict based
261
+ msg object.
262
+ """
263
+ record = logging .makeLogRecord (record )
264
+ record .attr = "value"
265
+
266
+ assert (
267
+ Logfmter (keys = ["at" , "attr" ]).format (record ) == "at=INFO msg=alpha attr=value"
268
+ )
You can’t perform that action at this time.
0 commit comments