I’m trying to switch from using
print() to the
logging module for debugging based on the assumption that:
logging will allow me to quickly enable and disable what’s being logged
logging has built-in file and formatting utilities
- The built-in levels of
logging are helpful
To understand how to use
logging better, I thought I would look at how it’s used in Nengo. However, I’m a bit confused. Nengo has it’s own logging utilities and I see a lot of:
logger = logging.getLogger(__name__) which I know sets the name of the logger to the current module
logger.debug('some message') which sends a message to the
DEBUG level of the log
But where does the log file and the log level get chosen? How is
logging intended to be used in Nengo? Are my assumptions about the utility of
I think the Logging HOWTO might answer some of your questions.
I believe Nengo is not choosing a log file or a log level by itself. Thus, the defaults get used: Printing to the command line and a log level of
'warning'. We provide the convenience function
nengo.utils.logging.log(...) to quickly set up logging to a file and a different log level. If I need logging output, I usually put a
nengo.log('info') at the beginning of my script.
I mainly use it in Nengo to get information about what Nengo is doing that I could not get easily otherwise. For example, it is used in the cache to log hits and misses. That allows me to determine whether the cache is correctly working. From the outside the same decoders are returned for a hit and a miss, so I could not tell otherwise. Another example is the optimizer where I log information on the number of passes and reduction in the number of operators whereas the final model should exactly do the same.
I don’t use
logging for ad-hoc debugging output that I intend to remove after diagnosing the problem. Though for complex problems the ability to have some control over the messages produced could be helpful.
To add to what @jgosmann answered, the reason why we don’t set a log level and log file is because Nengo is intended to be used as a library. What happens in
logging is, for the most part, global, so libraries should not modify it without the user’s permission. It’s super frustrating when your own
logging handlers etc aren’t working properly and it turns out it’s because you imported some library that messed with the
logging handlers without you realizing it. We provide
nengo.log as a way for users to opt-in to printing out log messages to the console (or to a file is a path is passed).
By contrast, Nengo GUI is an application (as opposed to a library). We expect most people to be running the GUI from the command line, and not really importing it and using it in their own applications. Because of that, it wouldn’t be unusual for Nengo GUI to actually modify the global state in
logging. It could even read the log messages from libraries it imports to get a complete picture of some bug that a user experiences.
Thanks! That answered all the questions I had. I’ll close the topic now.