やりたいこと
- Loggerクラスを定義してそれを他のクラスから呼び出して使う
- JSONフォーマット
-
message
以外に常に紐づけておきたい動的パラメータ、shopId
とitemId
も入れたい
JsonFormatter.py
import logging
import datetime
from pytz import timezone
from pythonjsonlogger import jsonlogger
class JsonFormatter(jsonlogger.JsonFormatter):
def parse(self):
return [
'timestamp',
'level',
'name',
'class',
'shopId',
'itemId',
'message',
]
shopId = None
itemId = None
def add_fields(self, log_record, record, message_dict):
super().add_fields(log_record, record, message_dict)
if not log_record.get('timestamp'):
now = datetime.datetime.now(timezone('Asia/Tokyo')).strftime('%Y-%m-%dT%H:%M:%S%z')
log_record['timestamp'] = now
if log_record.get('level'):
log_record['level'] = log_record['level'].upper()
else:
log_record['level'] = record.levelname
# logを出力するファイルとその行
log_record['class'] = record.pathname + ":" + str(record.lineno)
# taskNameいらない
del log_record['taskName']
if self.shopId and self.itemId:
log_record['shopId'] = self.shopId
log_record['itemId'] = self.itemId
def setItemId(self, shopId, itemId):
print(shopId, itemId)
self.shopId = shopId
self.itemId = itemId
def getLogger(module_name):
logger = logging.getLogger(module_name)
handler = logging.StreamHandler()
formatter = JsonFormatter()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
return logger, formatter
test.py
from JsonFormatter import getLogger
import time
logger, formatter = getLogger(__name__)
error_code = 100
shopId = "11111"
itemId = "22222"
logger.error('Error occured due to xx', extra={'error_code': error_code})
formatter.setItemId(shopId, itemId)
time.sleep(3)
logger.error('Error occured due to xx', extra={'error_code': error_code})
実行します
$ python3 test.py
結果
{"timestamp": "2024-07-22T11:50:05+0900", "level": "ERROR", "name": "__main__", "class": "/Users/shuto.kawabata/Desktop/test.py:10", "shopId": null, "itemId": null, "message": "Error occured due to xx", "error_code": 100}
{"timestamp": "2024-07-22T11:50:08+0900", "level": "ERROR", "name": "__main__", "class": "/Users/shuto.kawabata/Desktop/test.py:14", "shopId": "11111", "itemId": "22222", "message": "Error occured due to xx", "error_code": 100}
となり
formatter.setItemId(shopId, itemId)
したことで期待値通りにshopIdとitemIdに値が代入されました