serhii.net

In the middle of the desert you can say anything you want

15 Sep 2022

Python logging filters

Documented worse than I’d like to.

Filters allow to do things to the records (structs that make up a log message later), be it change them in place or don’t let them pass.

You can pass a function in place of a Filter, it should:

  • get a logging.LogRecord
  • optionally change it in place
  • decide whether to let it pass
  • return 0 for no, non-zero for yes

The fields of a LogRecord are the same ones we name when doing formatting: name, lineno, msg and friends.

If your Filter tries to log something in a way that it’ll get filtered through it, you get recursion.

Sample of a filter that removes specific matches and gets added to a Handler:


def filter(record: logging.LogRecord) -> int:
	"""Filters away log records containing annoying stuff."""
	blacklist_condition = (
		(
			record.name == "lib_sdk.data"
			and "not available on your" in record.msg
		)
		or (
			record.name == "lib_sdk.data"
			and record.levelno == logging.WARNING
			and "which is legacy" in record.msg
		)
		or (
			record.name == "lib_sdk.data"
			and record.levelno == logging.WARNING
			and "created but without information" in record.msg
		)
	)
	if blacklist_condition:
		return 0
	else:
		return 1

sh = logging.StreamHandler()
sh.addFilter(filter)

Much better than what I had before (220914-2249 Python logging change level through context manager and operator magic).

One can go crazy here with regexes etc. but I shan’t.

Nel mezzo del deserto posso dire tutto quello che voglio.