logging日志改造---自定义参数传递到格式中

news2024/9/21 8:00:12

目录

    • 一:需求
    • 二:实现方式
    • 三:存在的问题
      • 3.1: 问题描述
      • 3.2: 源码分析
      • 3.3: 解决方案
    • 四:相关链接

一:需求

  • 需求:将自定义的参数,放在日志的指定格式中。

二:实现方式

  • 例如:让debug, info,warning,error函数都允许传递一个trace_id, 并将这个trace_id输出到我们自定义日志指定的格式中。
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time   : 2023/10/19 10:08
    # @Author : shanwen.ren
    import logging
    import inspect
    import logging.config
    
    self_logger = logging.getLogger("debug")
    
    
    class Logger(logging.Logger):
    
        @staticmethod
        def check_trace_id(kwargs):
            """kwargs mush has trace_id and trace_id value type mush is str."""
            trace_id = str(kwargs.get("trace_id", ""))
            if "extra" not in kwargs:
                extra = {"trace_id": trace_id}
            else:
                assert isinstance(kwargs["extra"], dict)
                extra = kwargs["extra"]
                extra.update({"trace_id": trace_id})
    
            if "trace_id" in kwargs.keys():
                kwargs.pop("trace_id")
            return extra, kwargs
    
        def debug(self, msg, *args, **kwargs):
            extra, kwargs = self.check_trace_id(kwargs)
            self_logger.debug(msg, *args, extra=extra, **kwargs)
    
        def info(self, msg, *args, **kwargs):
            extra, kwargs = self.check_trace_id(kwargs)
            self_logger.info(msg, *args, extra=extra, **kwargs)
    
        def warning(self, msg, *args, **kwargs):
            extra, kwargs = self.check_trace_id(kwargs)
            self_logger.warning(msg, *args, extra=extra, **kwargs)
    
        def error(self, msg, *args, **kwargs):
            extra, kwargs = self.check_trace_id(kwargs)
            self_logger.error(msg, *args, extra=extra, **kwargs)
    
    
    logger = Logger()
    
    
    def init_log(log_path, log_name, log_level="DEBUG"):
        log_level = log_level.upper()
        LOG_PATH_DEBUG = "%s/%s.log" % (log_path, log_name)
        LOG_FILE_BACKUP_COUNT = 10
    
        log_conf = {
            "version": 1,
            "formatters": {
                "format1": {
                    "format": '|%(asctime)s.%(msecs)03d|%(levelname)s|%(trace_id)s|%(thread)d|%(filename)s %(lineno)d|%(message)s',
                    "datefmt": '%Y-%m-%d %H:%M:%S',
                },
            },
    
            "handlers": {
                "handler": {
                    "class": "logging.handlers.TimedRotatingFileHandler",
                    "level": log_level,
                    "formatter": "format1",
                    "when": "midnight",
                    "backupCount": LOG_FILE_BACKUP_COUNT,
                    "filename": LOG_PATH_DEBUG
                },
            },
    
            "loggers": {
                "debug": {
                    "handlers": ["handler"],
                    "level": log_level
                },
            }
        }
        logging.config.dictConfig(log_conf)
    
    
    def close_log():
        logging.shutdown()
    

三:存在的问题

3.1: 问题描述

  • 上面代码中由于本质是使用的self_logger对象, 因此filename和lineno都会定位到我们自定义的Logger对象的debug, info,warning,error方法中, 无法真正的定位到真实代码所在地。

3.2: 源码分析

  • 调用warning后会调用_log方法。
    在这里插入图片描述
  • findCaller会去取调用位置。
    在这里插入图片描述
  • 底层使用f_back获取上层调用, 返回上层调用的行号lno等信息。
    在这里插入图片描述
  • makeRecord最终作用于日志格式中。
    在这里插入图片描述

3.3: 解决方案

  • 基于源码分析, 发现底层用的inspect.currentframe().f_back,返回的上层调用者, 因此产生一个思路:废弃日志格式中的文件名和行号, 改成自己传递N-任意层调用的位置和行号。
  • 代码调整:
    在这里插入图片描述
    在这里插入图片描述
  • 改为自定义名称原因:
    在这里插入图片描述

四:相关链接

  • 官方文档:https://docs.python.org/zh-cn/3/library/logging.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三维模型表面积计算方法

【版权声明】 本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 更多算法总结请关注我的博客:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。 本文章来自于专栏《Python三维模型处理基础》的系列文…

【RocketMQ系列十】RocketMQ的核心概念说明

您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。 💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精…

【计网 DNS】计算机网络 DNS协议详解:中科大郑烇老师笔记 (六)

目录 0 引言1 DNS概述1.1 定义1.2 DNS域名结构1.2 域名解析步骤 🙋‍♂️ 作者:海码007📜 专栏:计算机四大基础专栏📜 其他章节:网络快速入门系列、计算机网络(一)、计算机网络&…

初始Redis 分布式结构的发展演变

目录 Redis的特点和使用场景 分布式系统的引入 单机系统 分布式系统 应用服务器的增多(处理更多的请求) 数据库读写分离(数据服务器的增多) 引入缓存 应对更大的数据量 业务拆分:微服务 Redis的特点和使用场景 我们先来…

使用 Rust 和 cURL 库下载程序

以下是一个使用 Rust 和 cURL 库的下载器程序,用于下载 图像。此程序使用了 https://www.duoip.cn/get_proxy 的代码。 extern crate curl; ​ use std::io::{self, Read}; use std::error::Error; ​ fn main() {let url "https://www.baidu.com";let …

04-HotSpot 垃圾收集器

HotSpot 垃圾收集器 HotSpot 虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,虽然我们要对各个收集器进行比较,但并非为了挑选出一个最好的收集器。我们选择的只是对具体应用最合适的收集器。 新生代垃圾收集器 Serial 垃圾收集器&…

如何将表格内容拆分至多列内容

如何将表格内容拆分至多列内容 需求示例步骤1.找到“分列”2.选择“分隔符号(D)”3.设置分隔符号4.完成5.分隔后的内容 总结 需求 表格的某一列里有很多内容,想将该列内容拆分到多列里,并能准确的显示拆分后的每一列内容 示例 …

【Java 进阶篇】Java XML约束:确保数据一致性和有效性

XML(可扩展标记语言)是一种常用的数据交换格式,用于存储和交换数据。然而,为了确保数据的一致性和有效性,通常需要定义XML约束。XML约束是一种规则集,定义了XML文档的结构、元素、属性和数据类型。本篇博客…

RobotRules 和UserAgent来下载文件

以下是一个使用WWW::RobotRules和LWP::UserAgent来下载文件的Perl程序: #!/usr/bin/perl ​ use strict; use warnings; use WWW::RobotRules; use LWP::UserAgent; use HTTP::Request; use HTTP::Response; ​ my $url http://www.people.com.cn/; my $agent LW…

结构体学习

struct是结构体关键字 我们用C语言中通常都是用关键字来定义类型变量。例如我们的整型变量,int book;是用整型关键字定义出来的。同样的,struct book同样是一个类型,不过我们叫他结构体。我认为的结构体的作用,无外乎是将一些毫…

APU的Vsense引脚的作用

开关电源PCB布局注意事项 开关电源PCB布线注意事项 一.Sense电压检测(FB) “Sense+”和“Sense-”,就是四线制中的电压检测线,high-sense 和low-sense分别连接远端负载的正负极,监测电源电压,抵消长距离传输线引起的电压损耗。这两个Sense接线端的作用简而言之就是调整Ou…

centos如何根据端口号查询程序路径

centos如何根据端口号查询程序路径 如果是半路接受的应用,上个人只给你说了程序的端口号,别的都没,那怎么找程序的路径哪?一是给上上个人要,二是自己找(我是自己找的) 小白教程,一…

链表的中间结点-力扣

1、题目描述 给你单链表的头结点 head ,请你找出并返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台备战技术面试?力扣提供海…

【STM32】标准库与HAL库对照学习系列教程大全

【STM32】标准库与HAL库对照学习系列教程大全 一、前言二、准备工作三、基础篇四、进阶篇五、特别篇六、外设篇 一、前言 前言:开始工作后,学习的时间变少了很多,但是今年的1024节,还是打算送个福利给大家,将之前的STM…

PR BeatEdit 节奏卡点神器 的报错 beat detection error: IBT failed 和解决路径

环境:DELL Latitude 笔记本 16G内衬,Win10,PR 2021,BeatEdit Pr 2.1.003 安装PR BeatEdit 节奏卡点神器没有问题,可以调出。 导入音频时报错:beat detection error: IBT failed 根据 BeatEdit for Premi…

【Unity程序技巧】 资源加载管理器

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

ScrapeKit 和 Swift 编写程序

以下是一个使用 ScrapeKit 和 Swift 编写的爬虫程序,用于爬取 图片。同时,我们使用了proxy 这段代码来获取代理。 import ScrapeKit ​ class PeopleImageCrawler: NSObject, ScrapeKit.Crawler {let url: URLlet proxyUrl: URL ​init(url: URL, proxy…

概率论_概率公式中的分号(;)、逗号(,)、竖线(|) 及其优先级

目录 1.概率公式中的分号(;)、逗号(,)、竖线(|) 2.各种概率相关的基本概念 2.1 联合概率 2.2 条件概率(定义) 2.3 全概率(乘法公式的加强版) 2.4 贝叶斯公式 贝叶斯定理的公式推导 1.概率公式中的分号(;)、逗号(,)、竖线(|) ; 分号代表前后是两类…

uview1.0部分机型u-input组件禁用后无法触发click事件

最近,线上的一个 App 收到用户反馈,输入框禁用状态下点击无法拉起模态框。找了一下身边可用机型进行了测试,起初所有机型都没有复现这个问题,突然有一天 Redmi K30S Ultra 出现了异常,点击输入框无法触发点击事件&…

分享几个bug发现手段-final chk、default test、stress test、fault injection

本文发散式分享几个有效的bug发现手段或者验证方法。 一、final chk final chk的思想是在执行完成一个测试用例(或者一个简单的命令)之后,然后查看下当前设计DUT的状态。比如说一个cacheline,在完成一笔read/write之后&#xff0c…