简体   繁体   中英

Unable to set different logging levels for two logging handlers in python

As described in python's logging cookbook , I want to display logging.INFO on the console, while simultaneously writing logging.WARNING to a log file.

However, I see logging.INFO on the console as well as in the log file when using this code:

import logging

def initialize_logger():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)         # <--- ADDING THIS LINE SOLVED IT
    fh = logging.FileHandler('error.log') # create file handler which logs WARNING
    fh.setLevel(logging.WARNING)
    ch = logging.StreamHandler()          # create console handler which logs INFO
    ch.setLevel(logging.INFO)
    formatter = logging.Formatter('%(name)s - %(message)s') # create formatter
    ch.setFormatter(formatter)            # add formatter to handlers
    fh.setFormatter(formatter)            # add formatter to handlers
    logger.addHandler(ch)                 # add the handlers to logger
    logger.addHandler(fh)                 # add the handlers to logger
    return logger

logger = initialize_logger()

Why do I see the same logging level for FileHandler and StreamHandler ?

How to properly set different logging levels for two simultaneously running handlers?


EDIT: added colon after function definition

Okay, to answer your first question,

Logger objects have a threefold job. First, they expose several methods to application code so that applications can log messages at runtime. Second, logger objects determine which log messages to act upon based upon severity (the default filtering facility) or filter objects. Third, logger objects pass along relevant log messages to all interested log handlers.

So in your application, you need that some level messages get logged to a file, and some are displayed on console. So to do that, you would first need to create a logger object, specify the lowest severity (ie. the default filtering facility as mentioned in doc above) that will be dispatched to the appropriate destination (ie. first to the handler, then right handlers' destination).

It is like you are saying to the logger object, your handlers will be handling log messages only above this level. In case you do not specify it, or you give a level above which the handlers are going to dispatch, then that log message may not be dispatched to the handler because the logger object did not receive it in the first place. Make sense?

So that means if you are going to be using handlers , you are required to setLevel() for logger first, since that is the initial filter/point where the log messages are dispatched to. Later, the logger dispatches it to respective handlers .

For your next question,

I ran your code after adding the following lines at the bottom:

logger.debug('Quick zephyrs blow, vexing daft Jim.')
logger.info('How quickly daft jumping zebras vex.')
logger.warning('Jail zesty vixen who grabbed pay from quack.')
logger.error('The five boxing wizards jump quickly.')

and I am getting the last three (from logger.info() ) in my console and the last two (from logger.warning() ) in my file at temp/error.log . This is the expected correct behavior. So I am not getting the error here.

Are you sure you are adding the logger.setLevel(logging.INFO) at the beginning? If you don't, then you will get the same level for both file and console. Do check that and let me know. Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM