@@ -148,12 +148,71 @@ def _logRecordFactory(name, level, msg, args):
148148 return LogRecord (name , level , _level_for (level ), msg , time .monotonic (), args )
149149
150150
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+
151209class Handler :
152210 """Base logging message handler."""
153211
154212 def __init__ (self , level : int = NOTSET ) -> None :
155213 """Create Handler instance"""
156214 self .level = level
215+ self .formatter = None
157216
158217 def setLevel (self , level : int ) -> None :
159218 """
@@ -167,7 +226,8 @@ def format(self, record: LogRecord) -> str:
167226
168227 :param record: The record (message object) to be logged
169228 """
170-
229+ if self .formatter :
230+ return self .formatter .format (record )
171231 return f"{ record .created :<0.3f} : { record .levelname } - { record .msg } "
172232
173233 def emit (self , record : LogRecord ) -> None :
@@ -182,6 +242,12 @@ def emit(self, record: LogRecord) -> None:
182242 def flush (self ) -> None :
183243 """Placeholder for flush function in subclasses."""
184244
245+ def setFormatter (self , formatter : Formatter ) -> None :
246+ """
247+ Set the Formatter to be used by this Handler.
248+ """
249+ self .formatter = formatter
250+
185251
186252# pylint: disable=too-few-public-methods
187253class StreamHandler (Handler ):
0 commit comments