python log formatter

Log Formatter

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime
import os
import logging
from logging import handlers
import json
import re
from llmkbqa.version import __version__

today=datetime.date.today()
str_time=today.strftime('%y%m%d')

env = os.environ.get('ENV', None)
app_id = 'xxx' + os.environ.get('APPLICATION_TYPE', 'server')
version = os.environ.get('VERSION', __version__)
log_dir = os.environ.get('LOG_DIR', log_dir)
log_path = os.path.join(log_dir, f"{str_time}_llm-elapsed.log")
when = "D"
backupCount = 10

class JsonFormatter(logging.Formatter):
    def __init__(self, fmt=None, datefmt=None, style='%', mid="mid_unknown", event_id=None):
        super().__init__(fmt, datefmt, style)
        self.mid = mid
        self.event_id = event_id

    def format(self, record):
        # 将 record.message 转换为 JSON 字符串
        if isinstance(record.msg, dict):
            record.msg = json.dumps(record.msg, ensure_ascii=False)
        # 添加 mid 到 record
        record.mid = self.mid
        if 'event_id' in record.__dict__:
            record.event_id = record.__dict__['event_id']
        else:
            record.event_id = self.event_id
        
        # 创建日志字典
        log_dict = {
            "time_stamp": self.formatTime(record, self.datefmt),
            "mid": record.mid,
            "event_id": record.event_id,
            "level": record.levelname,
            "message": record.msg,
            "msg_type": "json" if isinstance(record.msg, str) and record.msg.startswith('{') else "text"
        }
        # print(f"================={record}")
        
        # 将日志字典转换为 JSON 字符串
        return json.dumps(log_dict, ensure_ascii=False)


class ElapsedLog(logging.Logger):
    """
    日志记录
    """

    def __init__(self, name=None, verbose=False, file_handler=True, mid="mid_unknown", event_id=None):
        """
            verbose==False, 表示INFO level
            verbose==True, 表示DEBUG level
            file_handler=False, 表示不写入到文件
            file_handler=True, 表示写入到文件
        """
        super().__init__(name)
        super().setLevel(logging.DEBUG if verbose else logging.INFO)

        # 设置日志打印格式
        self.formatter = JsonFormatter(mid=mid, event_id=event_id)

        if file_handler:
            if not os.path.exists(log_dir):
                os.makedirs(log_dir)
            file_handler = handlers.TimedRotatingFileHandler(
                filename=log_path, when=when, backupCount=backupCount, encoding="utf-8")
            file_handler.suffix = "%Y%m%d-%H-%M-%S.log"
            file_handler.extMatch = re.compile(r"^\d{8}-\d{2}-\d{2}-\d{2}.log$")
            file_handler.setFormatter(self.formatter)
            self.addHandler(file_handler)

        stream_handler = logging.StreamHandler()
        stream_handler.setFormatter(self.formatter)
        self.addHandler(stream_handler)

    def set_mid(self, mid):
        """设置 mid"""
        self.formatter.mid = mid

    def set_event_id(self, event_id):
        """设置 event id"""
        self.formatter.event_id = event_id


# 创建日志记录器实例
logger = ElapsedLog(file_handler=True)

if __name__ == '__main__':
    # 设置 mid
    logger.set_mid('123456789')
    logger.set_event_id('ElapsedEvent')

    a = {"x": True}

    logger.info("测试日志")
    logger.debug("测试日志11")
    logger.error("测试日志44")
    logger.warning("测试日志55")
    logger.info(a)
posted @   春树&暮云  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示