This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: logging: Filters on Loggers can't actually filter messages on lower levels of the logging hierarchy
Type: Stage:
Components: Library (Lib) Versions: Python 2.4, Python 2.7, Python 2.6, Python 2.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: vinay.sajip Nosy List: leorochael, vinay.sajip
Priority: normal Keywords: patch

Created on 2009-12-17 18:52 by leorochael, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
logging-allow-parent-filtering.diff leorochael, 2009-12-17 18:52 Patch allowing parent loggers to filter messages.
Messages (4)
msg96524 - (view) Author: Leonardo Rochael Almeida (leorochael) Date: 2009-12-17 18:52
A filter added to, say, logging.getLogger('a').addFilter() never gets
the chance to filter messages logged into logging.getLogger('a.b').

On logging.Logger.handle() the current logger filters are called to
check if the message should be processed or not, but the logger parent
filters are not consulted (and this is ok, IMHO, more generic filters
shouldn't clobber messages of more specific loggers).

However, if none of the current filters block the message,
Logger.handle() then calls Logger.callHandlers(), which calls the
handlers of the current logger and of all the parent loggers as long as
each logger in the hierarchy allows the message to propagate. This is
done without consulting the parent loggers filters.

This means parent handlers get called to process log records even if the
parent logger filters would have otherwise blocked them.

Attached is a very crude patch that allows the parent loggers to filter
events before handling them. I'd prefer to simply call the "handle()" 
or "callHandler()" method of the parent loggers recursively, but
couldn't find a way to do this while still preserving the method
signatures AND properly reporting when no handler could be found.

My preference would be to have callHandlers() do the filtering AND
return a number of handlers invoked, including the parent handlers, so
that handle() could report if no handlers could be found.
msg96525 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-12-17 19:20
This behaviour is by design. Messages logged to logger 'a.b' are not
passed to logger 'a' - they are passed to *the handlers* of logger 'a'
(and so on up until a false value is seen for the logger's 'propagate'
attribute). In this respect, filtering works in the same way as levels
do - for example if logger 'a' has a level of WARNING and logger 'a.b'
has a level of DEBUG, then DEBUG events logged to 'a.b' will still show
up in the logs.

Closing, as it's not a bug, and implementing the alternative would not
be backwards compatible.
msg96541 - (view) Author: Leonardo Rochael Almeida (leorochael) Date: 2009-12-17 23:01
At the very least this is a documentation bug. By reading the std docs
on the logging module [1] one gets the impression that if a log record
gets to a certain logger, even if percolated from more specific loggers,
then the filters to that logger should be involved and even get the
chance to change the log record.

[1] http://docs.python.org/library/logging.html

This is reinforced by the documentation and the implementation of the
logging.Filter class, which is supposed to filter-out messages of more
specific loggers, but which would never actually filter out anything if
applied to a Logger of the same "name" (as opposed to a Handler, since
filter handlers do get called for log records of more specific loggers).
msg96555 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2009-12-18 08:48
> Leonardo Rochael Almeida  added the comment:

> 
> At the very least this is a documentation bug. By reading the std docs
> on the logging module [1] one gets the impression that if a log record
> gets to a certain logger, even if percolated from more specific loggers,
> then the filters to that logger should be involved and even get the
> chance to change the log record.
> 
> [1] http://docs.python.org/library/logging.html
> 
> This is reinforced by the documentation and the implementation of the
> logging.Filter class, which is supposed to filter-out messages of more
> specific loggers, but which would never actually filter out anything if
> applied to a Logger of the same "name" (as opposed to a Handler, since
> filter handlers do get called for log records of more specific loggers).
> 

Can you say more specifically which part of this document you think is misleading? For example, the Filter documentation says "Filters can be used by Handlers and Loggers for
more sophisticated filtering than is provided by levels." Now this documentation does also mention how the default Filter implementation works, which does refer to loggers and their children - but that's just a specific implementation of a Filter which allows through some part of the logger namespace hierarchy. (It just looks at the logger name to decide whether to let an event through or not.) It's not a statement about how Filters work in general.

If you can confirm which parts of the logging documentation you think need to be changed (feel free to suggest alternative wording or additional wording) I'll certainly try to make those parts clearer.
History
Date User Action Args
2022-04-11 14:56:55adminsetgithub: 51784
2009-12-18 08:48:45vinay.sajipsetmessages: + msg96555
2009-12-17 23:01:06leorochaelsetmessages: + msg96541
2009-12-17 19:20:16vinay.sajipsetstatus: open -> closed

nosy: + vinay.sajip
messages: + msg96525

assignee: vinay.sajip
resolution: not a bug
2009-12-17 18:52:13leorochaelcreate