Saturday, 8 November 2014

Logging and warnings

Now that some of my code is nearing release quality, I'm replacing all the diagnostic 'print' statements with logging commands. There are a few articles on StackOverflow describing how to make logging process-safe I don't really need that since the number of messages I expect to log are so few that there is no real chance of two processes trying to write to the file at the same time.

One tricky part was catching warnings that are thrown by the underlying scipy library. It turned out to be quite easy to fix.

The module containing main() has to import logging and then at the start of the main() function I add the following

logging.basicConfig(filename='example.log',
                    filemode='w',
                    format='%(levelname)s:%(message)s',
                    level=logging.DEBUG)
 
Then in the sub-modules, import logging and warnings and I used this structure to catch the warning, convert it to an exception that I could then pass to the logger. Finally I ran the function again without catching the warning to regenerate the result (which was still valid; the warning was just for not achieving an accuracy limit)

def function_that_gets_scipy_warning(self, args):
    with warnings.catch_warnings():
        warnings.filterwarnings('error')
        try:
            result = scipy.somefunction(args)
        except Warning, warn:
            logging.warning(warn)
            warnings.filterwarnings('ignore')
            result = scipy.somefunction(args)
    return result 
 
This writes the warning out to the example.log file and not to the terminal.

No comments:

Post a Comment