1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[python3] loggingのタイムスタンプを変更する

Posted at

pythonのloggingでは、ログのタイムスタンプは time.time() で生成されるのですが、 time モジュールで使用可能なディレクティブの関係でタイムスタンプの形式に制限があります。
なので、 datetime を使ってISO8601などに変換できるようにします。

(参考)
logging モジュールでは以下でミリ秒を後から付け足す形で整形していますが、ここでは書式化演算子( % )を使っています。
https://github.com/python/cpython/blob/v3.11.2/Lib/logging/__init__.py#L630
ミリ秒は独自で計算されている様子。
https://github.com/python/cpython/blob/v3.11.2/Lib/logging/__init__.py#L337

ISO8601にする

ハンドラにフォーマットを設定する時に、 logging.Formatter クラスの formatTime() をカスタムしたものを使用すればできます。
record.created にタイムスタンプがUNIX時間(typeはfloat)で格納されています。

import logging

from datetime import datetime, timedelta, timezone


class ISOTimeFormatter(logging.Formatter):
    def formatTime(self, record: logging.LogRecord, datefmt=None):
        tz_jst = timezone(timedelta(hours=+9), 'JST')
        ct = datetime.fromtimestamp(record.created, tz=tz_jst)
        s = ct.isoformat(timespec="microseconds")

        return s


logger = logging.getLogger()
fmt = ISOTimeFormatter("%(asctime)s - %(message)s") # logging.Formatterの代わりに自作のクラスを使う

sh = logging.StreamHandler()
sh.setFormatter(fmt)
logger.addHandler(sh)

logger.setLevel(logging.INFO)

あとは logger.info('hello') などで出力するだけです。 %(asctime)s がそのままISO8601のタイムスタンプになります。

2023-03-20T21:01:22.279373+09:00 - hello

その他の書式にする

ほとんど同じ要領ですが、 logging.Formatterdatefmt を指定することができるので、以下のようにしてもよいと思います。

import logging

from datetime import datetime, timedelta, timezone


class DatetimeFormatter(logging.Formatter):
    def formatTime(self, record: logging.LogRecord, datefmt=None):
        if datefmt is None:
            datefmt = "%Y-%m-%d %H:%M:%S,%03d" # logging.Formatterのデフォルトと同じ形式

        TZ_JST = timezone(timedelta(hours=+9), 'JST')
        created_time = datetime.fromtimestamp(record.created, tz=TZ_JST)
        s = created_time.strftime(datefmt)

        return s


logger = logging.getLogger()
fmt = DatetimeFormatter("%(asctime)s - %(message)s", datefmt="%Y-%m-%dT%H:%M:%S.%f%z") # ここでフォーマットを指定する

sh = logging.StreamHandler()
sh.setFormatter(fmt)
logger.addHandler(sh)

logger.setLevel(logging.INFO)

出力すると以下のようになります。

2023-03-20T21:11:27.637558+0900 - hello

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?