默认情况下logging.Formatter('%(asctime)s')打印如下格式:

2011-06-09 10:54:40,638

638是毫秒。我需要把逗号换成一个点:

2011-06-09 10:54:40.638

格式化我可以使用的时间:

logging.Formatter(fmt='%(asctime)s',datestr=date_format_str)

但是,文档没有指定如何格式化毫秒。我发现了这个SO问题,它谈论的是微秒,但是a)我更喜欢毫秒,b)由于%f,下面的问题在Python 2.6(我正在工作)上不起作用:

logging.Formatter(fmt='%(asctime)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')

当前回答

实例化Formatter后,我通常设置Formatter。Converter = gmtime。所以为了让@unutbu的答案在这种情况下工作,你需要:

class MyFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        ct = self.converter(record.created)
        if datefmt:
            s = time.strftime(datefmt, ct)
        else:
            t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
            s = "%s.%03d" % (t, record.msecs)
        return s

其他回答

实例化Formatter后,我通常设置Formatter。Converter = gmtime。所以为了让@unutbu的答案在这种情况下工作,你需要:

class MyFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        ct = self.converter(record.created)
        if datefmt:
            s = time.strftime(datefmt, ct)
        else:
            t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
            s = "%s.%03d" % (t, record.msecs)
        return s

使用这个智能答案的时区和选择的答案,你可以用你想要的格式构建毫秒和时区:

import logging
import time

if __name__ == "__main__":
    tz = time.strftime('%z')
    logging.basicConfig(
        format=(
            "%(asctime)s.%(msecs)03d" + tz + " %(levelname)s "
            "%(pathname)s:%(lineno)d[%(threadName)s]: %(message)s"
        ),
        level=logging.DEBUG,
        datefmt="%Y-%m-%dT%H:%M:%S",
    )
    logging.info("log example")

就我个人而言,我喜欢以UTC格式保存所有日志,但在日志中显式地将其作为没有时区的datetime,这在多区域应用程序中是没有意义的:

    logging.Formatter.converter = time.gmtime
    logging.basicConfig(
        format=(
            "%(asctime)s.%(msecs)03d+0000 %(levelname)s "
            "%(pathname)s:%(lineno)d[%(threadName)s]: %(message)s"
        ),
        level=logging.DEBUG,
        datefmt="%Y-%m-%dT%H:%M:%S",
    )

tl;dr给那些在这里寻找ISO格式日期的人:

而不是使用'%Y-%m-%d %H:% m:%S。%03d%z',按@unutbu指示创建自己的类。下面是iso date格式:

import logging
from time import gmtime, strftime

class ISOFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        t = strftime("%Y-%m-%dT%H:%M:%S", gmtime(record.created))
        z = strftime("%z",gmtime(record.created))
        s = "%s.%03d%s" % (t, record.msecs,z)        
        return s

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

console = logging.StreamHandler()
logger.addHandler(console)

formatter = ISOFormatter(fmt='%(asctime)s - %(module)s - %(levelname)s - %(message)s')
console.setFormatter(formatter)

logger.debug('Jackdaws love my big sphinx of quartz.')
#2020-10-23T17:25:48.310-0800 - <stdin> - DEBUG - Jackdaws love my big sphinx of quartz.

这也可以工作:

logging.Formatter(
    fmt='%(asctime)s.%(msecs)03d',
    datefmt='%Y-%m-%d,%H:%M:%S'
)

如果你用箭头或者不介意用箭头的话。你可以用python的时间格式代替arrow的时间格式。

import logging

from arrow.arrow import Arrow


class ArrowTimeFormatter(logging.Formatter):

    def formatTime(self, record, datefmt=None):
        arrow_time = Arrow.fromtimestamp(record.created)

        if datefmt:
            arrow_time = arrow_time.format(datefmt)

        return str(arrow_time)


logger = logging.getLogger(__name__)

default_handler = logging.StreamHandler()
default_handler.setFormatter(ArrowTimeFormatter(
    fmt='%(asctime)s',
    datefmt='YYYY-MM-DD HH:mm:ss.SSS'
))

logger.setLevel(logging.DEBUG)
logger.addHandler(default_handler)

现在你可以在datefmt属性中使用箭头的所有时间格式。