Это невозможно в stdlib logging
из-за способа написания исходного кода. Класс форматера установит asctime
для каждого экземпляра LogRecord
с помощью метода formatTime
. Как видно из модуля ведения журнала, код здесь , соответствующее поле %(asctime)
на самом деле является строковым атрибутом, а не экземпляром datetime
. Это означает, что он не может принимать пользовательское форматирование, кроме простых строковых операций, таких как заполнение и выравнивание.
Я согласен с вами, что это является недостатком модуля stdlib logging
, и призываю вас рассмотреть более мощную структуру ведения журналов, такую как structlog .
Другие читатели вашего вопроса могут быть не против использования подкласса Formatter
в журнале stdlib. Для них я бы предложил определить средство форматирования, которое использует экземпляр datetime
для экземпляра LogRecord
в сочетании со строкой шаблона форматера в фигурных скобках. Это позволяет неограниченно использовать поле asctime
с несколькими форматами strftime.
Настройка проще, чем использование Filter
или LoggingAdapter
, это просто переопределение метода formatTime
на одну строку:
import logging
from datetime import datetime
class MyFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
return datetime.fromtimestamp(record.created)
fmt = '{asctime:%Y-%m-%d %H:%M:%S} - {levelname} - {asctime:%a %b %d %Y} - {message}'
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(MyFormatter(fmt=fmt, style='{'))
logger.addHandler(handler)
logger.warning('the message')
Примечание: если один из необходимых вам форматов - это просто временная метка (секунды с начала эпохи), то вам вообще не нужна настраиваемая «гимнастика» Formatter - вы можете просто использовать created
поле (которое принимает настройки форматирования с плавающей запятой) в сочетании с полем asctime
.