Je ne peux pas effectuer de changement de fileHandle de journalisation à la volée.
Par exemple, j'ai 3 cours
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")
Si j'essaie à nouveau loggin.basicConfig()
, cela ne fonctionne pas.
En effet, logging.basicConfig
ne fait rien si un gestionnaire a déjà été configuré:
Cette fonction ne fait rien si le logger racine a déjà des gestionnaires configurés pour elle.
Vous aurez besoin de remplacer le gestionnaire actuel sur le logger racine:
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
Reportez-vous au chapitre Configuration de la journalisation dans le HOWTO Python Logging.
J'ai trouvé un moyen plus facile que la réponse «acceptée» ci-dessus. Si vous avez une référence au gestionnaire, il vous suffit d'appeler la méthode close (), puis de définir la propriété baseFilename. Lorsque vous associez baseFilename, veillez à utiliser os.path.abspath (). Il y a un commentaire dans la source de la bibliothèque qui indique que c'est nécessaire. Je garde mes informations de configuration dans un dict global (), il est donc facile de conserver les objets de référence FileHandler. Comme vous pouvez le voir ci-dessous, il ne faut que 2 lignes de code pour modifier le nom du fichier journal d'un gestionnaire à la volée.
import logging
def setup_logging():
global config
if config['LOGGING_SET']:
config['LOG_FILE_HDL'].close()
config['LOG_FILE_HDL'].baseFilename = os.path.abspath(config['LOG_FILE'])
config['DEBUG_LOG_HDL'].close()
config['DEBUG_LOG_HDL'].baseFilename = os.path.abspath(config['DEBUG_LOG'])
else:
format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(format_str)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# add file mode="w" to overwrite
config['LOG_FILE_HDL'] = logging.FileHandler(config['LOG_FILE'], mode='a')
config['LOG_FILE_HDL'].setLevel(logging.INFO)
config['LOG_FILE_HDL'].setFormatter(formatter)
log.addHandler(config['LOG_FILE_HDL'])
# the delay=1 should prevent the file from being opened until used.
config['DEBUG_LOG_HDL'] = logging.FileHandler(config['DEBUG_LOG'], mode='a', delay=1)
config['DEBUG_LOG_HDL'].setLevel(logging.DEBUG)
config['DEBUG_LOG_HDL'].setFormatter(formatter)
log.addHandler(config['DEBUG_LOG_HDL'])
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
log.addHandler(ch)
config['LOGGING_SET'] = True
La réponse fournie par @Martijn Pieters fonctionne bien. Toutefois, le coupeur de code supprime tous les gestionnaires et ne place que le gestionnaire de fichiers. Ce sera gênant si votre application a des gestionnaires ajoutés par d'autres modules.
Ainsi, l'extrait de code ci-dessous est conçu de manière à ne remplacer que le gestionnaire de fichiers.
La ligne if isinstance(hdlr,log.FileHander)
est la clé.
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,log.FileHander):
log.removeHandler(hdlr)
log.addHandler(filehandler) # set the new handler
# set the log level to INFO, DEBUG as the default is ERROR
logging.setLevel(log.DEBUG)
J'ai essayé de mettre en œuvre les suggestions sur cette page de @Martijn Pieters combinées avec @Arun Thundyill Saseendran. Je suis trop nouvelle pour pouvoir faire un commentaire et je dois donc poster une réponse corrigée. Dans l'appel isinstance, je devais utiliser "logging" au lieu de "log" pour accéder aux types (log était une instance), puis "FileHander" devait être "FileHandler". J'utilise Python 3.6.
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): #fixed two typos here
log.removeHandler(hdlr)
log.addHandler(filehandler) # set the new handler
# set the log level to INFO, DEBUG as the default is ERROR
logging.setLevel(log.DEBUG)