Skip to content

Commit 7b1161d

Browse files
committed
logging: Add support for custom handlers.
Any custom handlers will be passed a LogRecord instance which has members and a dict with "levelname", "message" and "name", to be used for creating a log message. The handler list is a global singleton so that sub-logging objects all use the same set of (root) handlers. The name of the root handler is also changed from None to "root", to match CPython. Signed-off-by: Damien George <damien@micropython.org>
1 parent dedf328 commit 7b1161d

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

logging/example_logging.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@
1313
1/0
1414
except:
1515
log.exception("Some trouble (%s)", "expected")
16+
17+
class MyHandler(logging.Handler):
18+
def emit(self, record):
19+
print("levelname=%(levelname)s name=%(name)s message=%(message)s" % record.__dict__)
20+
21+
logging.getLogger().addHandler(MyHandler())
22+
logging.info("Test message7")

logging/logging.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,25 @@
1717

1818
_stream = sys.stderr
1919

20+
class LogRecord:
21+
def __init__(self):
22+
self.__dict__ = {}
23+
24+
def __getattr__(self, key):
25+
return self.__dict__[key]
26+
27+
class Handler:
28+
def __init__(self):
29+
pass
30+
31+
def setFormatter(self, fmtr):
32+
pass
33+
2034
class Logger:
2135

2236
level = NOTSET
37+
handlers = []
38+
record = LogRecord()
2339

2440
def __init__(self, name):
2541
self.name = name
@@ -37,12 +53,19 @@ def isEnabledFor(self, level):
3753
return level >= (self.level or _level)
3854

3955
def log(self, level, msg, *args):
40-
if level >= (self.level or _level):
41-
_stream.write("%s:%s:" % (self._level_str(level), self.name))
42-
if not args:
43-
print(msg, file=_stream)
56+
if self.isEnabledFor(level):
57+
level = self._level_str(level)
58+
if args:
59+
msg = msg % args
60+
if self.handlers:
61+
d = self.record.__dict__
62+
d["levelname"] = level
63+
d["message"] = msg
64+
d["name"] = self.name
65+
for h in self.handlers:
66+
h.emit(self.record)
4467
else:
45-
print(msg % args, file=_stream)
68+
print(level, ":", self.name, ":", msg, sep="", file=_stream)
4669

4770
def debug(self, msg, *args):
4871
self.log(DEBUG, msg, *args)
@@ -66,22 +89,24 @@ def exc(self, e, msg, *args):
6689
def exception(self, msg, *args):
6790
self.exc(sys.exc_info()[1], msg, *args)
6891

92+
def addHandler(self, hndlr):
93+
self.handlers.append(hndlr)
6994

7095
_level = INFO
7196
_loggers = {}
7297

73-
def getLogger(name):
98+
def getLogger(name="root"):
7499
if name in _loggers:
75100
return _loggers[name]
76101
l = Logger(name)
77102
_loggers[name] = l
78103
return l
79104

80105
def info(msg, *args):
81-
getLogger(None).info(msg, *args)
106+
getLogger().info(msg, *args)
82107

83108
def debug(msg, *args):
84-
getLogger(None).debug(msg, *args)
109+
getLogger().debug(msg, *args)
85110

86111
def basicConfig(level=INFO, filename=None, stream=None, format=None):
87112
global _level, _stream

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy