@@ -148,12 +148,71 @@ def _logRecordFactory(name, level, msg, args):
148
148
return LogRecord (name , level , _level_for (level ), msg , time .monotonic (), args )
149
149
150
150
151
+ class Formatter :
152
+ """
153
+ Responsible for converting a LogRecord to an output string to be
154
+ interpreted by a human or external system.
155
+
156
+ Only implements a sub-set of CPython logging.Formatter behavior,
157
+ but retains all the same arguments in order to match the API.
158
+
159
+ The only init arguments currently supported are: fmt and defaults.
160
+ All others are currently ignored
161
+
162
+ The only style value currently supported is '{'. CPython has support
163
+ for some others, but this implementation does not. Additionally, the
164
+ default value for style in this implementation is '{' whereas the default
165
+ style value in CPython is '%'
166
+ """
167
+
168
+ def __init__ ( # pylint: disable=too-many-arguments
169
+ self , fmt = None , datefmt = None , style = "{" , validate = True , defaults = None
170
+ ):
171
+ self .fmt = fmt
172
+ self .datefmt = datefmt
173
+ self .style = style
174
+ if self .style != "{" :
175
+ raise ValueError ("Only '{' formatting sytle is supported at this time." )
176
+
177
+ self .validate = validate
178
+ self .defaults = defaults
179
+
180
+ def format (self , record : LogRecord ) -> str :
181
+ """
182
+ Format the given LogRecord into an output string
183
+ """
184
+ if self .fmt is None :
185
+ return record .msg
186
+
187
+ vals = {
188
+ "name" : record .name ,
189
+ "levelno" : record .levelno ,
190
+ "levelname" : record .levelname ,
191
+ "message" : record .msg ,
192
+ "created" : record .created ,
193
+ "args" : record .args ,
194
+ }
195
+ if "{asctime}" in self .fmt :
196
+ now = time .localtime ()
197
+ vals ["asctime" ] = (
198
+ f"{ now .tm_year } -{ now .tm_mon :02d} -{ now .tm_mday :02d} "
199
+ f"{ now .tm_hour :02d} :{ now .tm_min :02d} :{ now .tm_sec :02d} "
200
+ )
201
+
202
+ if self .defaults :
203
+ for key , val in self .defaults .items ():
204
+ vals [key ] = val
205
+
206
+ return self .fmt .format (** vals )
207
+
208
+
151
209
class Handler :
152
210
"""Base logging message handler."""
153
211
154
212
def __init__ (self , level : int = NOTSET ) -> None :
155
213
"""Create Handler instance"""
156
214
self .level = level
215
+ self .formatter = None
157
216
158
217
def setLevel (self , level : int ) -> None :
159
218
"""
@@ -167,7 +226,8 @@ def format(self, record: LogRecord) -> str:
167
226
168
227
:param record: The record (message object) to be logged
169
228
"""
170
-
229
+ if self .formatter :
230
+ return self .formatter .format (record )
171
231
return f"{ record .created :<0.3f} : { record .levelname } - { record .msg } "
172
232
173
233
def emit (self , record : LogRecord ) -> None :
@@ -182,6 +242,12 @@ def emit(self, record: LogRecord) -> None:
182
242
def flush (self ) -> None :
183
243
"""Placeholder for flush function in subclasses."""
184
244
245
+ def setFormatter (self , formatter : Formatter ) -> None :
246
+ """
247
+ Set the Formatter to be used by this Handler.
248
+ """
249
+ self .formatter = formatter
250
+
185
251
186
252
# pylint: disable=too-few-public-methods
187
253
class StreamHandler (Handler ):
0 commit comments