Logging custom level not print module properly??
Didymus
lynto28 at gmail.com
Tue Mar 3 10:11:57 EST 2015
On Tuesday, March 3, 2015 at 10:02:02 AM UTC-5, Peter Otten wrote:
> Didymus wrote:
>
> > Hi,
> >
> > I have setup custom levels (with the help of the Python community) for
> > logging. I set this up as a class in a module "log.py" below. The problem
> > I'm seeing is that no matter the file the the logging is happening in it
> > always prints the module as "log", I've rcreated the testcase below:
> >
> > % python run.py
> > [PWARNING log 22] Warning Message.
> > [INFO run 8] Message.
> >
> > The log.py:
> >
> > """ Logging Module """
> > import common
> > import logging
> >
> > # Custom
> > PWARNING_NUM = 34
> >
> > # Performance Warning...
> > logging.addLevelName(PWARNING_NUM, "PWARNING")
> >
> > def pwarning(self, message, *args, **kws):
> > """ Performance Warning Message Level """
> > # Yes, logger takes its '*args' as 'args'.
> > self.log(PWARNING_NUM, message, *args, **kws)
> >
> > logging.Logger.pwarning = pwarning
> >
> > class SetLogging():
> > # Variables.
> > fileHandler = None
> > consoleHandler = None
> >
> > def __init__(self):
> > """ Set Verbosity Level, set which ever is True..."""
> > common.verbosity = 'INFO'
> > self.setLogHandlers()
> >
> > def setverbosity(self, verbosity_level):
> > """ Set what the logging level should be """
> > level = logging.getLevelName(verbosity_level)
> > common.rootLogger.setLevel(level)
> >
> > def setLogHandlers(self):
> > """ Set logging file and level. """
> > logFormatter = logging.Formatter("[%(levelname)s %(module)s
> > %(lineno)d] %(message)s") common.rootLogger = logging.getLogger()
> > # Add a File to log too...
> > fileHandler = logging.FileHandler(common.LOG_FILENAME)
> > fileHandler.setFormatter(logFormatter)
> > common.rootLogger.addHandler(fileHandler)
> > # Put the message on the Console as well..
> > consoleHandler = logging.StreamHandler()
> > consoleHandler.setFormatter(logFormatter)
> > common.rootLogger.addHandler(consoleHandler)
> > self.setverbosity(common.verbosity)
> >
> > # Main
> > if __name__ == '__main__':
> > log = SetLogging()
> > log.setLogHandlers()
> > log.setverbosity('PMESSAGE')
> >
> >
> > run.py:
> > import common
> > import log
> > #
> > common.LOG_FILENAME = '/tmp/runtest.log' # Set the File the log
> > will write too based on the name and time stamp.
> > log = log.SetLogging()
> > # Set logging level and handlers.
> >
> > common.rootLogger.pwarning('Warning Message.')
> > common.rootLogger.info('Message.')
> >
> >
> > common.py:
> > # Logging Verbosity and File.
> > #
> > rootLogger = None
> > # Logger Handle, Undefined at the moment.
> > LOG_FILENAME = '/tmp/python.log'
> > # Log File full pathname.
> >
> >
> > Not sure why the "def pwarning" isnt; picking up the module that the call
> > is happening in correctly, but the standard INFO is. Thanks for any help
> > in advanced.
>
> The findCaller() method determines that your pwarning() is not part of the
> logging machinery and thus presents the file containing the pwarning()
> function as the origin of the logging event.
>
> I see no easy and clean way to inform findCaller() to go up one more level
> (the unittest package checks for a global flag for that purpose), but that
> may be because I didn't look hard enough.
>
> If your usecase for custom levels is compelling I suggest that you
> override/replace findCaller() rather than go for the following hack...
>
> exec compile('''
> # Custom
> PWARNING_NUM = 34
>
> # Performance Warning...
> addLevelName(PWARNING_NUM, "PWARNING")
>
> def pwarning(self, message, *args, **kws):
> """ Performance Warning Message Level """
> # Yes, logger takes its '*args' as 'args'.
> self.log(PWARNING_NUM, message, *args, **kws)
>
> Logger.pwarning = pwarning
> ''', logging.__file__.rstrip("co"), "exec") in vars(logging)
>
> ...which pretends that pwarning() is part of the logging/__init__.py module.
Thanks! I'll take a look.
I did find that if I changed the "self.log" to "self._log" it works correctly but gives me a pylint warning about acccess to a protected member _log..
def pwarning(self, message, *args, **kws):
""" Performance Warning Message Level """
# Yes, logger takes its '*args' as 'args'.
self._log(PWARNING_NUM, message, args, **kws)
Still wondering what the correct Pythonic way to handle this.
-Tom
More information about the Python-list
mailing list