web-dev-qa-db-ja.com

Pythonロギング:時間形式でミリ秒を使用

デフォルトでは、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)

ただし、 documentation はミリ秒のフォーマット方法を指定しません。私は見つけました this SO question これはマイクロ秒について話しますが、a)ミリ秒を好むでしょう、b)Python 2.6では動作しません(私が取り組んでいる)%fのため:

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

注意してください Craig McDanielの解 は明らかに優れています。


logging.FormatterのformatTimeメソッドは次のようになります。

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

"%s,%03d"のコンマに注意してください。 datefmttime.struct_timeであり、これらのオブジェクトはミリ秒を記録しないため、ctを指定してもこれを修正できません。

ctの定義を変更してstruct_timeではなくdatetimeオブジェクトにする場合、(少なくとも最新バージョンのPythonでは)ct.strftimeを呼び出してから%fを使用して、マイクロ秒をフォーマットできます。

import logging
import datetime as dt

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

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

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

formatter = MyFormatter(fmt='%(asctime)s %(message)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')
console.setFormatter(formatter)

logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09,07:12:36.553554 Jackdaws love my big sphinx of quartz.

または、ミリ秒を取得するには、カンマを小数点に変更し、datefmt引数を省略します。

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

...
formatter = MyFormatter(fmt='%(asctime)s %(message)s')
...
logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09 08:14:38.343 Jackdaws love my big sphinx of quartz.
66
unutbu

これも動作するはずです:

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

ミリ秒を追加する方が良いオプションでした、ありがとう。 BlenderのPython 3.5.3でこれを使用した私の修正を以下に示します。

import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', datefmt='%Y-%m-%d %H:%M:%S')
log = logging.getLogger(__name__)
log.info("Logging Info")
log.debug("Logging Debug")
14
Master James

私が見つけた最も簡単な方法は、default_msec_formatをオーバーライドすることでした:

formatter = logging.Formatter('%(asctime)s')
formatter.default_msec_format = '%s.%03d'
11
Mickey B

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
4
Jonathan

datetimeモジュールを必要とせず、他のソリューションのように障害のない単純な拡張は、次のような単純な文字列置換を使用することです。

import logging
import time

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

このように、ミリ秒に%Fを使用することで、地域の違いを考慮して、日付形式を自由に記述できます。例えば:

log = logging.getLogger(__name__)
log.setLevel(logging.INFO)

sh = logging.StreamHandler()
log.addHandler(sh)

fm = MyFormatter(fmt='%(asctime)s-%(levelname)s-%(message)s',datefmt='%H:%M:%S.%F')
sh.setFormatter(fm)

log.info("Foo, Bar, Baz")
# 03:26:33.757-INFO-Foo, Bar, Baz
2
torrentails

arrow を使用している場合、または矢印を使用してもかまいません。 Pythonの時間形式を矢印の形式に置き換えることができます。

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属性ですべての 矢印の時刻形式 を使用できます。

1
Slapy