Как вставить новую строку в ведение журнала python?
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
>>> logging.info('hello')
11:15:01 INFO hello
>>> logging.warning('\n new hello')
11:16:49 WARNING
new hello
потому что журнал переполнен, я хочу явно вставить новую строку перед asctime
и levelname
. Возможно ли это без изменения format
?
Я заглянул в модуль logging
и немного искал в googled и не мог найти жизнеспособный способ.
Ответы
Ответ 1
У меня есть два решения, первое очень простое, но выход не очень чистый. Второй метод даст точный результат, который вы хотите, но он немного более задействован.
Способ 1
Чтобы создать пустую строку, просто запишите пустую строку с новой строкой:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
logging.info('hello')
logging.info('\n')
logging.warning('new hello')
Выход будет содержать пустую информационную строку, которая не очень чиста:
16:07:26 INFO hello
16:07:26 INFO
16:07:26 ВНИМАНИЕ new hello
Способ 2
В этом методе я создал два разных обработчика. console_handler
, который я использую большую часть времени. Когда мне нужна новая строка, я переключаюсь на второй обработчик, blank_handler
.
import logging
import types
def log_newline(self, how_many_lines=1):
# Switch handler, output a blank line
self.removeHandler(self.console_handler)
self.addHandler(self.blank_handler)
for i in range(how_many_lines):
self.info('')
# Switch back
self.removeHandler(self.blank_handler)
self.addHandler(self.console_handler)
def create_logger():
# Create a handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(logging.Formatter(fmt="%(name)s %(levelname)-8s: %(message)s"))
# Create a "blank line" handler
blank_handler = logging.StreamHandler()
blank_handler.setLevel(logging.DEBUG)
blank_handler.setFormatter(logging.Formatter(fmt=''))
# Create a logger, with the previously-defined handler
logger = logging.getLogger('logging_test')
logger.setLevel(logging.DEBUG)
logger.addHandler(console_handler)
# Save some data and add a method to logger object
logger.console_handler = console_handler
logger.blank_handler = blank_handler
logger.newline = types.MethodType(log_newline, logger)
return logger
if __name__ == '__main__':
logger = create_logger()
logger.info('Start reading database')
logger.info('Updating records ...')
logger.newline()
logger.info('Finish updating records')
Результат - это то, что вы хотите видеть:
logging_test INFO : Start reading database
logging_test INFO : Updating records ...
logging_test INFO : Finish updating records
Обсуждение
- Если вы можете мириться с результатом, отличным от идеального, метод 1 - это путь. Преимущество состоит в том, чтобы быть простым, наименьшим количеством усилий.
- Второй метод выполняет работу правильно, но это немного связано. Он создает два разных обработчика и переключает их для достижения вашей цели.
- Другим недостатком использования метода 2 является изменение вашего кода путем поиска
logging
и замены их на logger
. Вы должны позаботиться о замене только релевантных частей и оставить таким образом текст logging.DEBUG
.
Ответ 2
Не могли бы вы добавить новую строку после первого приветствия? то есть.
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
logging.info('hello\n')
logging.info('new hello')
Который выведет
2014-08-06 11:37:24,061 INFO : hello
2014-08-06 11:37:24,061 INFO : new hello
Ответ 3
Используйте пользовательский Formatter
, который использует разные строки формата в разное время. Вы не можете сделать это с помощью basicConfig()
- вам придется использовать другие части API logging
.
class MyFormatter(logging.Formatter):
def format(self, record):
# set self._fmt to value with or without newline,
# as per your decision criteria
# self._fmt = ...
return super(MyFormatter, self).format(record)
Или вы можете вызвать метод super
, а затем изменить строку, чтобы вставить новую строку перед ее возвратом (если это зависит от длины строки, скажем).
Ответ 4
Самый простой способ вставить новые строки, которые я понял:
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s\n\r%(message)s', datefmt='%H:%M:%S')
logging.info('hello')
logging.info('new hello')
Ответ 5
В качестве альтернативы Hai Vu Метод 2 вы могли бы также reset обработчик Formatter
каждый раз, когда вы хотите записать новую строку:
import logging
import types
def log_newline(self, how_many_lines=1):
# Switch formatter, output a blank line
self.handler.setFormatter(self.blank_formatter)
for i in range(how_many_lines):
self.info('')
# Switch back
self.handler.setFormatter(self.formatter)
def create_logger():
# Create a handler
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt="%(name)s %(levelname)-8s: %(message)s")
blank_formatter = logging.Formatter(fmt="")
handler.setFormatter(formatter)
# Create a logger, with the previously-defined handler
logger = logging.getLogger('logging_test')
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
# Save some data and add a method to logger object
logger.handler = handler
logger.formatter = formatter
logger.blank_formatter = blank_formatter
logger.newline = types.MethodType(log_newline, logger)
return logger
if __name__ == '__main__':
logger = create_logger()
logger.info('Start reading database')
logger.info('Updating records ...')
logger.newline()
logger.info('Finish updating records')
Преимущество этого в том, что у вас есть один обработчик. Например, вы можете определить атрибут FileHandler
mode
для записи, если вы хотите очистить свой лог файл при каждом новом запуске вашей программы.
Ответ 6
В ответ на полезный ответ Винай Салипа (ниже) я сделал это так (я использую соглашение суперкласса python3, но super(MyFormatter, self)
работает так же хорошо)...
class MyFormatter(logging.Formatter):
def format(self, record):
return super().format(record).replace(r'\n', '\n')
Затем я могу вставлять новые строки следующим образом:
logging.info('Message\\n\\n\\n\\nOther stuff')
или
logging.info(r'Message\n\n\n\nOther stuff')
Ответ 7
Что-то вроде этого. Добавьте \n
в logging.basicConfig между asctime
и levelname
>>> logging.basicConfig(level=logging.DEBUG, format='%(asctime)s\n %(levelname)s %(message)s',datefmt='%H:%M:%S')