Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to change the filemode for a logger object that is not configured using basicConfig?

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
like image 818
Xivilai Avatar asked Mar 16 '15 21:03

Xivilai


People also ask

How do you overwrite a log in Python?

The filemode can be changed to write mode, which will overwrite the previous logs and only save the current ones. Since the filemode is set to w , this means that the log file will be opened in write mode each time basicConfig() is run, which will ultimately overwrite the file.

How do I create a multiple logging level in Python?

You can set a different logging level for each logging handler but it seems you will have to set the logger's level to the "lowest". In the example below I set the logger to DEBUG, the stream handler to INFO and the TimedRotatingFileHandler to DEBUG. So the file has DEBUG entries and the stream outputs only INFO.

What is logging getLogger (__ Name __?

logger = logging.getLogger(__name__) This means that logger names track the package/module hierarchy, and it's intuitively obvious where events are logged just from the logger name. Sounds like good advice.

How do I set the default logger format in basicconfig?

The default setting in basicConfig () is to set the logger to write to the console in the following format: While you can pass any variable that can be represented as a string from your program as a message to your logs, there are some basic elements that are already a part of the LogRecord and can be easily added to the output format.

What is a filemode parameter?

A FileMode parameter is specified in many of the constructors for FileStream, IsolatedStorageFileStream, and in the Open methods of File and FileInfo to control how a file is opened. FileMode parameters control whether a file is overwritten, created, opened, or some combination thereof. Use Open to open an existing file.

What is the default configuration for the root log file?

The filemode is set to w, which means the log file is opened in “write mode” each time basicConfig () is called, and each run of the program will rewrite the file. The default configuration for filemode is a, which is append. You can customize the root logger even further by using more parameters for basicConfig (), which can be found here.

How to set the default level of logging for a class?

The default is a, which means append. format: This is the format of the log message. By using the level parameter, you can set what level of log messages you want to record. This can be done by passing one of the constants available in the class, and this would enable all logging calls at or above that level to be logged.


Video Answer


1 Answers

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.

like image 191
jedwards Avatar answered Oct 08 '22 10:10

jedwards