Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Python logger class to generate multiple logs for different log levels

I looked through the tutorials for the python logging class here and didnt see anything that would let me make multiple logs of different levels for the same output. In the end I would like to have three logs: <timestamp>_DEBUG.log (debug level)
<timestamp>_INFO.log (info Level)
<timestamp>_ERROR.log (error level)

Is there a way to, in one script, generate multiple log files for the same input?

<-------------UPDATE #1-------------------------->
So in implementing @robert's suggestion, I now have a small issue, probably due to not fully understanding what is being done in his code.

Here is my code in scriptRun.py

import os
import logging

logger = logging.getLogger("exceptionsLogger")
debugLogFileHandler = logging.FileHandler("Debug.log")
errorLogFileHandler = logging.FileHandler("Error.Log")
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
errorLogFileHandler.setFormatter(formatter)
debugLogFileHandler.setFormatter(formatter)
logger.addHandler(debugLogFileHandler)
logger.addHandler(errorLogFileHandler)

class LevelFilter(logging.Filter):
    def __init__(self, level):
        self.level = level
    def filter(self, record):
        return record.levelno == self.level
debugLogFileHandler.addFilter(LevelFilter(logging.DEBUG))
errorLogFileHandler.addFilter(LevelFilter(logging.ERROR))

directory = []
for dirpath, dirnames, filenames in os.walk("path\to\scripts"):
    for filename in [f for f in filenames if f.endswith(".py")]:
        directory.append(os.path.join(dirpath, filename))
for entry in directory:
    execfile(entry)
    for lists in x:
        if lists[0] == 2:
            logger.error(lists[1]+"   "+lists[2])
        elif lists[0] == 1:
            logger.debug(lists[1]+"   "+lists[2])

an example of what this is running is:

import sys

def script2Test2():
    print y
def script2Ttest3():
    mundo="hungry"

global x 
x = []

theTests = (test2, test3)

for test in theTests:
    try:
        test()
        x.append([1,test.__name__," OK"])
    except:
        error = str(sys.exc_info()[1])
        x.append([2,test.__name__,error])

Now to my issue: running scriptRun.py does not throw any errors when i run it, and error.log and debug.log are created, but only error.log is populated with entries.

any idea why?

<------------------------Update #2----------------------->

So I realized that nothing is being logged that is "lower" than warning. even if i remove the filters and debugLogFileHandler.setLevel(logging.DEBUG) it does not seem to matter. If I set the actual log command to logger.warning or higher, it will print to the logs. Of course once I uncomment debugLogFileHandler.addFilter(LevelFilter(logging.DEBUG)) I get no log activity in Debug.log. I;m tempted to just make my own log level, but that seems like a really bad idea, in case anyone/anything else uses this code.

<-------------------------Final UPDATE--------------------->
Well I was stupid and forgot to set the logger itself to log DEBUG level events. Since by default the logging class doesn't log anything below warning, it wasnt logging any of the debug information I send it.

Final thanks and shoutout to @Robert for the filter.

like image 950
Snaxib Avatar asked Sep 16 '11 15:09

Snaxib


1 Answers

Create multiple Handlers, each for one output file (INFO.log, DEBUG.log etc.).

Add a filter to each handler that only allows the specific level.

For example:

import logging

# Set up loggers and handlers.
# ...

class LevelFilter(logging.Filter):
    def __init__(self, level):
        self.level = level

    def filter(self, record):
        return record.levelno == self.level

debugLogFileHandler.addFilter(LevelFilter(logging.DEBUG))
infoLogFileHandler.addFilter(LevelFilter(logging.INFO))
like image 162
robert Avatar answered Oct 11 '22 18:10

robert