Logging with Custom Levels not working
Greetings, I've been setting up a custom logging for a project here and got some great examples of code from stackoverflow. The only problem I'm having is that no matter what I set the log level too all the messages print out... Verbosity Level set to: 55 [PVERBOSE] Performance Verbose Level [PDEBUG] Performance Debug Level [PMESSAGE] Performance Message Level [PWARNING] Performance Warning Level [PERROR] Performance Error Level This should only print the PERROR level, but everything in the custom levels is being printed out. Not sure what I'm doing wrong here. Any help is greatly appreciated. We are use Python 2.7.5 .Example Code below: Thanks Tom #!/usr/bin/python -tt import logging # # Performance Custom Message Levels 'PERROR' : 55, 'PWARNING' : 54, 'PMESSAGE': 53, 'PDEBUG' : 52, 'PVERBOSE' : 51 # PERROR_NUM = 55 PWARNING_NUM = 54 PMESSAGE_NUM = 53 PDEBUG_NUM = 52 PVERBOSE_NUM = 51 # Performance Error... logging.addLevelName(PERROR_NUM, "PERROR") def perror(self, message, *args, **kws): """ Performance Error Message Level """ # Yes, logger takes its '*args' as 'args'. self._log(PERROR_NUM, message, args, **kws) logging.Logger.perror = perror # 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 # Performance Messages... logging.addLevelName(PMESSAGE_NUM, "PMESSAGE") def pmessage(self, message, *args, **kws): """ Performance Info/Message Level """ # Yes, logger takes its '*args' as 'args'. self._log(PMESSAGE_NUM, message, args, **kws) logging.Logger.pmessage = pmessage # Performance Debug... logging.addLevelName(PDEBUG_NUM, "PDEBUG") def pdebug(self, message, *args, **kws): """ Performance Debug Message Level """ # Yes, logger takes its '*args' as 'args'. self._log(PDEBUG_NUM, message, args, **kws) logging.Logger.pdebug = pdebug # Performance Verbose... logging.addLevelName(PVERBOSE_NUM, "PVERBOSE") def pverbose(self, message, *args, **kws): """ Performance Verbose Message Level """ # Yes, logger takes its '*args' as 'args'. self._log(PVERBOSE_NUM, message, args, **kws) logging.Logger.pverbose = pverbose # # Setup Logging. # def SetLogging(verbosity): """ Set logging file and level. """ global rootLogger logFormatter = logging.Formatter("[%(levelname)s] %(message)s") # Output formatting for message (i.e. date/time, thread, line #, message level, message). rootLogger = logging.getLogger() # Add a File to log too... fileHandler = logging.FileHandler('/tmp/log.txt') fileHandler.setFormatter(logFormatter) rootLogger.addHandler(fileHandler) # Put the message on the Console as well.. consoleHandler = logging.StreamHandler() consoleHandler.setFormatter(logFormatter) rootLogger.addHandler(consoleHandler) # Set what the logging level should be: level = logging.getLevelName(verbosity) # This turns the level into a number, which setLevel uses or logging.INFO for "verbosity" variable. rootLogger.setLevel(level) # This can be DEBUG, INFO, WARN, ERROR or CRITICAL to control verbosity. Custom Levels: PVERBOSE (51), PDEBUG (52), PWARNING (53) or PERROR (54) print 'Verbosity Level set to: %s' % level # # # verbosity = 'PERROR' SetLogging(verbosity) rootLogger.pverbose('Performance Verbose Level') rootLogger.pdebug('Performance Debug Level') rootLogger.pmessage('Performance Message Level') rootLogger.pwarning('Performance Warning Level') rootLogger.perror('Performance Error Level') -- https://mail.python.org/mailman/listinfo/python-list
Re: Logging with Custom Levels not working
On Wednesday, February 18, 2015 at 3:16:40 PM UTC-5, Ian wrote: > > def perror(self, message, *args, **kws): > > """ Performance Error Message Level """ > > # Yes, logger takes its '*args' as 'args'. > > self._log(PERROR_NUM, message, args, **kws) > > > > logging.Logger.perror = perror > > I think you need to call self.log, not self._log. The _log method > appears to assume that the level check has already been performed. You > really shouldn't be calling it directly anyway, as the leading _ is an > indication that the method is not part of the public API. Yes, I had tried that and get: Logged from file log5.py, line 21 Traceback (most recent call last): File "/usr/lib64/python2.7/logging/__init__.py", line 851, in emit msg = self.format(record) File "/usr/lib64/python2.7/logging/__init__.py", line 724, in format return fmt.format(record) File "/usr/lib64/python2.7/logging/__init__.py", line 464, in format record.message = record.getMessage() File "/usr/lib64/python2.7/logging/__init__.py", line 328, in getMessage msg = msg % self.args TypeError: not all arguments converted during string formatting I also added: ll = rootLogger.getEffectiveLevel() which send back the correct level, but it's still printing out everything... -Tom -- https://mail.python.org/mailman/listinfo/python-list
Re: Logging with Custom Levels not working
On Friday, February 20, 2015 at 4:25:50 AM UTC-5, Ian wrote: > > On Wednesday, February 18, 2015 at 3:16:40 PM UTC-5, Ian wrote: > >> > def perror(self, message, *args, **kws): > >> > """ Performance Error Message Level """ > >> > # Yes, logger takes its '*args' as 'args'. > >> > self._log(PERROR_NUM, message, args, **kws) > >> > > >> > logging.Logger.perror = perror > >> > >> I think you need to call self.log, not self._log. The _log method > >> appears to assume that the level check has already been performed. You > >> really shouldn't be calling it directly anyway, as the leading _ is an > >> indication that the method is not part of the public API. > > > > Yes, I had tried that and get: > > > > Logged from file log5.py, line 21 > > Traceback (most recent call last): > > File "/usr/lib64/python2.7/logging/__init__.py", line 851, in emit > > msg = self.format(record) > > File "/usr/lib64/python2.7/logging/__init__.py", line 724, in format > > return fmt.format(record) > > File "/usr/lib64/python2.7/logging/__init__.py", line 464, in format > > record.message = record.getMessage() > > File "/usr/lib64/python2.7/logging/__init__.py", line 328, in getMessage > > msg = msg % self.args > > TypeError: not all arguments converted during string formatting > > log and _log don't have the same function signature. Specifically, log > takes *args and _log just takes args (as noted in the comment on the > preceding line). Hi, I found the problem. I wasn't setting the level on the Handlers. Need to have: fileHandler.setLevel(level) consoleHandler.setLevel(level) Once that was added to the SetLogging() function, it was printing out the correct levels. The rootLogger.setLevel(level) wasn't getting propagated to the Handlers... Thanks for all the help! Tom -- https://mail.python.org/mailman/listinfo/python-list
Logging custom level not print module properly??
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. -Tom -- https://mail.python.org/mailman/listinfo/python-list
Re: Logging custom level not print module properly??
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 -- https://mail.python.org/mailman/listinfo/python-list
Logging Custom Levels?
Hi, I've create a Python file called "log.py" and placed in the custom levels: # Performance Debug... logging.addLevelName(PDEBUG_NUM, "PDEBUG") def pdebug(self, message, *args, **kws): """ Performance Debug Message Level """ self.log(PDEBUG_NUM, message, *args, **kws) logging.Logger.pdebug = pdebug This works except that the %(module) and %(lineno) does not print properly, it instead prints out as the "log.py" and the line that this is on. I think I figured out a way to get the module and line from the calling custom level: import inspect frame = inspect.currentframe() filename = os.path.splitext(os.path.basename(frame.f_back.f_code.co_filename))[0] linenumber = frame.f_back.f_lineno My question is how do I pass this into the "self.log" call properly? I've tried a few different things without any luck. Any ideas how I can pass this into the custom logging level and get it to work? Thanks in Advance for any help! Tom -- https://mail.python.org/mailman/listinfo/python-list
Re: Logging Custom Levels?
On Tuesday, March 31, 2015 at 1:37:29 PM UTC-4, Jean-Michel Pichavant wrote: > > A solution is pretty simple, do not use an intermediate log function pdebug. > > import logging > PDEBUG_NUM=20 > logging.addLevelName(PDEBUG_NUM, "PDEBUG") > > logger = logging.getLogger('foo') > logging.basicConfig(level=logging.DEBUG, format='%(message)s %(lineno)d') > > logger.log(PDEBUG_NUM, 'This will work :') > > > If you *really* want to go for the hackish way, forget about the inspect > module, the following pdebug function should do the trick: > > def pdebug(self, message, *args, **kws): > if self.isEnabledFor(PDEBUG_NUM): > self._log(PDEBUG_NUM, message, args, **kws) > > Cheers, > > JM > Very good, thank you! Tom -- https://mail.python.org/mailman/listinfo/python-list
pexpect matching?
Greetings, I have the following code: import pexpect child = pexpect.spawn('/bin/bash') i = child.expect_exact('bash-3.2$ ') child.sendline("rpm -q --queryformat '%{VERSION}\\n' glibc") i = child.expect (['2', '2.5', '2.52.5', pexpect.TIMEOUT]) print child.before print '---' print child.after if i == 0: print 'We got 2' elif i == 1: print 'We got 2.5' elif i == 2: print ' We got 7' elif i == 3: print 'Timed Out!' else: print 'What happened?' The output of the commandline is: % rpm -q --queryformat '%{VERSION}\n' glibc 2.5 2.5 I've tried to use "\b", "^", "$" around the return stings and even expect_exact, but end up with it printing "We got 2". It's just mathcing the first character and not the entire string. rpm -q --queryformat '%{VERSION}\n' glibc --- 2 We got 2 What am I doing wrong here? What do I need to tell the expect line to grab the entire line back to check against? Thanks Tom -- https://mail.python.org/mailman/listinfo/python-list
Assignment Operators?
Hi All, I was wondering if someone could explain an assignment operator that I'm seeing in some code. As an example: >>> errors = False >>> errors |= 3 >>> errors 3 >>> errors |= 4 >>> errors 7 The '|=' operator, I read should be like a = a | b, but this appears to add the two numbers as long as it's more than the previous: >>> errors |= 5 >>> errors 7 Is there anywhere I can read up more on this and the other assignment operators and what/how they work. I got this off http://rgruet.free.fr/PQR27/PQR2.7.html I'm using: % python Python 2.7.5 (default, Sep 25 2014, 13:57:38) [GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2 Thanks for any help in advance. Tom -- https://mail.python.org/mailman/listinfo/python-list
argparse epilog call function?
Greetings, I might be barking up the wrong tree, but was wondering if there's a way to have the argpasre epilog call a function. for example: epilog=Examples() Where Examples is: def Examples(): text = """Lots of examples""" print(text.format()) I've place this in and found that it prints out no matter if I use the -h or not and also it prints first If I do: epilog='Single Example' it works as intended, unfortunately, I need to show several examples. Just wondering if someone has found a why to do this (without making a custom help). thanks Tom -- https://mail.python.org/mailman/listinfo/python-list
Re: argparse epilog call function?
On Tuesday, June 27, 2017 at 9:56:13 AM UTC-4, Didymus wrote: > Greetings, > > I might be barking up the wrong tree, but was wondering if there's a way to > have the argpasre epilog call a function. for example: > > epilog=Examples() > > Where Examples is: > > def Examples(): > text = """Lots of examples""" > print(text.format()) > > I've place this in and found that it prints out no matter if I use the -h or > not and also it prints first If I do: > > epilog='Single Example' > > it works as intended, unfortunately, I need to show several examples. Just > wondering if someone has found a why to do this (without making a custom > help). > > thanks > Tom Well, I thought I had a good idea to work around this by setting a string to the formatted text and then use that string in the epilog: text = Example() # parser = argparse.ArgumentParser(prog=sys.argv[0], description="Example Arg Parse", epilog=text) I had to change the Example function to return the string and in a print it works fine, however when used in the argsparse, the formatting is lost... -T -- https://mail.python.org/mailman/listinfo/python-list
Re: argparse epilog call function?
On Tuesday, June 27, 2017 at 11:47:42 AM UTC-4, Didymus wrote: > On Tuesday, June 27, 2017 at 9:56:13 AM UTC-4, Didymus wrote: > > Greetings, > > > > I might be barking up the wrong tree, but was wondering if there's a way to > > have the argpasre epilog call a function. for example: > > > > epilog=Examples() > > > > Where Examples is: > > > > def Examples(): > > text = """Lots of examples""" > > print(text.format()) > > > > I've place this in and found that it prints out no matter if I use the -h or > > not and also it prints first If I do: > > > > epilog='Single Example' > > > > it works as intended, unfortunately, I need to show several examples. Just > > wondering if someone has found a why to do this (without making a custom > > help). > > > > thanks > > Tom > Well, I thought I had a good idea to work around this by setting a string to > the formatted text and then use that string in the epilog: > > text = Example() > # > parser = argparse.ArgumentParser(prog=sys.argv[0], > description="Example Arg Parse", > epilog=text) > > I had to change the Example function to return the string and in a print it > works fine, however when used in the argsparse, the formatting is lost... > > -T Greetings, I got what I was looking for: def Examples(): text = """Lots of examples""" return text.format() parser = argparse.ArgumentParser(prog=sys.argv[0], formatter_class=argparse.RawTextHelpFormatter, description="Argparse Example", epilog=text) The key here is the "formatter_class=argparse.RawTestHelpFormatter". Once I set that the epilog prints out nicely formatted: % ./test.py -h usage: ./test.py [-h] [-n NAME] [-f | -m | -r | -v] Argparse Example. optional arguments: -h, --helpshow this help message and exit -n NAME, --name NAME Name to be created. Examples: Ex 1: ./test.py -n juser Ex 2: ./test.py -n juser -r ... Thanks for all the help. -Tom -- https://mail.python.org/mailman/listinfo/python-list