I cannot perform an on-the-fly logging fileHandle change.
For example, I have 3 classes
one.py
import logging class One(): def __init__(self,txt="?"): logging.debug("Hey, I'm the class One and I say: %s" % txt)
two.py
import logging class Two(): def __init__(self,txt="?"): logging.debug("Hey, I'm the class Two and I say: %s" % txt)
config.py
import logging class Config(): def __init__(self,logfile=None): logging.debug("Reading config") self.logfile(logfile)
myapp
from one import One from two import Two from config import Config import logging #Set default logging logging.basicConfig( level=logging.getLevelName(DEBUG), format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', filename=None ) logging.info("Starting with stdout") o=One(txt="STDOUT") c=Config(logfile="/tmp/logfile") # Here must be the code that change the logging configuration and set the filehandler t=One(txt="This must be on the file, not STDOUT")
If I try loggin.basicConfig()
again, it doesn't work.
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.
Indeed, logging.basicConfig
does nothing if a handler has been set up already:
This function does nothing if the root logger already has handlers configured for it.
You'll need to replace the current handler on the root logger:
import logging fileh = logging.FileHandler('/tmp/logfile', 'a') formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fileh.setFormatter(formatter) log = logging.getLogger() # root logger for hdlr in log.handlers[:]: # remove all old handlers log.removeHandler(hdlr) log.addHandler(fileh) # set the new handler
See the Configuring Logging chapter in the Python Logging HOWTO.
The answer provided by @Martijn Pieters works good. However, the code snipper removes all handlers and placed only the file handler back. This will be troublesome if your application has handlers added by other modules.
Hence, the below snippet is designed in such a way to replace only the file handler.
The line if isinstance(hdlr,logging.FileHandler)
is the key.
import logging filehandler = logging.FileHandler('/tmp/logfile', 'a') formatter = logging.Formatter('%(asctime)-15s::%(levelname)s::%(filename)s::%(funcName)s::%(lineno)d::%(message)s') filehandler.setFormatter(formatter) log = logging.getLogger() # root logger - Good to get it only once. for hdlr in log.handlers[:]: # remove the existing file handlers if isinstance(hdlr,logging.FileHandler): log.removeHandler(hdlr) log.addHandler(filehandler) # set the new handler # set the log level to INFO, DEBUG as the default is ERROR log.setLevel(logging.DEBUG)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With