Сбой Python при использовании статического класса

Я делаю свои первые шаги в Python и дошел до того, что мне нужен модуль журналирования. Причины, по которым я не выбрал обработчик вращающихся файлов:

  1. Я хотел, чтобы при каждом запуске кода создавалась новая папка с новыми файлами журналов.
  2. Использование обычных имен файлов (myName_X.logи не по умолчанию myName.log.X).
  3. Ограничьте файлы журнала числом строк, а не размером файла (как это делается с помощью обработчика вращающихся файлов).

Я написал такой модуль, используя встроенный в Python модуль логирования, но у меня есть две проблемы:

  1. Новая папка и файл будут созданы, а данные регистрации будут напечатаны в файле. Однако когда main() запускается во второй раз (см. код ниже), вновь созданный файл заблокирован и не может быть удален из проводника, пока я не закрою IDE или не сниму блокировку через Process Explorer.
  2. Интерпретатор 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])

0 ответов

Другие вопросы по тегам