18

If I create a logger object by using logger = logging.getLogger("Name") I am unable to change the filemode from append('a') to write ('w'). I can if I use the root logger with basicConfig, but then I get a lot of system debug messages being logged when all I want is my own messages beginning at the DEBUG level.

I am hoping to either (1) change the filemode for my own logger object to 'w' or (2) add a filter to the root logger. Is it even possible to filter out these debug messages from the root logger?

def create_log():
    # create logger for "Sample App"
    logger = logging.getLogger('automated_testing')
    logger.setLevel(logging.DEBUG)

    # create file handler which logs even debug messages
    fh = logging.FileHandler('results.log')
    fh.setLevel(logging.DEBUG)
    # create console handler with a higher log level
    ch = logging.StreamHandler(stream=sys.stdout)
    ch.setLevel(logging.DEBUG)
    # create formatter and add it to the handlers
    formatter = logging.Formatter('[%(asctime)s] %(levelname)8s --- %(message)s ' +
                                  '(%(filename)s:%(lineno)s)',datefmt='%Y-%m-%d %H:%M:%S')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    # add the handlers to the logger
    logger.addHandler(ch)
    logger.addHandler(fh)

    return logger
nimig
  • 155
  • 1
  • 11
Xivilai
  • 2,481
  • 3
  • 15
  • 15
  • 4
    To set the mode of your "own" `FileHandler` you can use the `mode` keyword argument `FileHandler(filename, mode='w')` - [docs](https://docs.python.org/2/library/logging.handlers.html#filehandler) – jedwards Mar 16 '15 at 21:42

1 Answers1

27

Something like:

import sys
import logging

def create_logger():
    # create logger for "Sample App"
    logger = logging.getLogger('automated_testing')
    logger.setLevel(logging.DEBUG)

    # create file handler which logs even debug messages
    fh = logging.FileHandler('results.log', mode='w')
    fh.setLevel(logging.DEBUG)

    # create console handler with a higher log level
    ch = logging.StreamHandler(stream=sys.stdout)
    ch.setLevel(logging.INFO)

    # create formatter and add it to the handlers
    formatter = logging.Formatter('[%(asctime)s] %(levelname)8s --- %(message)s ' +
                                  '(%(filename)s:%(lineno)s)',datefmt='%Y-%m-%d %H:%M:%S')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)

    # add the handlers to the logger
    logger.addHandler(ch)
    logger.addHandler(fh)

    return logger

logger = create_logger()


logger.log(logging.NOTSET,   "NOTSET   Message - 0")
logger.log(logging.DEBUG,    "DEBUG    Message - 10")
logger.log(logging.INFO,     "INFO     Message - 20")
logger.log(logging.WARNING,  "WARNING  Message - 30")
logger.log(logging.CRITICAL, "CRITICAL Message - 40")

Prints to stdout:

[2015-03-16 17:51:08]     INFO --- INFO     Message - 20 (temp3.py:34)
[2015-03-16 17:51:08]  WARNING --- WARNING  Message - 30 (temp3.py:35)
[2015-03-16 17:51:08] CRITICAL --- CRITICAL Message - 40 (temp3.py:36)

Writes (not appends) to results.log:

[2015-03-16 17:51:08]    DEBUG --- DEBUG    Message - 10 (temp3.py:33)
[2015-03-16 17:51:08]     INFO --- INFO     Message - 20 (temp3.py:34)
[2015-03-16 17:51:08]  WARNING --- WARNING  Message - 30 (temp3.py:35)
[2015-03-16 17:51:08] CRITICAL --- CRITICAL Message - 40 (temp3.py:36)

DEBUG+ are logged in results.txt while only INFO+ are send to stdout.

Note that the NOTSET log entry is passed up to the root logger then, since you don't have any handlers on the root logger, discarded.

jedwards
  • 29,432
  • 3
  • 65
  • 92