1

Suppose I have got a logger like:

logger = logging.getLogger(__name__)

Then I add a file handler to it. I want all logs go to the file and all info and above log to be printed on screen.

I know I should set the level of the file handler to logging.INFO.

However, if I use logger.setLevel(logging.INFO), then the debug logs won't go to the file. If I use logger.setLevel(logging.DEBUG), then all debug logs will be printed on screen.

How to solve this problem?

dspjm
  • 5,473
  • 6
  • 41
  • 62
  • http://stackoverflow.com/questions/35135401/unexpected-python-logger-output-when-using-several-handlers-with-different-log-l/35136229#35136229 – Padraic Cunningham Mar 26 '16 at 10:12

1 Answers1

2

You should use logger.setLevel(logging.DEBUG) on the logger and handler.setLevel(logging.INFO) on the screen handler. That way the logger gets all messages, the file handler gets all messages but the screen or stream handler gets only INFO or higher.

Bharel
  • 23,672
  • 5
  • 40
  • 80
  • How to get the screen handler, looks like it is going to be configured through logging.basicConfig() – dspjm Mar 26 '16 at 10:05
  • @dspjm Don't use `logging.basicConfig()` then and set your own `StreamHandler()` or set the level to `logging.INFO` like this: `logging.basicConfig(level=logging.INFO)`. – Bharel Mar 26 '16 at 10:09
  • You can retrieve a list of handlers associated with your logger using `logger.handlers` – Brandon E Taylor Mar 26 '16 at 10:18
  • @Brandon bad idea mate, it's not safe. There's a reason it's not documented. – Bharel Mar 26 '16 at 10:19
  • @Bharel Good to know. Thank you. – Brandon E Taylor Mar 26 '16 at 10:20
  • 1
    @Brandon yeah, the main concern is the fact that logging is a thread safe library and it can mess up the locks. Other problems may include stream flushing and buffering. It's better that he won't initialize a root logger at all or at least initialize it in the proper level instead of initializing and then modifying. – Bharel Mar 26 '16 at 10:24
  • @Bharel looks like the best way is to setup my own StreamHandler(), however, I didn't choose this method at the beginning was because I have called the basicConifg() at the beginning of the program. So I don't know under these kind of circumstances, is there still a way to work around. – dspjm Mar 26 '16 at 10:52
  • 1
    @dspjm You may create a new logger with your own `StreamHandler()` and `FileHandler()` and set [`logger.propagate = False`](https://docs.python.org/3/library/logging.html#logging.Logger.propagate) if you can't change `basicConfig`. – Bharel Mar 26 '16 at 11:01