tetrahedron-technologies / pydhsfw

Python-based Distributed Hardware Server FrameWork for extending DCSS beamline control system and enabling development in python.
MIT License
3 stars 0 forks source link

Should we add new more verbose logging level to logger? #57

Open gcmullen opened 3 years ago

gcmullen commented 3 years ago

Potentially add a new logging level called barf() for really big messages like the jpegs that come through some messages.

Here's how in general but there are risks and the logging documentation advises to use caution. https://stackoverflow.com/questions/2183233/how-to-add-a-custom-loglevel-to-pythons-logging-facility

def addLoggingLevel(levelName, levelNum, methodName=None):
    """
    Comprehensively adds a new logging level to the `logging` module and the
    currently configured logging class.

    `levelName` becomes an attribute of the `logging` module with the value
    `levelNum`. `methodName` becomes a convenience method for both `logging`
    itself and the class returned by `logging.getLoggerClass()` (usually just
    `logging.Logger`). If `methodName` is not specified, `levelName.lower()` is
    used.

    To avoid accidental clobberings of existing attributes, this method will
    raise an `AttributeError` if the level name is already an attribute of the
    `logging` module or if the method name is already present 

    Example
    -------
    >>> addLoggingLevel('TRACE', logging.DEBUG - 5)
    >>> logging.getLogger(__name__).setLevel("TRACE")
    >>> logging.getLogger(__name__).trace('that worked')
    >>> logging.trace('so did this')
    >>> logging.TRACE
    5

    """
    if not methodName:
        methodName = levelName.lower()

    if hasattr(logging, levelName):
       raise AttributeError('{} already defined in logging module'.format(levelName))
    if hasattr(logging, methodName):
       raise AttributeError('{} already defined in logging module'.format(methodName))
    if hasattr(logging.getLoggerClass(), methodName):
       raise AttributeError('{} already defined in logger class'.format(methodName))

    # This method was inspired by the answers to Stack Overflow post
    # http://stackoverflow.com/q/2183233/2988730, especially
    # http://stackoverflow.com/a/13638084/2988730
    def logForLevel(self, message, *args, **kwargs):
        if self.isEnabledFor(levelNum):
            self._log(levelNum, message, args, **kwargs)
    def logToRoot(message, *args, **kwargs):
        logging.log(levelNum, message, *args, **kwargs)

    logging.addLevelName(levelNum, levelName)
    setattr(logging, levelName, levelNum)
    setattr(logging.getLoggerClass(), methodName, logForLevel)
    setattr(logging, methodName, logToRoot)
dsclassen commented 3 years ago

Seeing the entire base64 encoded image data is a bit jarring. I am in favor of somehow suppressing it.

gcmullen commented 3 years ago

Agreed. I just don't know where or how soon the addLoggingLevel() function above should be called. I think it has to be done before the _logger = logging.getLogger(__name__) call in each module. Ugh, I hope not, not sure how to get in front of that it that's the case. We will have to experiment with this.

dsclassen commented 3 years ago

https://github.com/xolox/python-coloredlogs and https://github.com/xolox/python-verboselogs both available via pip install... seem like decent options for implementing some extra log levels.

gcmullen commented 3 years ago

Sounds like we have an answer to the questions. Yes! with coloredlogs and verboselogs.

Need a tracker for implementation. If our framework takes advantage of these we will need the FW set up defaults properly with and give the DHS author the ability to override.