首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Python日志中使用不同的类和导入动态更改文件句柄

如何在Python日志中使用不同的类和导入动态更改文件句柄
EN

Stack Overflow用户
提问于 2012-12-12 20:14:03
回答 3查看 47.2K关注 0票数 60

我不能执行动态日志记录fileHandle更改。

例如,我有3个班级

one.py

代码语言:javascript
复制
import logging
class One():
    def __init__(self,txt="?"):
        logging.debug("Hey, I'm the class One and I say: %s" % txt)

two.py

代码语言:javascript
复制
import logging
class Two():
    def __init__(self,txt="?"):
        logging.debug("Hey, I'm the class Two and I say: %s" % txt)

config.py

代码语言:javascript
复制
import logging
class Config():
    def __init__(self,logfile=None):
        logging.debug("Reading config")
        self.logfile(logfile)

myapp

代码语言:javascript
复制
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")

如果我再次尝试loggin.basicConfig(),它不起作用。

EN

回答 3

Stack Overflow用户

发布于 2017-11-23 12:13:30

@Martijn提供的答案运行良好。但是,代码截取程序会移除所有处理程序,只放回文件处理程序。如果您的应用程序有由其他模块添加的处理程序,这将会很麻烦。

因此,下面的代码片段被设计成只替换文件处理程序。

if isinstance(hdlr,logging.FileHandler)这一行是关键。

代码语言:javascript
复制
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)
票数 14
EN

Stack Overflow用户

发布于 2016-02-01 05:59:54

我找到了一种比上面的“接受”答案更简单的方法。如果有对处理程序的引用,则只需调用close()方法,然后设置baseFilename属性。在分配baseFilename时,请确保使用os.path.abspath()。在库源代码中有一个注释,表明它是必需的。我将我的配置内容保存在全局dict()中,这样很容易保存FileHandler引用对象。如下所示,只需要两行代码就可以动态更改处理程序的日志文件名。

代码语言:javascript
复制
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
票数 9
EN

Stack Overflow用户

发布于 2019-01-24 06:08:43

我试着结合@Arun Thundyill Saseendran来实现@Martijn在这个页面上的建议。我太新了,不允许发表评论,所以我必须发布一个调整后的答案。在isinstance调用中,我必须使用'logging‘而不是'log’来访问类型(log是一个实例),然后'FileHander‘应该是'FileHandler’。我使用的是Python 3.6。

代码语言:javascript
复制
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)      
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13839554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档