2010-05-02 63 views
5

我想以这种方式配置我的Python记录器,以便记录器的每个实例都应该登录与记录器本身名称相同的文件。Python记录器动态文件名

例如为:

log_hm = logging.getLogger('healthmonitor') 
log_hm.info("Testing Log") # Should log to /some/path/healthmonitor.log 

log_sc = logging.getLogger('scripts') 
log_sc.debug("Testing Scripts") # Should log to /some/path/scripts.log 

log_cr = logging.getLogger('cron') 
log_cr.info("Testing cron") # Should log to /some/path/cron.log 

我想保留它通用的,不想硬编码的所有类型的记录器的名字,我可以有。那可能吗?

回答

7
import os 
import logging 

class MyFileHandler(object): 

    def __init__(self, dir, logger, handlerFactory, **kw): 
     kw['filename'] = os.path.join(dir, logger.name) 
     self._handler = handlerFactory(**kw) 

    def __getattr__(self, n): 
     if hasattr(self._handler, n): 
      return getattr(self._handler, n) 
     raise AttributeError, n 

logger = logging.getLogger('test') 
logger.setLevel(logging.INFO) 
handler = MyFileHandler(os.curdir, logger, logging.FileHandler) 
logger.addHandler(handler) 
logger.info('hello mylogger') 
+0

是否可以在“getLogger”调用之前添加处理程序,以便每次调用getLogger时都不必添加它? – sharjeel 2010-05-03 10:12:45

+1

@sharjeel:在初始化期间设置处理程序,以后所有对'getLogger()'的调用都不需要添加处理程序。解决方案与〜unutbu的类似。在那个例子中'myLogger'应该只被调用一次,否则你会产生奇怪的副作用。 – 2010-05-03 10:39:00

+0

我喜欢这种方法。您还可以跟踪打开的文件和新的实例,检查文件是否已经打开,然后不要重新打开。 虽然,在我的情况下,这种科学不是必需的:-) – sharjeel 2010-05-07 14:26:19

13

如何简单地包裹处理程序代码中的函数:

import os 
def myLogger(name): 
    logger = logging.getLogger(name) 
    logger.setLevel(logging.DEBUG) 
    handler = logging.FileHandler(os.path.join('/some/path/', name + '.log'), 'w') 
    logger.addHandler(handler) 
    return logger 

log_hm = myLogger('healthmonitor') 
log_hm.info("Testing Log") # Should log to /some/path/healthmonitor.log 
+1

这是一个可行的解决方案,但我正在寻找更多的Pythonic。 有没有办法利用现有的Python日志框架,而不是在其上添加包装? – sharjeel 2010-05-02 17:14:30

+0

这种方法存在问题。当使用相同名称多次调用时,它会添加重复处理程序。打开文件是写模式将消除以前的数据。 – 2017-09-11 23:02:25

+0

我的烤面包机也有问题,因为我每次烤面包两次,都不会像第一次烤面包一样。 :) – unutbu 2017-09-12 01:28:29

0

该方法在上述溶液中使用的是正确的,但有当调用多次添加重复处理的问题。这是改进版本。

import os 
def getLogger(name): 
    # logger.getLogger returns the cached logger when called multiple times 
    # logger.Logger created a new one every time and that avoids adding 
    # duplicate handlers 
    logger = logging.Logger(name) 
    logger.setLevel(logging.DEBUG) 
    handler = logging.FileHandler(os.path.join('/some/path/', name + '.log'), 'a') 
    logger.addHandler(handler) 
    return logger 

def test(i): 
    log_hm = getLogger('healthmonitor') 
    log_hm.info("Testing Log %s", i) # Should log to /some/path/healthmonitor.log 

test(1) 
test(2)