我正在 Python 中迈出第一步,并且已经到了需要一个日志记录模块的地步。我没有选择旋转文件处理程序的原因是:
- 我希望每次运行代码时都创建一个新文件夹,以托管新的日志文件。
- 使用常规文件名(
myName_X.log
,而不是默认文件名myName.log.X
)。 - 按行数限制日志文件,而不是文件大小(由旋转文件处理程序完成)。
我已经编写了这样一个模块,使用 Python 的内置日志模块,但我有两个问题:
- 创建新文件夹和文件,并将记录数据打印到文件中。但是,当
main()
第二次运行时(见下面的代码),新创建的文件被锁定,除非我关闭 IDE 或通过 Process Explorer 释放锁定,否则无法从文件资源管理器中删除。 - IPython 解释器在我第二次运行时冻结
main()
。如果我尝试该pdb
模块,它也会冻结。
我正在使用 WinPython 3.3.5(带有 Spyder 2.3.0beta)。我花了几个小时试图找到解决这个问题的方法。我不知道这是我的代码中的问题还是 Spyder 的错误。
一般的编码评论总是受欢迎的。
main_example.py:
import myLogging
def main():
try:
myLoggerInstance = myLogging.MyLogger()
# Do stuff...
# logging example
for i in range(0, 3):
msg = 'Jose Halapeno on a stick {0}'.format(i)
myLoggerInstance.WriteLog('DEBUG', msg)
print('end of prints...')
finally:
myLoggerInstance._closeFileHandler()
print('closed file handle...')
if __name__ == "__main__":
main()
myLogging.py:
import logging
import time
import os
class MyLogger:
_linesCounter = 0
_nNumOfLinesPerFile = 100000
_fileCounter = 0
_dirnameBase = os.path.dirname(os.path.abspath(__file__))
_dirname = ''
_filenameBase = 'logfile_{0}.log'
_logger = logging.getLogger('innerGnnLogger')
_severityDict = {'CRITICAL' : logging.CRITICAL, 'ERROR': logging.ERROR, 'WARNING':
logging.WARNING, 'INFO': logging.INFO, 'DEBUG': logging.DEBUG}
@staticmethod
def __init__():
# remove file handle
MyLogger._closeFileHandler()
# create folder for session
MyLogger._dirname = MyLogger._dirnameBase + time.strftime("\\logs_%Y_%m_%d-
%H_%M_%S\\")
MyLogger._dirname = MyLogger._dirname.replace('\\\\', '/')
if not os.path.exists(MyLogger._dirname):
os.makedirs(MyLogger._dirname)
# set logger
MyLogger._logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
MyLogger._hConsole = logging.StreamHandler()
MyLogger._hFile = logging.FileHandler(MyLogger._dirname + \
MyLogger._filenameBase.format(MyLogger._fileCounter))
MyLogger._hConsole.setLevel(logging.WARNING)
MyLogger._hFile.setLevel(logging.DEBUG)
# create formatter
MyLogger._formatter = logging.Formatter('%(asctime)s %(filename)s, %(funcName)s, %(lineno)s, %(levelname)s: %(message)s')
# add formatter to handlers
MyLogger._hConsole.setFormatter(MyLogger._formatter)
MyLogger._hFile.setFormatter(MyLogger._formatter)
# add handlers to logger
MyLogger._logger.addHandler(MyLogger._hConsole)
MyLogger._logger.addHandler(MyLogger._hFile)
@staticmethod
def _StartNewFileHandler():
MyLogger._closeFileHandler()
# create new file handler
++MyLogger._fileCounter
MyLogger._hFile = logging.FileHandler(MyLogger._dirname + \
MyLogger._filenameBase.format(MyLogger._fileCounter))
MyLogger._hFile.setLevel(logging.DEBUG)
MyLogger._hFile.setFormatter(MyLogger._formatter)
MyLogger._logger.addHandler(MyLogger._hFile)
@staticmethod
def WriteLog(severity, message):
if (len(MyLogger._logger.handlers) < 2):
MyLogger._StartNewFileHandler()
MyLogger._linesCounter += 1
MyLogger._logger.log(MyLogger._severityDict[severity], message)
if (MyLogger._linesCounter >= MyLogger._nNumOfLinesPerFile):
MyLogger._logger.info('Last line in file')
MyLogger._StartNewFileHandler()
MyLogger._linesCounter = 0
@staticmethod
def _closeFileHandler():
if (len(MyLogger._logger.handlers) > 1):
MyLogger._logger.info('Last line in file')
MyLogger._logger.handlers[1].stream.close()
MyLogger._logger.removeHandler(MyLogger._logger.handlers[1])