Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-92592 : allow logging filters to return a LogRecord #92591

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

adriangb
Copy link
Contributor

@adriangb adriangb commented May 10, 2022

@adriangb adriangb changed the title allow logging filters to return a LogRecord gh-92592 : allow logging filters to return a LogRecord May 10, 2022
Copy link
Member

@vsajip vsajip left a comment

Thanks for this PR.

@@ -713,6 +713,41 @@ which, when run, produces something like:
2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters

Imparting contextual in Handlers
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be contextual information rather than just contextual. Also, no need to capitalise handlers here, as we're not talking about the class.

Imparting contextual in Handlers
---------------------------------

Each :class:`~Handler` has it's own chain of Filters.
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's should be its - the former is only used as a contraction of it is. Also, no need to capitalise filters here.


Each :class:`~Handler` has it's own chain of Filters.
If you want to add contextual information to a :class:`LogRecord` without leaking
this contextual information to other handlers, you can use a filter that returns
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could shorten this contextual information to just it.

Doc/howto/logging-cookbook.rst Show resolved Hide resolved
@@ -663,8 +663,9 @@ empty string, all events are passed.
.. method:: filter(record)

Is the specified record to be logged? Returns zero for no, nonzero for
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the change, this should be `a 'falsy' value for no, and a 'truthy' value for yes.

@@ -686,6 +687,12 @@ which has a ``filter`` method with the same semantics.
parameter. The returned value should conform to that returned by
:meth:`~Filter.filter`.

.. versionchanged:: 3.12
You can now return a :class:`LogRecord` instance from filters to replace
the log record without modifying it in place. This allows filters installed
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

installed on -> attached to

this and the record is then dropped. Returns a zero value if a record
is to be dropped, else non-zero.
this by returning a falsy value and the record is then dropped and
this method returns a falsy value.
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this now repetition which isn't needed?

Copy link
Contributor Author

@adriangb adriangb May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth differentiating between the return values of filters and the return value of the Filterer.filter function. The main difference is that filters may return a truthy value that is not a log record but Filterer.filter will now always return a log record (or falsy). I reworded it a bit to make these two different paragraphs.

is to be dropped, else non-zero.
this by returning a falsy value and the record is then dropped and
this method returns a falsy value.
Filters can return a log record, which case that log record
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change sentences to If a filter attached to a handler returns a log record instance, then that instance is used in place of the original log record in any further processing of the event by that handler. If a filter returns any other truthy value, the original log record is used in any further processing of the event by that handler.

Copy link
Contributor Author

@adriangb adriangb May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you that does sound better

@@ -467,6 +467,65 @@ def log_at_all_levels(self, logger):
for lvl in LEVEL_RANGE:
logger.log(lvl, self.next_message())

def test_handler_filter_replaces_record(self):
def replace_message(record: logging.LogRecord):
return logging.LogRecord(
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use copy.copy() here and elsewhere instead of this.

@@ -0,0 +1,3 @@
Let :mod:`logging` Filters to return a :class:`logging.LogRecord` instance
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to capitalise filters and handlers here, and also either use Allow filters to return ... or Let filters return ..., as Let ... to ... would be grammatically incorrect. Also, strictly, it would be more accurate to say ... so that filters attached to handlers can enrich ...

@bedevere-bot
Copy link

@bedevere-bot bedevere-bot commented May 10, 2022

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@adriangb
Copy link
Contributor Author

@adriangb adriangb commented May 10, 2022

Thank you for the quick an in-depth review @vsajip, that was great feedback.

I think using copy.copy resolves one of the two things I didn't like about this (the very verbose copying).

How do you feel about the interaction with filters on logging.Logger?
Since the handlers and loggers share the same implementation we have to do both.
As far as I can tell this change has no benefits for those filters, but also has no downsides.
I added a test that confirms this change "works" for logger filters, but it is pretty contrived and not representative of real world usage IMO.

@vsajip
Copy link
Member

@vsajip vsajip commented May 10, 2022

Since the handlers and loggers share the same implementation we have to do both.

Well, that shared Filterer implementation could take one of two paths - if instance(self, Handler) -> the new path, else the old (simpler) path.

@adriangb adriangb marked this pull request as ready for review May 10, 2022
@adriangb
Copy link
Contributor Author

@adriangb adriangb commented May 10, 2022

I'm not as concerned about the implementation (it's really not any more complex) as I am about the explainability. Doing something like that sounds like a leaky implementation detail. For example, you would not be able to use the same filter on a handler and a logger and we would have to explain why.

If there are no cons to letting this also work for logger filters, I think we should just do that, even if it doesn't enable any new functionality.

@vsajip
Copy link
Member

@vsajip vsajip commented May 10, 2022

No cons from my point of view. I was just thinking out loud 😄

@gpshead gpshead self-requested a review May 10, 2022
@gpshead
Copy link
Member

@gpshead gpshead commented May 10, 2022

The Azure pipelines failure suggests whitespace issues in a couple files. Try a make patchcheck

@adriangb
Copy link
Contributor Author

@adriangb adriangb commented May 10, 2022

Thank you @gpshead, I was wondering why that was failing

.. versionchanged:: 3.12
You can now return a :class:`LogRecord` instance from filters to replace
the log record without modifying it in place. This allows filters attached to
on a :class:`Handler` to modify the log record before it is emitted without
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attached to a handler, not attached to on a handler.

Copy link
Contributor Author

@adriangb adriangb May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you, corrected

Is the specified record to be logged? Returns falsy for no, truthy for
yes. Filters can either modify log records in-place or return a completely
different record instance which will replace the original
log record without modifying it.
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the without modifying it should be replaced by in any future processing of the event.

@@ -686,6 +687,12 @@ which has a ``filter`` method with the same semantics.
parameter. The returned value should conform to that returned by
:meth:`~Filter.filter`.

.. versionchanged:: 3.12
You can now return a :class:`LogRecord` instance from filters to replace
the log record without modifying it in place. This allows filters attached to
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without -> , rather than

@@ -0,0 +1,3 @@
Let :mod:`logging` filters to return a :class:`logging.LogRecord` instance
Copy link
Member

@vsajip vsajip May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still says Let ... to which is incorrect. Did you forget to make this change, which I suggested earlier?

Copy link
Contributor Author

@adriangb adriangb May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it looks like I missed that part of the comment, thank you for bringing it back up and for your patience

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants