1+ from __future__ import annotations # backward compatibility
2+
13import logging
2- from decimal import Decimal
34from datetime import datetime , timezone
4-
5+ from decimal import Decimal
56import json
6-
7- BUILTIN_ATTRS = {
8- 'args' ,
9- 'asctime' ,
10- 'created' ,
11- 'exc_info' ,
12- 'exc_text' ,
13- 'filename' ,
14- 'funcName' ,
15- 'levelname' ,
16- 'levelno' ,
17- 'lineno' ,
18- 'module' ,
19- 'msecs' ,
20- 'message' ,
21- 'msg' ,
22- 'name' ,
23- 'pathname' ,
24- 'process' ,
25- 'processName' ,
26- 'relativeCreated' ,
27- 'stack_info' ,
28- 'taskName' ,
29- 'thread' ,
30- 'threadName' ,
7+ from types import ModuleType
8+ from typing import Any , Optional , Dict
9+
10+
11+ BUILTIN_ATTRS : set [str ] = {
12+ "args" ,
13+ "asctime" ,
14+ "created" ,
15+ "exc_info" ,
16+ "exc_text" ,
17+ "filename" ,
18+ "funcName" ,
19+ "levelname" ,
20+ "levelno" ,
21+ "lineno" ,
22+ "module" ,
23+ "msecs" ,
24+ "message" ,
25+ "msg" ,
26+ "name" ,
27+ "pathname" ,
28+ "process" ,
29+ "processName" ,
30+ "relativeCreated" ,
31+ "stack_info" ,
32+ "taskName" ,
33+ "thread" ,
34+ "threadName" ,
3135}
3236
3337
@@ -58,21 +62,21 @@ class JSONFormatter(logging.Formatter):
5862
5963 """
6064
61- json_lib = json
65+ json_lib : ModuleType = json
6266
63- def format (self , record ) :
64- message = record .getMessage ()
65- extra = self .extra_from_record (record )
66- json_record = self .json_record (message , extra , record )
67- mutated_record = self .mutate_json_record (json_record )
67+ def format (self , record : logging . LogRecord ) -> Any | str :
68+ message : str = record .getMessage ()
69+ extra : dict [ str , Any ] = self .extra_from_record (record )
70+ json_record : dict [ str , Any ] = self .json_record (message , extra , record )
71+ mutated_record : Optional [ dict [ str , Any ]] = self .mutate_json_record (json_record )
6872 # Backwards compatibility: Functions that overwrite this but don't
6973 # return a new value will return None because they modified the
7074 # argument passed in.
7175 if mutated_record is None :
7276 mutated_record = json_record
7377 return self .to_json (mutated_record )
7478
75- def to_json (self , record ) :
79+ def to_json (self , record : dict [ str , Any ]) -> Any | str :
7680 """Converts record dict to a JSON string.
7781
7882 It makes best effort to serialize a record (represents an object as a string)
@@ -93,9 +97,9 @@ def to_json(self, record):
9397 try :
9498 return self .json_lib .dumps (record )
9599 except (TypeError , ValueError , OverflowError ):
96- return '{}'
100+ return "{}"
97101
98- def extra_from_record (self , record ) :
102+ def extra_from_record (self , record : logging . LogRecord ) -> dict [ str , Any ] :
99103 """Returns `extra` dict you passed to logger.
100104
101105 The `extra` keyword argument is used to populate the `__dict__` of
@@ -108,7 +112,9 @@ def extra_from_record(self, record):
108112 if attr_name not in BUILTIN_ATTRS
109113 }
110114
111- def json_record (self , message , extra , record ):
115+ def json_record (
116+ self , message : str , extra : dict [str , Any ], record : logging .LogRecord
117+ ) -> dict [str , Any ]:
112118 """Prepares a JSON payload which will be logged.
113119
114120 Override this method to change JSON log format.
@@ -120,16 +126,18 @@ def json_record(self, message, extra, record):
120126 :return: Dictionary which will be passed to JSON lib.
121127
122128 """
123- extra [' message' ] = message
124- if ' time' not in extra :
125- extra [' time' ] = datetime .now (timezone .utc )
129+ extra [" message" ] = message
130+ if " time" not in extra :
131+ extra [" time" ] = datetime .now (timezone .utc )
126132
127133 if record .exc_info :
128- extra [' exc_info' ] = self .formatException (record .exc_info )
134+ extra [" exc_info" ] = self .formatException (record .exc_info )
129135
130136 return extra
131137
132- def mutate_json_record (self , json_record ):
138+ def mutate_json_record (
139+ self , json_record : dict [str , Any ]
140+ ) -> Optional [Dict [str , Any ]]:
133141 """Override it to convert fields of `json_record` to needed types.
134142
135143 Default implementation converts `datetime` to string in ISO8601 format.
@@ -142,7 +150,7 @@ def mutate_json_record(self, json_record):
142150 return json_record
143151
144152
145- def _json_serializable (obj ) :
153+ def _json_serializable (obj : Any ) -> Any :
146154 try :
147155 return obj .__dict__
148156 except AttributeError :
@@ -189,23 +197,29 @@ class VerboseJSONFormatter(JSONFormatter):
189197 https://docs.python.org/3/library/logging.html#logrecord-attributes.
190198
191199 """
192- def json_record (self , message , extra , record ):
193- extra ['filename' ] = record .filename
194- extra ['funcName' ] = record .funcName
195- extra ['levelname' ] = record .levelname
196- extra ['lineno' ] = record .lineno
197- extra ['module' ] = record .module
198- extra ['name' ] = record .name
199- extra ['pathname' ] = record .pathname
200- extra ['process' ] = record .process
201- extra ['processName' ] = record .processName
202- if hasattr (record , 'stack_info' ):
203- extra ['stack_info' ] = record .stack_info
204- else :
205- extra ['stack_info' ] = None
206- extra ['thread' ] = record .thread
207- extra ['threadName' ] = record .threadName
208- return super (VerboseJSONFormatter , self ).json_record (message , extra , record )
200+
201+ def json_record (
202+ self , message : str , extra : dict [str , Any ], record : logging .LogRecord
203+ ) -> dict [str , Any ]:
204+ extra .update (
205+ {
206+ "filename" : record .filename ,
207+ "funcName" : record .funcName ,
208+ "levelname" : record .levelname ,
209+ "lineno" : record .lineno ,
210+ "module" : record .module ,
211+ "name" : record .name ,
212+ "pathname" : record .pathname ,
213+ "process" : record .process ,
214+ "processName" : record .processName ,
215+ "stack_info" : record .stack_info
216+ if hasattr (record , "stack_info" )
217+ else None ,
218+ "thread" : record .thread ,
219+ "threadName" : record .threadName ,
220+ }
221+ )
222+ return super ().json_record (message , extra , record )
209223
210224
211225class FlatJSONFormatter (JSONFormatter ):
@@ -230,10 +244,12 @@ class FlatJSONFormatter(JSONFormatter):
230244
231245 """
232246
233- keep = (bool , int , float , Decimal , complex , str , datetime )
247+ keep : tuple [ type , ...] = (bool , int , float , Decimal , complex , str , datetime )
234248
235- def json_record (self , message , extra , record ):
236- extra = super (FlatJSONFormatter , self ).json_record (message , extra , record )
249+ def json_record (
250+ self , message : str , extra : dict [str , Any ], record : logging .LogRecord
251+ ) -> dict [str , Any ]:
252+ extra = super ().json_record (message , extra , record )
237253 return {
238254 k : v if v is None or isinstance (v , self .keep ) else str (v )
239255 for k , v in extra .items ()
0 commit comments