xki*_*ill 42 python configuration logging
我无法执行即时记录文件手柄更改.
例如,我有3个班级
one.py
import logging
class One():
def __init__(self,txt="?"):
logging.debug("Hey, I'm the class One and I say: %s" % txt)
Run Code Online (Sandbox Code Playgroud)
two.py
import logging
class Two():
def __init__(self,txt="?"):
logging.debug("Hey, I'm the class Two and I say: %s" % txt)
Run Code Online (Sandbox Code Playgroud)
config.py
import logging
class Config():
def __init__(self,logfile=None):
logging.debug("Reading config")
self.logfile(logfile)
Run Code Online (Sandbox Code Playgroud)
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")
Run Code Online (Sandbox Code Playgroud)
如果我再试loggin.basicConfig()一次,它就不起作用了.
Mar*_*ers 57
事实上,logging.basicConfig做什么,如果处理程序已经成立已:
如果根记录器已经为其配置了处理程序,则此函数不执行任何操作.
您需要替换根记录器上的当前处理程序:
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
Run Code Online (Sandbox Code Playgroud)
请参阅Python Logging HOWTO中的" 配置日志记录"一章.
小智 7
我找到了一种比上面"接受"的答案更简单的方法.如果您有对处理程序的引用,那么您需要做的就是调用close()方法然后设置baseFilename属性.分配baseFilename时,请务必使用os.path.abspath().库源中有一条注释表明它是必需的.我将配置内容保存在全局dict()中,因此很容易保留FileHandler引用对象.正如您在下面所看到的,它只需要2行代码即可动态更改处理程序的日志文件名.
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
Run Code Online (Sandbox Code Playgroud)
我尝试结合 @Martijn Pieters 和 @Arun Thundyill Saseendran 实施此页面上的建议。我太新了,无法发表评论,所以我必须发布调整后的答案。在 isinstance 调用中,我必须使用“logging”而不是“log”来访问类型(log 是一个实例),然后“FileHander”应该是“FileHandler”。我正在使用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)
Run Code Online (Sandbox Code Playgroud)
@Martijn Pieters提供的答案很好。但是,代码截取器将删除所有处理程序,而仅将文件处理程序放回原处。如果您的应用程序具有其他模块添加的处理程序,这将很麻烦。
因此,下面的代码段被设计为仅替换文件处理程序。
线if isinstance(hdlr,log.FileHander)是关键。
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26916 次 |
| 最近记录: |