7

I have the following code setting up the logger:

import logging

logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO)
log = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
log.addHandler(handler)

log.info('abc')

When I run it, I get output like:

2020-06-10 13:32:16,245 INFO: abc
abc

I presume the first one is the console output? How do I get rid of the duplicate one?

UPDATE

Thanks guys for the answers, now I know why I get duplicates, the reason I did it this way because the default stream handler does not output to stdout, so I googled and saw someone adding a stdout handler, hence I got 2 stream handlers (console and stdout).

I have now read again the documentation about the basicConfig() and I have worked out the easiest way to achieve what I want:

import sys
import logging

log = logging.getLogger(__name__)
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout)

log.info('abc')

1 Answer 1

1

This call to logging.basicConfig will already add a stream handler (to stderr), so there is no reason to add another stream handler manually. Doing so will cause duplicate output to the terminal, in your case each log event is printing on both stderr and stdout.

If you want the stream handler to stdout instead of stderr, just adjust the basicConfig call accordingly by specifying the stream or the handlers keywords (docs).

There are two other things you could clean up: use a logger bound to the module __name__ context rather than using the root logger directly, and avoid to configure the logging module at import time. If you configure the logging system too eagerly at import time, then the user (and the test suite) is no longer able to configure it differently.

import logging

# create your logger as module level global
log = logging.getLogger(__name__)

def main():
    # configure logging at entry point (so it is not configured at *import* time)
    fmt = '%(asctime)s %(levelname)s: %(message)s'
    logging.basicConfig(format=fmt, level=logging.INFO)  # streamhandler to stderr
    log.info('abc')


if __name__ == "__main__":
    main()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.