1

What I'm trying to achieve is the following:

If I run this code:

import logging
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

I want only the messages "error" and "critical" to go to stderr. Right now "warning" - "critical" all go to stderr.

So I tried creating my own custom logging config:

logconfig_dict = {
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "stream": "ext://sys.stdout",
        },
        "error_console": {
            "class": "logging.StreamHandler",
            "level": "ERROR",
            "stream": "ext://sys.stderr",
        },
    },
    "root": {"level": "DEBUG", "handlers": ["console", "error_console"]},
    "version": 1,
}

import logging
from logging.config import dictConfig

logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
dictConfig(logconfig_dict)
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

When this runs all five logs to to stdout. "error" and "critical" are also sent to stderr.

Given the above, I just need "error" and "critical" to stop going to stdout.

It seems like this should be done easily but selecting a range for what log levels you want to go to a handler but I'm not seeing that functionality mentioned in the docs.

martineau
  • 119,623
  • 25
  • 170
  • 301
RayB
  • 2,096
  • 3
  • 24
  • 42

1 Answers1

0

Turns out it is quit easy when using a filter as Dan suggested.

Basically you can do something like this to filter out logs above a certain level:

def noErrorLogs():
    return lambda param: 0 if param.levelno < 40 else 1


logconfig_dict = {
    "filters": {
        "myfilter": {
            "()": noErrorLogs,
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "stream": "ext://sys.stdout",
            "filters": ["myfilter"],
        }
    },
    "root": {"level": "DEBUG", "handlers": ["console"]},
    "version": 1,
}

For details on why the function being used to filter is returning a lambda see this: https://stackoverflow.com/a/64165049/620699

RayB
  • 2,096
  • 3
  • 24
  • 42