diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index a55d3865bdccae..728fd5801f1cb1 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -212,7 +212,6 @@ PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::Devic const char * pychip_Stack_ErrorToString(ChipError::StorageType err); const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode); -void pychip_Stack_SetLogFunct(LogMessageFunct logFunct); PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback); @@ -863,17 +862,6 @@ uint64_t pychip_GetCommandSenderHandle(chip::DeviceProxy * device) return 0; } -void pychip_Stack_SetLogFunct(LogMessageFunct logFunct) -{ - // TODO: determine if log redirection is supposed to be functioning in CHIP - // - // Background: original log baseline supported 'redirect logs to this - // function' however CHIP does not currently provide this. - // - // Ideally log redirection should work so that python code can do things - // like using the log module. -} - PyChipError pychip_DeviceController_PostTaskOnChipThread(ChipThreadTaskRunnerFunct callback, void * pythonContext) { if (callback == nullptr || pythonContext == nullptr) diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index beeaedd6ae3327..06afff3ef3c380 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -28,15 +28,11 @@ import asyncio import builtins -import logging import os -import sys -import time -from ctypes import CFUNCTYPE, Structure, c_bool, c_char_p, c_int64, c_uint8, c_uint16, c_uint32, c_void_p, py_object, pythonapi +from ctypes import CFUNCTYPE, Structure, c_bool, c_char_p, c_uint16, c_uint32, c_void_p, py_object, pythonapi from threading import Condition, Event, Lock import chip.native -from chip.logging import LOG_CATEGORY_AUTOMATION, LOG_CATEGORY_DETAIL, LOG_CATEGORY_ERROR, LOG_CATEGORY_PROGRESS from chip.native import PyChipError from .ChipUtility import ChipUtility @@ -76,51 +72,6 @@ class DeviceStatusStruct(Structure): ] -class LogCategory(object): - """Debug logging categories used by chip.""" - - @staticmethod - def categoryToLogLevel(cat): - if cat == LOG_CATEGORY_ERROR: - return logging.ERROR - elif cat == LOG_CATEGORY_PROGRESS: - return logging.INFO - elif cat in (LOG_CATEGORY_DETAIL, LOG_CATEGORY_AUTOMATION): - return logging.DEBUG - else: - return logging.NOTSET - - -class ChipLogFormatter(logging.Formatter): - """A custom logging.Formatter for logging chip library messages.""" - - def __init__( - self, - datefmt=None, - logModulePrefix=False, - logLevel=False, - logTimestamp=False, - logMSecs=True, - ): - fmt = "%(message)s" - if logModulePrefix: - fmt = "CHIP:%(chip-module)s: " + fmt - if logLevel: - fmt = "%(levelname)s:" + fmt - if datefmt is not None or logTimestamp: - fmt = "%(asctime)s " + fmt - super(ChipLogFormatter, self).__init__(fmt=fmt, datefmt=datefmt) - self.logMSecs = logMSecs - - def formatTime(self, record, datefmt=None): - if datefmt is None: - timestampStr = time.strftime("%Y-%m-%d %H:%M:%S%z") - if self.logMSecs: - timestampUS = record.__dict__.get("timestamp-usec", 0) - timestampStr = "%s.%03ld" % (timestampStr, timestampUS / 1000) - return timestampStr - - class AsyncCallableHandle: def __init__(self, callback): self._callback = callback @@ -185,15 +136,12 @@ def __call__(self): pythonapi.Py_DecRef(py_object(self)) -_LogMessageFunct = CFUNCTYPE( - None, c_int64, c_int64, c_char_p, c_uint8, c_char_p) _ChipThreadTaskRunnerFunct = CFUNCTYPE(None, py_object) @_singleton class ChipStack(object): - def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, - bluetoothAdapter=None, enableServerInteractions=True): + def __init__(self, persistentStoragePath: str, enableServerInteractions=True): builtins.enableDebugMode = False # TODO: Probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321. @@ -206,8 +154,6 @@ def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, self.callbackRes = None self.commissioningEventRes = None self.openCommissioningWindowPincode = {} - self._activeLogFunct = None - self.addModulePrefixToLogMessage = True self._enableServerInteractions = enableServerInteractions # @@ -216,50 +162,6 @@ def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, # self._loadLib() - # Arrange to log output from the chip library to a python logger object with the - # name 'chip.ChipStack'. If desired, applications can override this behavior by - # setting self.logger to a different python logger object, or by calling setLogFunct() - # with their own logging function. - self.logger = logging.getLogger(__name__) - self.setLogFunct(self.defaultLogFunct) - - # Determine if there are already handlers installed for the logger. Python 3.5+ - # has a method for this; on older versions the check has to be done manually. - if hasattr(self.logger, "hasHandlers"): - hasHandlers = self.logger.hasHandlers() - else: - hasHandlers = False - logger = self.logger - while logger is not None: - if len(logger.handlers) > 0: - hasHandlers = True - break - if not logger.propagate: - break - logger = logger.parent - - # If a logging handler has not already been initialized for 'chip.ChipStack', - # or any one of its parent loggers, automatically configure a handler to log to - # stdout. This maintains compatibility with a number of applications which expect - # chip log output to go to stdout by default. - # - # This behavior can be overridden in a variety of ways: - # - Initialize a different log handler before ChipStack is initialized. - # - Pass installDefaultLogHandler=False when initializing ChipStack. - # - Replace the StreamHandler on self.logger with a different handler object. - # - Set a different Formatter object on the existing StreamHandler object. - # - Reconfigure the existing ChipLogFormatter object. - # - Configure chip to call an application-specific logging function by - # calling self.setLogFunct(). - # - Call self.setLogFunct(None), which will configure the chip library - # to log directly to stdout, bypassing python altogether. - # - if installDefaultLogHandler and not hasHandlers: - logHandler = logging.StreamHandler(stream=sys.stdout) - logHandler.setFormatter(ChipLogFormatter()) - self.logger.addHandler(logHandler) - self.logger.setLevel(logging.DEBUG) - @_ChipThreadTaskRunnerFunct def HandleChipThreadRun(callback): callback() @@ -292,49 +194,6 @@ def GetStorageManager(self): def enableServerInteractions(self): return self._enableServerInteractions - @property - def defaultLogFunct(self): - """Returns a python callable which, when called, logs a message to the python logger object - currently associated with the ChipStack object. - The returned function is suitable for passing to the setLogFunct() method.""" - - def logFunct(timestamp, timestampUSec, moduleName, logCat, message): - moduleName = ChipUtility.CStringToString(moduleName) - message = ChipUtility.CStringToString(message) - if self.addModulePrefixToLogMessage: - message = "CHIP:%s: %s" % (moduleName, message) - logLevel = LogCategory.categoryToLogLevel(logCat) - msgAttrs = { - "chip-module": moduleName, - "timestamp": timestamp, - "timestamp-usec": timestampUSec, - } - self.logger.log(logLevel, message, extra=msgAttrs) - - return logFunct - - def setLogFunct(self, logFunct): - """Set the function used by the chip library to log messages. - The supplied object must be a python callable that accepts the following - arguments: - timestamp (integer) - timestampUS (integer) - module name (encoded UTF-8 string) - log category (integer) - message (encoded UTF-8 string) - Specifying None configures the chip library to log directly to stdout.""" - if logFunct is None: - logFunct = 0 - if not isinstance(logFunct, _LogMessageFunct): - logFunct = _LogMessageFunct(logFunct) - # TODO: Lock probably no longer necessary, see https://github.com/project-chip/connectedhomeip/issues/33321. - with self.networkLock: - # NOTE: ChipStack must hold a reference to the CFUNCTYPE object while it is - # set. Otherwise it may get garbage collected, and logging calls from the - # chip library will fail. - self._activeLogFunct = logFunct - self._ChipStackLib.pychip_Stack_SetLogFunct(logFunct) - def Shutdown(self): # # Terminate Matter thread and shutdown the stack. @@ -484,9 +343,6 @@ def _loadLib(self): self._ChipStackLib.pychip_Stack_StatusReportToString.restype = c_char_p self._ChipStackLib.pychip_Stack_ErrorToString.argtypes = [c_uint32] self._ChipStackLib.pychip_Stack_ErrorToString.restype = c_char_p - self._ChipStackLib.pychip_Stack_SetLogFunct.argtypes = [ - _LogMessageFunct] - self._ChipStackLib.pychip_Stack_SetLogFunct.restype = PyChipError self._ChipStackLib.pychip_DeviceController_PostTaskOnChipThread.argtypes = [ _ChipThreadTaskRunnerFunct, py_object]