Skip to content

Commit f7dc544

Browse files
committed
adding Formatter and example including timestamp
1 parent cbfea81 commit f7dc544

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

adafruit_logging.py

+67-1
Original file line numberDiff line numberDiff line change
@@ -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+
151209
class 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
187253
class StreamHandler(Handler):

examples/logging_formatter_example.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# SPDX-FileCopyrightText: 2024 Tim Cocks
2+
# SPDX-License-Identifier: MIT
3+
4+
5+
"""Briefly exercise the logger and null logger."""
6+
7+
import adafruit_logging as logging
8+
# To test on CPython, un-comment below and comment out above
9+
# import logging
10+
11+
12+
logger = logging.getLogger("example")
13+
logger.setLevel(logging.INFO)
14+
print_handler = logging.StreamHandler()
15+
logger.addHandler(print_handler)
16+
17+
default_formatter = logging.Formatter()
18+
print_handler.setFormatter(default_formatter)
19+
logger.info("Default formatter example")
20+
21+
22+
timestamp_formatter = logging.Formatter(
23+
fmt="{asctime} {levelname}: {message}", style="{"
24+
)
25+
print_handler.setFormatter(timestamp_formatter)
26+
logger.info("Timestamp formatter example")
27+
28+
29+
custom_vals_formatter = logging.Formatter(
30+
fmt="{ip} {levelname}: {message}", style="{", defaults={"ip": "192.168.1.188"}
31+
)
32+
print_handler.setFormatter(custom_vals_formatter)
33+
logger.info("Custom formatter example")

0 commit comments

Comments
 (0)