Конфигурация журнала для входа в файл и печати в стандартный вывод
Я использую модуль протоколирования Python для регистрации некоторых строк отладки в файле, который работает очень хорошо. Теперь, кроме того, я хотел бы использовать этот модуль, чтобы также печатать строки в stdout. Как мне это сделать? Чтобы записать мои строки в файл, я использую следующий код:
import logging
import logging.handlers
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(
LOGFILE, maxBytes=(1048576*5), backupCount=7
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
а затем вызовите функцию журнала, например
logger.debug("I am written to the file")
Благодарим вас за помощь!
Ответы
Ответ 1
Просто возьмите дескриптор корневого регистратора и добавьте StreamHandler. StreamHandler пишет stderr. Не уверен, что вам действительно нужно stdout поверх stderr, но это то, что я использую, когда я настраиваю регистратор Python, а также добавляю FileHandler. Затем все мои журналы идут в оба места (что и похоже на то, что вам нужно).
import logging
logging.getLogger().addHandler(logging.StreamHandler())
Вы также можете добавить Formatter, чтобы все ваши строки журнала имели общий заголовок.
т
import logging
logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
rootLogger = logging.getLogger()
fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName))
fileHandler.setFormatter(logFormatter)
rootLogger.addHandler(fileHandler)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logFormatter)
rootLogger.addHandler(consoleHandler)
Печатает в формате:
2012-12-05 16:58:26,618 [MainThread ] [INFO ] my message
Ответ 2
logging.basicConfig()
с Python 3.3, logging.basicConfig()
может принимать handlers
аргументов ключевых слов, что значительно упрощает настройку ведения журнала, особенно при настройке нескольких обработчиков с одним и тем же форматером:
handlers
- если указано, это должен быть итеративный из уже созданных обработчиков для добавления в корневой логгер. Любым обработчикам, которые еще не имеют установленного форматера, будет назначен форматер по умолчанию, созданный в этой функции.
Поэтому довольно длинный и подробный пример кода из принятого ответа становится следующим:
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s",
handlers=[
logging.FileHandler("{0}/{1}.log".format(logPath, fileName)),
logging.StreamHandler()
])
(Или с помощью import sys
+ StreamHandler(sys.stdout)
соответствии с требованиями исходного вопроса.)
Чтобы получить регистратор, используйте
logger = logging.getLogger()
Позже в вашем скрипте используйте logger.info()
для вывода полезных сообщений журнала.
Ответ 3
Добавление StreamHandler без аргументов переходит в stderr вместо stdout. Если какой-либо другой процесс имеет зависимость от дампа stdout (т.е. При написании плагина NRPE), то обязательно укажите stdout явно или вы можете столкнуться с неожиданными проблемами.
Здесь приведен пример повторного использования предполагаемых значений и LOGFILE из вопроса:
import logging
from logging.handlers import RotatingFileHandler
from logging import handlers
import sys
log = logging.getLogger('')
log.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(format)
log.addHandler(ch)
fh = handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)
fh.setFormatter(format)
log.addHandler(fh)
Ответ 4
Либо запускайте basicConfig
с stream=sys.stdout
в качестве аргумента перед настройкой любых других обработчиков, либо регистрируя любые сообщения, либо вручную добавляя StreamHandler
, который толкает сообщения на stdout в корневой журнал (или любой другой регистратор, который вы хотите, если на то пошло).
Ответ 5
После многократного использования кода Waterboy в нескольких пакетах Python я, наконец, превратил его в крошечный автономный пакет Python, который вы можете найти здесь:
https://github.com/acschaefer/duallog
Код хорошо документирован и прост в использовании. Просто загрузите файл .py
и pip install duallog
его в свой проект, или установите весь пакет с помощью pip install duallog
.
Ответ 6
Для версии 2.7 попробуйте следующее:
fh = logging.handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)