Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-92592: Allow logging filters to return a LogRecord. (GH-92591)#92591

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
vsajip merged 18 commits intopython:mainfromadriangb:logging-filters
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
18 commits
Select commitHold shift + click to select a range
3aeeba6
allow logging filters to return a LogRecord
adriangbMay 10, 2022
1e4d27f
edit docstring
adriangbMay 10, 2022
b526a35
remove unecessary __bool__ impl
adriangbMay 10, 2022
f1ea183
edit docs
adriangbMay 10, 2022
19561d3
Add docs and blurb
adriangbMay 10, 2022
14e704d
Merge branch 'main' into logging-filters
adriangbMay 10, 2022
4d34540
fix rst
adriangbMay 10, 2022
a69e76a
touch up wording
adriangbMay 10, 2022
67453f6
add test for filters on loggers
adriangbMay 10, 2022
b1e1084
push straggler change
adriangbMay 10, 2022
f72c594
Merge branch 'main' into logging-filters
adriangbMay 10, 2022
225329f
pr feedback
adriangbMay 10, 2022
735d78a
Merge branch 'logging-filters' of https://github.com/adriangb/cpython…
adriangbMay 10, 2022
5e54c77
Merge branch 'main' into logging-filters
adriangbMay 10, 2022
f52e404
fix whitespace
adriangbMay 10, 2022
46e2f7f
fix docs as per pr feedback
adriangbMay 10, 2022
7a0f470
Update logging-cookbook.rst
vsajipJun 7, 2022
643551d
Update logging.rst
vsajipJun 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
allow logging filters to return a LogRecord
  • Loading branch information
@adriangb
adriangb committedMay 10, 2022
commit3aeeba6ed13eda4b895d8a531cf320768f5dc030
38 changes: 30 additions & 8 deletionsLib/logging/__init__.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,9 @@ def __repr__(self):
return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
self.pathname, self.lineno, self.msg)

def __bool__(self):
return True

def getMessage(self):
"""
Return the message for this LogRecord.
Expand DownExpand Up@@ -811,23 +814,34 @@ def filter(self, record):
Determine if a record is loggable by consulting all the filters.

The default is to allow the record to be logged; any filter can veto
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

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
ContributorAuthor

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 theFilterer.filter function. The main difference is that filters may return a truthy value that is not a log record butFilterer.filter will now always return a log record (or falsy). I reworded it a bit to make these two different paragraphs.

Filters can return a log record, which case that log record
Copy link
Member

Choose a reason for hiding this comment

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

Change sentences toIf 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.

adriangb reacted with thumbs up emoji
Copy link
ContributorAuthor

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

is used to call the next filter.
If filters return a truthy value that is not a log record the
next filter is called with the existing log record.

If none of the filters return falsy values, this method returns
a log record.

.. versionchanged:: 3.2

Allow filters to be just callables.

.. versionchanged:: 3.12
Allow filters to return a LogRecord instead of
modifying it in place.
"""
rv = True
for f in self.filters:
if hasattr(f, 'filter'):
result = f.filter(record)
else:
result = f(record) # assume callable - will raise if not
if not result:
rv = False
break
return rv
return False
if isinstance(result, LogRecord):
record = result
return record

#---------------------------------------------------------------------------
# Handler classes and functions
Expand DownExpand Up@@ -966,6 +980,8 @@ def handle(self, record):
emission.
"""
rv = self.filter(record)
if isinstance(rv, LogRecord):
record = rv
if rv:
self.acquire()
try:
Expand DownExpand Up@@ -1634,8 +1650,14 @@ def handle(self, record):
This method is used for unpickled records received from a socket, as
well as those created locally. Logger-level filtering is applied.
"""
if (not self.disabled) and self.filter(record):
self.callHandlers(record)
if self.disabled:
return
maybe_record = self.filter(record)
if not maybe_record:
return
if isinstance(maybe_record, LogRecord):
record = maybe_record
self.callHandlers(record)

def addHandler(self, hdlr):
"""
Expand Down
34 changes: 34 additions & 0 deletionsLib/test/test_logging.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -466,6 +466,40 @@ 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

Choose a reason for hiding this comment

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

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

adriangb reacted with thumbs up emoji
name=record.name,
level=record.levelno,
pathname=record.pathname,
lineno=record.lineno,
msg="new message!",
exc_info=record.exc_info,
args=(),
)

# Set up a logging hierarchy such that "child" and it's handler
# (and thus `replace_message()`) always get called before
# propagating up to "parent".
# Then we can confirm that `replace_message()` was able to
# replace the log record without having a side effect on
# other loggers or handlers.
parent = logging.getLogger("parent")
child = logging.getLogger("parent.child")
stream_1 = io.StringIO()
stream_2 = io.StringIO()
handler_1 = logging.StreamHandler(stream_1)
handler_2 = logging.StreamHandler(stream_2)
handler_2.addFilter(replace_message)
parent.addHandler(handler_1)
child.addHandler(handler_2)

child.info("original message")
handler_1.flush()
handler_2.flush()
self.assertEqual(stream_1.getvalue(), "original message\n")
self.assertEqual(stream_2.getvalue(), "new message!\n")

def test_logger_filter(self):
# Filter at logger level.
self.root_logger.setLevel(VERBOSE)
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp