Я использую Python 2.6 в качестве замены пакетного скрипта.Он будет запущен двойным щелчком, поэтому весь вывод на стандартный вывод будет потерян / проигнорирован пользователем.Итак, я решил добавить ведение журнала, и чтобы упростить задачу, я написал для этого класс.Идея состоит в том, что я могу использовать Logging.Logger
в любом месте моего кода, и регистратор будет готов к работе.
Я хочу, чтобы в каталоге было не более 10 старых файлов журнала, поэтому я очищаюстарые вручную.Я не нашел такой функции через API, плюс я параноик и хочу все регистрировать, даже если в каталоге журналов были файлы с неожиданными именами.
Итак, ниже моя попыткатакой класс, но я получаю сообщение об ошибке при попытке его проверить (запустить):
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "C:/AutomationScripts/build scripts/Deleteme.py", line 6, in <module>
class Logging:
File "C:/AutomationScripts/build scripts/Deleteme.py", line 42, in Logging
__clearOldLogs(dummySetting)
File "C:/AutomationScripts/build scripts/Deleteme.py", line 38, in __clearOldLogs
_assert(Logger, 'Logger does not exist yet! Why?')
NameError: global name '_assert' is not defined
>>>
Да, я пришел из Java / C # фона.Я, вероятно, не делаю вещи "питонским" способом.Пожалуйста, помогите мне сделать правильную вещь, и, пожалуйста, дайте полный ответ, который сработает, вместо того, чтобы просто указывать на пробелы в моих знаниях.Я полагаю, что предоставил достаточно примера кода.Извините, он не будет работать без класса настроек, но, надеюсь, вы поймете идею.
# This file has been tested on Python 2.6.*. For Windows only.
import logging # For actual logging
import tkMessageBox # To display an error (if logging is unavailable)
class Logging:
"""
Logging class provides simplified interface to logging
as well as provides some handy functions.
"""
# To be set when the logger is properly configured.
Logger = None
@staticmethod
def _assert(condition, message):
""" Like a regular assert, except that it should be visible to the user. """
if condition: return
# Else log and fail
if Logger:
Logger.debug(traceback.format_stack())
Logger.error('Assert failed: ' + message)
else:
tkMessageBox.showinfo('Assert failed: ' + message, traceback.format_stack())
assert(condition)
@staticmethod
def _removeFromEnd(string, endString):
_assert(string.endswith(endString),
"String '{0}' does not end in '{1}'.".format(string, endString))
return string[:-len(endString)]
def __clearOldLogs(logSettings):
"""
We want to clear old (by date) files if we get too many.
We should call this method only after variable 'Logger' has been created.
"""
# The following check should not be necessary from outside of
# Logging class, when it is fully defined
_assert(Logger, 'Logger does not exist yet! Why?')
# Do more work here
def __createLogger(logSettings):
logFileName = logSettings.LogFileNameFunc()
#_assert(False, 'Test')
logName = _removeFromEnd(logFileName, logSettings.FileExtension)
logFileName = os.path.join(logSettings.BaseDir, logFileName)
# If someone tried to log something before basicConfig is called,
# Python creates a default handler that goes to the console and will
# ignore further basicConfig calls. Remove the handler if there is one.
root = logging.getLogger()
if root.handlers:
for handler in root.handlers:
root.removeHandler(handler)
logging.basicConfig(filename = logFileName, name = logName, level = logging.DEBUG, format = "%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(logName)
return logger
# Settings is a separate class (not dependent on this one).
Logger = __createLogger(Settings.LOGGING)
__clearOldLogs(Settings.LOGGING)
if __name__ == '__main__':
# This code section will not run when the class is imported.
# If it is run directly, then we will print debugging info.
logger = Logging.Logger
logger.debug('Test debug message.')
logger.info('Test info message.')
logger.warning('Test warning message.')
logger.error('Test error message.')
logger.critical('Test critical message.')
Приветствуются соответствующие вопросы, предложения по стилю и полные ответы.Спасибо!