加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python日志输出的内容修改为json格式

发布时间:2020-12-20 10:14:33 所属栏目:Python 来源:网络整理
导读:业务中要求,python项目的日志输出为json串,同时包括异常;经过查看python logging相关的源码,发现还不能完全的兼容;比如异常的源码那里: class Formatter(object): """ 省略 """ def format(self,record): record.message = record.getMessage() if sel

业务中要求,python项目的日志输出为json串,同时包括异常;经过查看python logging相关的源码,发现还不能完全的兼容;比如异常的源码那里:

class Formatter(object):
    """省略"""
    def format(self,record):
        record.message = record.getMessage()
        if self.usesTime():
            record.asctime = self.formatTime(record,self.datefmt)
        s = self.formatMessage(record)
        if record.exc_info:
            # Cache the traceback text to avoid converting it multiple times
            # (it‘s constant anyway)
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info)
        if record.exc_text:
            if s[-1:] != "n":
                s = s + "n"
            s = s + record.exc_text
        if record.stack_info:
            if s[-1:] != "n":
                s = s + "n"
            s = s + self.formatStack(record.stack_info)
        return s

logging.Formatter的format方法,首先会按照格式化串格式化message,然后如果出现异常,是直接再message后面加上异常;此时格式已经不是指定的格式,因此这里需要修自定义。

# -*- coding:utf-8 -*-
import json
import logging
import os
import traceback



BASE_DIR = os.path.abspath(os.getcwd())
LOG_DIR = os.path.join(BASE_DIR,"logs")

host_ip ="localhost"

JSON_LOGGING_FORMAT = json.dumps({
    "ip": "%(ip)s","app": "%(app)s","level": "%(levelname)s","trace": "%(stack_msg)s","filepath": "%(pathname)s","line_number": "%(lineno)s","time": "%(asctime)s","message": "%(message)s","stack_trace": "%(exc_text)s"
})


class JsonLoggingFilter(logging.Filter):
    def __init__(self,name,ip,app):
        logging.Filter.__init__(self,name=name)
        self.ip = ip
        self.app = app

    def filter(self,record):
        record.ip = self.ip
        record.app = self.app
        # 为record 添加异常堆栈信息字段; 当有多个handler 的时候,这里会判断多次
        if hasattr(record,"stack_msg") and hasattr(record,"stack_trace"):
            return True

        if record.exc_info:
            ex_type,ex_val,ex_stack = record.exc_info
            stack_list = []
            for stack in traceback.extract_tb(ex_stack):
                stack_list.append("%s" % stack)

            record.stack_msg = ex_val
            record.stack_trace = "#".join(stack_list)
        else:
            record.stack_msg,record.stack_trace = "",""

        return True


class JsonFormatter(logging.Formatter):
    def __init__(self,fmt=None):
        logging.Formatter.__init__(self,fmt=fmt)

    def format(self,self.datefmt)

        if record.exc_info:
            # Cache the traceback text to avoid converting it multiple times
            # (it‘s constant anyway)
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info).replace("n"," ").replace(""","")

        s = self.formatMessage(record)
        return s


class JsonLogger(logging.Logger):
    logger = None
    level = None
    mode = None

    def __init__(self,app_name,level=logging.DEBUG,console_level=logging.INFO,mode="w"):
        self.name = app_name
        self.app_name = app_name

        logging.Logger.__init__(self,name=app_name)

        self.logger = logging.Logger(name=app_name)
        self.logger.setLevel(level)

        if not os.path.exists(LOG_DIR):
            os.makedirs(LOG_DIR)
        log_file_path = os.path.join(LOG_DIR,"%s.json" % app_name)
        json_logging_filter = JsonLoggingFilter(app_name,ip=host_ip,app=app_name)
        json_formatter = JsonFormatter(JSON_LOGGING_FORMAT)

        # 文件日志
        file_handle = logging.FileHandler(log_file_path,mode=mode)
        file_handle.setLevel(level)
        file_handle.setFormatter(json_formatter)
        file_handle.addFilter(json_logging_filter)
        # 控制台日志
        console_handle = logging.StreamHandler()
        console_handle.setLevel(console_level)
        console_handle.setFormatter(json_formatter)
        console_handle.addFilter(json_logging_filter)

        self.logger.addHandler(file_handle)
        self.logger.addHandler(console_handle)

    def getLogger(self):
        return self.logger

    def setLevel(self,level):
        self.logger.level = level


if __name__ == __main__:
    my_logger = JsonLogger("python-common").getLogger()
    my_logger.info("info  level log")
    try:
        open(/path/to/does/not/exist,rb)
    except FileNotFoundError as e:
        my_logger.exception("file exception",exc_info=e)

?

参考:

https://www.cnblogs.com/yyds/p/6901864.html

关于异常?https://www.jianshu.com/p/b342b19657fc

日志输出 json串?https://blog.csdn.net/diqiuyi7777/article/details/86498203

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读