我的新合同让我陷入了沉重的境地。当前系统使用python日志记录模块进行定时日志文件轮换。问题是作为守护程序运行的进程的日志文件是否正确旋转,而完成时创建和销毁的进程实例的另一个日志文件不会旋转。永远。我现在必须找到解决这个问题的方法。在对互联网和python文档进行了2天的研究之后,我只有一半在黑暗中。由于我是记录模块的新手,因此我无法看到问题的答案,因为我可能闭着眼睛看着它!
该过程以:
开始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_new.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.log,fmlog的日志写入fmlog.log。 问题是fmapp_log.log按预期旋转,但fmlog.log永远不会旋转。我该如何解决这个问题?我知道进程必须连续运行才能进行旋转,这就是为什么只使用一个记录器的原因。我怀疑必须为fmlog进程创建另一个句柄,当进程退出时,它必须永远不会被销毁。
要求: 应用程序(框架或主要)日志和fmlog(进程)日志必须是不同的文件。 两个日志文件都必须按时间旋转。
希望有人能理解上述内容,并能给我一些指示。