Use standard logging library
In Python there is only one proper pattern: use standard logging module according to official HowTo. Or, for Python 3, this standard logging module and this HowTo. There are no important differences between these versions¹.
If you have reasons to dislike the standard library, you can alternatively use one of the existing replacements. They have different configuration and some extensions, but the basic usage is similar or identical. I'll get to them later. It should be relatively easy to switch to them at any time, so logging
is at least a good starting point.
Usage in your module
Your code looks like this:
import logging
logger = logging.getLogger(__name__) # you can use other name
logger.info('Loading my cool module with cool logging')
def coolFunction(x):
logger.debug('Most of the time this message is really irrelevant')
...
if something_suspicious:
logger.warning('Something suspicious happened: nothing broken yet, but you probably want to know')
...
if everything_is_wrong:
logger.error('Everything is broken and this program just went nuts')
Or alternatively, you can use simpler:
logging.info(...)
logging.debug(...)
instead of creating a logger, but it seems simple enough to add this single line everywhere.
If you are not sure what logging levels to use for different messages, you can refer to this SO question with some decent answers.
Configuration
Then somewhere in your cofig you say:
logging.basicConfig(filename='example.log', level=logging.INFO)
or
logging.basicConfig(filename='example.log', level=logging.DEBUG)
to set the output and filter the errors appropriately. If you want to use stderr, say
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
instead.
Alternative handlers, logging to external services
There is also a number of libraries that you can but in place of basic logger, like raven for Sentry. You don't need to change anything in your code to tap into such a service, you just change the configuration.
Alternative libraries
There are some libraries that that you may want to use to completely replace logging
. They follow similar pattern, central logging configuration, then access a logger in each file and log using log levels. Logbook seems to be a mostly drop-in replacement for logging, with some nice features added. Some other are mentioned in this SO question.
Removing logging from optimized build
For extreme cases where debug logging might significantly affect performance or leak sensitive data in production environment, built-in __debug__
constant can be used:
if __debug__:
debug_info = some_complex_computation()
logger.debug()
In this case, the whole statement would be erased when compiling the code with -o
option. However, this solution is ugly and somewhat brittle, it should be used with care and only where really necessary. For most applications that means "nowhere, never".
Other languages
For other languages, it may look just the same (e.g. in Java) or slightly different, and vary somewhat (not every language has one standard way). But in general, you will find very similar patters, stuff like
LOG(DEBUG, "Your message")
or
LOG_ERROR("Error message")
or
LOG(INFO) << "Some people like C++ streams' syntax"
¹ AFAIK the only difference worth knowing about is that Python 3 has a "last resort" logger logging to stderror, so if you omit config completely, you still get something. In Python 2 you get just a warning about misconfigured logging.
debug
variable instead of expecting the same parameter to get passed in over and over again, from every place where it is used in your program?debug
variable used in a large code base. The problem is that the meaning of debug becomes really murky - It is used in different functions for different reasons: logging, mocking rest APIs with local JSON, changing the REST endpoint, etc. This could be mitigated with calling the variablelogging_enabled
though.debug
is a pretty terrible name for a global variable, it's quite meaningless, as you say. For a big system you should definitely use more fine-grained logging with multiple logging levels, as shown in my answer. There is some general agreement on what different log levels mean.