Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit b021b99

Browse files
author
Jay Logue
committed
A little more work on python logging
-- Changed the initialization code for WeaveStack so that a default log handler is only installed if no other handler is in place at any point in the logger hierarchy. Now, if you initialize the root logger prior to initializing WeaveStack, openweave log output will naturally go to the root handler, whereas if you don’t, output will go to stdout by default.
1 parent a927894 commit b021b99

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

src/device-manager/python/openweave/WeaveStack.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def formatTime(self, record, datefmt=None):
145145

146146
@_singleton
147147
class WeaveStack(object):
148-
def __init__(self):
148+
def __init__(self, installDefaultLogHandler=True):
149149
self.networkLock = Lock()
150150
self.completeEvent = Event()
151151
self._weaveStackLib = None
@@ -157,28 +157,49 @@ def __init__(self):
157157
# Locate and load the openweave shared library.
158158
self._loadLib()
159159

160-
# By default, configure the openweave library to log to a python logger object with the
161-
# name 'openweave.WeaveStack'. If this logger has not already been initialized by
162-
# the application, automatically configure it to log to stdout.
160+
# Arrange to log output from the openweave library to a python logger object with the
161+
# name 'openweave.WeaveStack'. If desired, applications can override this behavior by
162+
# setting self.logger to a different python logger object, or by calling setLogFunct()
163+
# with their own logging function.
164+
self.logger = logging.getLogger(__name__)
165+
self.setLogFunct(self.defaultLogFunct)
166+
167+
# Determine if there are already handlers installed for the logger. Python 3.5+
168+
# has a method for this; on older versions the check has to be done manually.
169+
if hasattr(self.logger, 'hasHandlers'):
170+
hasHandlers = self.logger.hasHandlers()
171+
else:
172+
hasHandlers = False
173+
logger = self.logger
174+
while logger is not None:
175+
if len(logger.handlers) > 0:
176+
hasHandlers = True
177+
break
178+
if not logger.propagate:
179+
break
180+
logger = logger.parent
181+
182+
# If a logging handler has not already been initialized for 'openweave.WeaveStack',
183+
# or any one of its parent loggers, automatically configure a handler to log to
184+
# stdout. This maintains compatibility with a number of applications which expect
185+
# openweave log output to go to stdout by default.
163186
#
164-
# Applications can override this behavior in any one the following ways:
165-
# - Setting self.logger to a different python logger object.
166-
# - Replacing the StreamHandler on self.logger with a different handler object.
167-
# - Setting a different Formatter object on the existing StreamHandler object.
168-
# - Reconfiguring the existing LogMessageFormatter object, e.g. to enable logging
169-
# of timestamps.
170-
# - Configuring openwave to call an application-specific logging function by
187+
# This behavior can be overridden in a variety of ways:
188+
# - Initialize a different log handler before WeaveStack is initialized.
189+
# - Pass installDefaultLogHandler=False when initializing WeaveStack.
190+
# - Replace the StreamHandler on self.logger with a different handler object.
191+
# - Set a different Formatter object on the existing StreamHandler object.
192+
# - Reconfigure the existing WeaveLogFormatter object.
193+
# - Configure openweave to call an application-specific logging function by
171194
# calling self.setLogFunct().
172-
# - Calling self.setLogFunct(None), which will configure the openweave library
195+
# - Call self.setLogFunct(None), which will configure the openweave library
173196
# to log directly to stdout, bypassing python altogether.
174197
#
175-
self.logger = logging.getLogger(__name__)
176-
if len(self.logger.handlers) == 0:
198+
if installDefaultLogHandler and not hasHandlers:
177199
logHandler = logging.StreamHandler(stream=sys.stdout)
178200
logHandler.setFormatter(WeaveLogFormatter())
179201
self.logger.addHandler(logHandler)
180202
self.logger.setLevel(logging.DEBUG)
181-
self.setLogFunct(self.defaultLogFunct)
182203

183204
def HandleComplete(appState, reqState):
184205
self.callbackRes = True

0 commit comments

Comments
 (0)