HowTo:Python timedrotingfilehandle用于多个processinstance和文件?

2024-09-30 01:25:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我的新合同刚到期。当前系统使用python日志模块进行定时日志文件旋转。问题是作为守护进程运行的进程的日志文件被正确地旋转,而在完成时创建和销毁的进程实例的另一个日志文件没有旋转。永远不会。我现在必须找到解决这个问题的办法。在互联网和python文档上进行了两天的研究之后,我才刚刚从黑暗中走出来。由于我是日志模块的新手,我看不到问题的答案,因为我可能是闭着眼睛看的!你知道吗

该过程从以下内容开始:

python /admin/bin/fmlog.py -l 10 -f /tmp/fmlog/fmapp_log.log -d

其中:

-l 10 => DEBUG logging-level
-f ... => Filename to log to for app-instance 
-d => run as daemon

下面显示了我的代码经过大量编辑的版本:

#!/usr/bin python

from comp.app import app, yamlapp
...
from comp.utils.log4_new import *

# Exceptions handling class
class fmlogException(compException): pass

class fmlog(app):
    # Fmlog application class
    def __init__(self, key, config, **kwargs):
        # Initialise the required variables
        app.__init__(self, key, config, **kwargs)
        self._data = {'sid': self._id}
        ...

    def process(self, tid=None):
        if tid is not None:
            self.logd("Using thread '%d'." % (tid), data=self._data)

        # Run the fmlog process
        self.logi("Processing this '%s'" % (filename), data=self._data)
        ...

    def __doDone__(self, success='Failure', msg='', exception=None):
        ...
        self.logd("Process done!")

if __name__ == '__main__':
    def main():
        with yamlapp(filename=config, cls=fmlog, configcls=fmlogcfg, sections=sections, loglevel=loglevel, \
        logfile=logfile, excludekey='_dontrun', sortkey='_priority', usethreads=threads, maxthreads=max, \
        daemon=daemon, sleep=sleep) as a:
            a.run()

   main()

yamlapp进程(app的子类)被实例化并作为守护进程运行,直到手动停止。此进程将只创建一个或多个fmlog类实例,并在需要时(满足某些条件)调用process()函数。如果yamlapp进程在线程模式下运行,那么每个线程最多可以创建x个实例。你知道吗

应用程序进程代码:

#!/usr/bin/env python
...
from comp.utils.log4_new import *

class app(comp.base.comp, logconfig, log):
    def __init__(self, cls, **kwargs):
        self.__setdefault__('_configcls', configitem)
        self.__setdefault__('_daemon', True)
        self.__setdefault__('_maxthreads', 5) 
        self.__setdefault__('_usethreads', False)
        ...

        comp.base.comp.__init__(self, **kwargs)
        logconfig.__init__(self, prog(), **getlogkwargs(**kwargs))
        log.__init__(self, logid=prog())

    def __enter__(self):
        self.logi(msg="Starting application '%s:%s' '%d'..." % (self._cls.__name__, \
            self.__class__.__name__, os.getpid()))

        return self

    def ...

    def run(self):
        ...
        if self._usethreads:
            ...

        while True:
            self.logd(msg="Start of run iteration...")
            if not self._usethreads:
                while not self._q.empty():
                    item = self._q.get()
                    try:
                        item.process()

            self.logd(msg="End of run iteration...")
            time.sleep(self._sleep)

日志配置和设置是通过log4完成的_新建.py课程:

#!/usr/bin/env python

import logging
import logging.handlers
import re

class logconfig(comp):
    def __init__(self, logid, **kwargs):
        comp.__init__(self, **kwargs)
        self.__setdefault__('_logcount', 20)
        self.__setdefault__('_logdtformat', None)
        self.__setdefault__('_loglevel', DEBUG)
        self.__setdefault__('_logfile', None)
        self.__setdefault__('_logformat', '[%(asctime)-15s][%(levelname)5s] %(message)s')
        self.__setdefault__('_loginterval', 'S')
        self.__setdefault__('_logintervalnum', 30)
        self.__setdefault__('_logsuffix', '%Y%m%d%H%M%S')

        self._logid = logid
        self.__loginit__()

    def __loginit__(self):
        format = logging.Formatter(self._logformat, self._logdtformat)

        if self._logfile:
            hnd = logging.handlers.TimedRotatingFileHandler(self._logfile, when=self._loginterval, interval=self._logintervalnum, backupCount=self._logcount)
            hnd.suffix = self._logsuffix
            hnd.extMatch = re.compile(strftoregex(self._logsuffix))
        else:
            hnd = logging.StreamHandler()
        hnd.setFormatter(format)

        l = logging.getLogger(self._logid)
        for h in l.handlers:
            l.removeHandler(h)

        l.setLevel(self._loglevel)
        l.addHandler(hnd)

class log():
    def __init__(self, logid):
        self._logid = logid

    def __log__(self, msg, level=DEBUG, data=None):
        l = logging.getLogger(self._logid)
        l.log(level, msg, extra=data)

    def logd(self, msg, **kwargs):
        self.__log__(level=DEBUG, msg=msg, **kwargs)

    def ...

    def logf(self, msg, **kwargs):
        self.__log__(level=FATAL, msg=msg, **kwargs)

def getlogkwargs(**kwargs):
    logdict = {}
    for key, value in kwargs.iteritems():
        if key.startswith('log'): logdict[key] = value

    return logdict        

日志记录按预期完成:来自yamlapp(app的子类)的日志被写入fmapp_日志.log,并将fmlog中的日志写入fmlog.log日志. 问题是fmapp_日志.log按预期旋转,但是fmlog.log日志从不旋转。我该怎么解决这个问题?我知道这个过程必须连续运行才能发生旋转,这就是为什么只使用一个记录器的原因。我怀疑必须为fmlog进程创建另一个句柄,该句柄在进程退出时决不能被销毁。你知道吗

要求: app(framework或main)日志和fmlog(process)日志必须指向不同的文件。 两个日志文件必须进行时间轮换。你知道吗

希望有人能理解以上内容,并能给我一些建议。你知道吗


Tags: selflogappdata进程initloggingdef

热门问题