user2186862
user2186862

Reputation: 223

python - two logger objects with different levels and output streams

Programming language : Python 3.7

I'd like to set up two Python logger objects: one outputs to a file and another to sys.stdout.

Here's my code:

def get_custom_logger(name: str, debug: bool, fname: str = None) -> logging.Logger:
     level = logging.DEBUG if debug else logging.INFO
     if fname is not None:
        logging.basicConfig(filename=fname, filemode='a+', level=level)
    else:
        logging.basicConfig(level=level, stream=sys.stdout)
    return logging.getLogger(name=name)

def main():
    tlog_info = get_custom_logger(name='Test_Info_Stdout', debug=False)
    tlog_info.info('INFO message')
    tlog_info.debug('DEBUG message - will be recorded iff debug = True')
    print(tlog_info)
    #
    tlog_dbg = get_custom_logger(name='Test_Debug_FileStream', debug=True, fname='test.out')
    tlog_dbg.info('INFO message')
    tlog_dbg.debug('DEBUG message - will be recorded iff debug = True')
    print(tlog_dbg)

if __name__ == '__main__':
    main()

This doesn't work. It either

I've tried using the handlers argument to basicConfig:

    loghandler = logging.StreamHandler(sys.stdout) if fname is None else logging.FileHandler(fname, mode='a+')
    logging.basicConfig(level=level, stream=sys.stdout, handlers=[loghandler])

but I get the same result.

What gives?

And is there a cleaner, more pythonic way of doing this?

Note that I want to call get_custom_logger from various functions/classes of a larger code; some loggers will record to a file, others to the console.

Upvotes: 1

Views: 959

Answers (2)

Misslinska
Misslinska

Reputation: 92

One way around is to create a root logger and on the top of it add two loggers. Here you have longer explanation how to do it.

Upvotes: 0

Dipen Dadhaniya
Dipen Dadhaniya

Reputation: 4640

You should call basicConfig only once. Check this comment.

Alternatively you can do something like this:

def get_custom_logger(name, debug, fname= None):
    level = logging.DEBUG if debug else logging.INFO

    logger = logging.getLogger(name=name)

    if fname is not None:
        handler = logging.FileHandler(fname)
    else:
        handler = logging.StreamHandler(sys.stdout)

    logger.setLevel(level)
    handler.setLevel(level)
    logger.addHandler(handler)

    return logger

Upvotes: 3

Related Questions