我有一个Python 3.4应用程序,它广泛使用日志记录。我有两个FileHandler和一个StreamHandler注册。一切都按预期工作,除了有时,似乎在requests
库抛出异常后发生,日志文件丢失所有累积的消息并从新消息开始。我假设由于某种原因,FileHandler使用mode='w'
重新打开了文件,但我不明白为什么。有什么想法吗?
主程序按如下方式设置记录器:
# Set up root logger - two handlers logging to files
fh_debug = logging.FileHandler('Syncer.debug', mode='w', encoding='utf-8')
fh_debug.setLevel(logging.DEBUG)
fh_log = logging.FileHandler('Syncer.log', mode='w', encoding='utf-8')
fh_log.setLevel(logging.INFO)
fh_formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
fh_debug.setFormatter(fh_formatter)
fh_log.setFormatter(fh_formatter)
logging.getLogger().addHandler(fh_debug)
logging.getLogger().addHandler(fh_log)
# Add console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch_formatter = logging.Formatter('%(message)s')
ch.setFormatter(ch_formatter)
logging.getLogger().addHandler(ch)
# Need to set the logging level of the logger as well as the handlers
logging.getLogger().setLevel(logging.DEBUG)
# Set up the logger for this module
logger = logging.getLogger("Syncer")
logger.debug('Logger started.')
模块只包含
logger = logging.getLogger(__name__)
答案 0 :(得分:0)
您的问题是您为mode
选择了错误的FileHandler
。
默认模式FileHandler
为a
,这意味着将新行添加到日志文件中。
class logging.FileHandler(filename,mode =' a',encoding = None,delay = False)
您将默认模式修改为w
,将文件截断为零长度或创建新文件进行写入。这就是你丢失所有累积消息的原因。
将其更改为mode='a'
或只删除mode='w'
,然后您的记录器即可使用。
答案 1 :(得分:0)
发生这种情况会导致Python退出,因为logging
模块被(部分)关闭,导致日志文件被关闭,但是requests
试图记录某些内容,因此记录器会重新打开日志文件-不幸的是,将其截断。
class FileHandler(StreamHandler):
# [...]
def close(self):
# [...]
self.stream = None
# [...]
def _open(self):
return open(self.baseFilename, self.mode, encoding=self.encoding,
errors=self.errors)
def emit(self, record):
if self.stream is None:
self.stream = self._open()
StreamHandler.emit(self, record)
我认为最简单的解决方法是在程序启动时截断日志文件,并告诉logging
以追加模式打开文件:
open('Syncer.debug', mode='w').close() # truncate
fh_debug = logging.FileHandler('Syncer.debug', mode='a', encoding='utf-8')
fh_debug.setLevel(logging.DEBUG)
open('Syncer.log', mode='w').close() # truncate
fh_log = logging.FileHandler('Syncer.log', mode='a', encoding='utf-8')
fh_log.setLevel(logging.INFO)