I'm using Logging (import logging
) to log messages.
Within 1 single module, I am logging messages at the debug level my_logger.debug('msg')
;
Some of these debug messages come from function_a()
and others from function_b()
; I'd like to be able to enable/disable logging based on whether they come from a or from b;
I'm guessing that I have to use Logging's filtering mechanism.
Can someone show me how the code below would need to be instrumented to do what I want?
import logging logger = logging.getLogger( "module_name" ) def function_a( ... ): logger.debug( "a message" ) def function_b( ... ): logger.debug( "another message" ) if __name__ == "__main__": logging.basicConfig( stream=sys.stderr, level=logging.DEBUG ) #don't want function_a()'s noise -> .... #somehow filter-out function_a's logging function_a() #don't want function_b()'s noise -> .... #somehow filter-out function_b's logging function_b()
If I scaled this simple example to more modules and more funcs per module, I'd be concerned about lots of loggers;
Can I keep it down to 1 logger per module? Note that the log messages are "structured", i.e. if the function(s) logging it are doing some parsing work, they all contain a prefix logger.debug("parsing: xxx")
- can I somehow with a single line just shut-off all "parsing" messages (regardless of the module/function emitting the message?)
A filter provides an optional, secondary control over what is logged, beyond the control that is provided by setting the level. Applications can apply a filter mechanism to control logging output through the logging APIs. An example of filter usage is to suppress all the events with a particular message key.
Filter : http://docs.python.org/library/logging.html#filter-objects. It will have one method, filter(record) , that examines the log record and returns True to log it or False to discard it. Then you can install the filter on either a Logger or a Handler by calling its addFilter(filter) method.
Using Regular Expressions (Regex) You can use regular expressions, also known as a regex, to filter logs. Regex can be helpful in filtering your logs to get exactly what you want to see from the log message. Regex also gives the flexibility of writing an expression of your choice.
Filters allow you to select data based on values that it contains. Most frequently, you use filters when viewing logs, but filters can also be used for other tasks, such as exporting logs and selecting data for reports. Diagrams allow you to visualize your network security environment.
Just implement a subclass of logging.Filter
: http://docs.python.org/library/logging.html#filter-objects. It will have one method, filter(record)
, that examines the log record and returns True to log it or False to discard it. Then you can install the filter on either a Logger
or a Handler
by calling its addFilter(filter)
method.
Example:
class NoParsingFilter(logging.Filter): def filter(self, record): return not record.getMessage().startswith('parsing') logger.addFilter(NoParsingFilter())
Or something like that, anyway.
Do not use global. It's an accident waiting to happen.
You can give your loggers any "."-separated names that are meaningful to you.
You can control them as a hierarchy. If you have loggers named a.b.c
and a.b.d
, you can check the logging level for a.b
and alter both loggers.
You can have any number of loggers -- they're inexpensive.
The most common design pattern is one logger per module. See Naming Python loggers
Do this.
import logging logger= logging.getLogger( "module_name" ) logger_a = logger.getLogger( "module_name.function_a" ) logger_b = logger.getLogger( "module_name.function_b" ) def function_a( ... ): logger_a.debug( "a message" ) def function_b( ... ): logger_b.debug( "another message" ) if __name__ == "__main__": logging.basicConfig( stream=sys.stderr, level=logging.DEBUG ) logger_a.setLevel( logging.DEBUG ) logger_b.setLevel( logging.WARN ) ... etc ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With