当前位置: 首页 > news >正文

Python 在logging.config.dictConfig()日志配置方式下,使用自定义的Handler处理程序

文章目录

    • 一、基于 RotatingFileHandler 的自定义处理程序
    • 二、基于 TimedRotatingFileHandler 的自定义处理程序


Python logging模块的基本使用、进阶使用详解

Python logging.handlers模块,RotatingFileHandler、TimedRotatingFileHandler 处理器各参数详细介绍

Python logging.config模块,logging.config.fileConfig()、logging.config.dictConfig() 使用介绍

python logging模块Filters过滤器介绍,如何使用自定义的过滤器


这篇文章将介绍如何在logging.config.dictConfig()日志配置方式下,使用自定义的Handler处理程序。

一、基于 RotatingFileHandler 的自定义处理程序

默认情况下,使用logging.handlers.RotatingFileHandler()生成的备份文件,不是以.log为后缀,例如:原日志文件为rotated.log,那么生成的备份日志文件为rotated.log.xxxxxx为数字。

接下来将使用自定义处理程序,将生成的备份日志文件的后缀改为rotated.xxx.log

rtfHandler.py 自定义处理程序模块

# -*- coding:utf-8 -*-
import logging
import logging.handlers
import os
import redef my_rotating_file_handler(filename,mode='a',maxBytes=0,backupCount=0,encoding=None,delay=False):rh = logging.handlers.RotatingFileHandler(filename,mode=mode,maxBytes=maxBytes,backupCount=backupCount,encoding=encoding,delay=delay)global bckCount		# 声明全局变量,供 remove_old_log()、rotator() 方法使用bckCount = backupCount# 调用新实现的备份日志文件命名规则rh.rotator = rotatorrh.namer = namerreturn rhdef namer(name):# 在备份文件后增加 .log 后缀 name = name + '.log'return namedef rotator(source, dest):global dest_file	# 声明全局变量,供 remove_old_log() 方法使用dest_file = destsp = dest.rsplit(".",3)sp.pop(1)		# 删除备份文件中间的那个".log"# 因为改了备份日志文件名称规则,所以原有的备份规则失效了,下面是重写的备份规则for dst in range(bckCount,0,-1):sp[1] = str(dst)dest = ".".join(sp)if os.path.exists(dest):os.remove(dest)sp[1] = str(dst-1)src = ".".join(sp)if os.path.exists(src):os.rename(src,dest)sp[1] = str(1)dest = ".".join(sp)os.rename(source,dest)remove_old_log()# 因为改变了命名规则,所以重新实现了一个删除旧日志文件的方法
def remove_old_log():logdir = os.path.dirname(dest_file)fname = os.path.basename(dest_file)flist = os.listdir(logdir)fsplit = fname.rsplit(".",3)pattern = re.compile(r".".join([fsplit[0],"[0-9]+",fsplit[3]]))for f in flist:if re.match(pattern,f) and int(f.rsplit(".",2)[1]) > bckCount:fpath = os.path.join(logdir,f)os.remove(fpath)

rtfLog.yaml 日志配置文件,handlers.rtfhandler 下配置了一个自定义的处理程序

version: 1
disable_existing_loggers: false
formatters:simple:format: '[%(asctime)s - %(name)s - %(levelname)-8s] %(message)s'
handlers:console:class: logging.StreamHandlerformatter: simplelevel: DEBUGstream: ext://sys.stdoutrtfhandler:# 通过()键,引用一个自定义的处理程序# ext:// 用来告诉dicConfig(),它后面的config.rtfHandler.my_rotating_file_handler 是配置以外的对象(): ext://config.rtfHandler.my_rotating_file_handlerlevel: DEBUGformatter: simple# 下面的标量都是提供给自定义的处理程序方法的参数filename: rotated.logmode: amaxBytes: 40backupCount: 2encoding: utf8delay: False
loggers:mylogger:level: DEBUGhandlers: [console,rtfhandler]propagate: no

rtfLogger.py 封装日志模块,使用dictConfig()读取日志配置文件以完成日志配置

# -*- coding:utf-8 -*-
import logging.config
import yaml
import osclass Logger():def __init__(self,logger_name=''):self.logger_name = logger_name# 获取当前文件所在目录cur_dir = os.path.dirname(__file__)# 拼接对应的yaml配置文件路径log_conf = os.path.join(cur_dir, 'logconf', 'rtflog.yaml')with open(log_conf, 'r', encoding='utf8') as f:config = yaml.safe_load(f.read())# 加载配置文件logging.config.dictConfig(config)def logger(self):logger = logging.getLogger(self.logger_name)return logger

main.py 主程序,测试日志功能

# -*- coding:utf-8 -*-
from config.rtfLogger import Logger
import timemlogger = Logger('mylogger').logger()for i in range(10):mlogger.info(f'Message no. {i + 1}')time.sleep(1)

运行main.py程序,输出:
日志轮转,自定义备份文件命名规则

二、基于 TimedRotatingFileHandler 的自定义处理程序

默认情况下,使用logging.handlers.TimedRotatingFileHandler ()生成的备份文件,不是以.log为后缀,例如:原日志文件为timed_rotated.log,那么生成的备份日志文件为timed_rotated.log.xxxxxx为格式化的日期时间,如:2023-08-21_23-56-50

接下来将使用自定义处理程序,将生成的备份日志文件的后缀改为rotated.xxx.log

trfHandler.py 自定义处理程序模块

# -*- coding:utf-8 -*-
import logging
import logging.handlers
import os
import redef my_timed_rotating_file_handler(filename,when='h',interval=1,backupCount=0,encoding=None,delay=False,utc=False,atTime=None):global trfhtrfh = logging.handlers.TimedRotatingFileHandler(filename=filename,when=when,interval=interval,backupCount=backupCount,encoding=encoding,delay=delay,utc=utc,atTime=atTime)trfh.rotator = rotatortrfh.namer = namerreturn trfhdef namer(name):name = name + '.log'return name# 重新定义了备份文件命名规则
def rotator(source, dest):fsp = dest.rsplit(".",3)fsp.pop(1)dest = ".".join(fsp)os.rename(source,dest)remove_old_log(trfh)# 重新定义了旧备份文件删除规则
def remove_old_log(trfh):logdir = os.path.dirname(trfh.baseFilename)fname = os.path.basename(trfh.baseFilename)pattern = re.compile(fname.rsplit(".",1)[0] + "\." + trfh.extMatch.pattern[1:],re.ASCII)flist = os.listdir(logdir)loglist = []for f in flist:if re.match(pattern,f):loglist.append(f)loglist.sort(reverse=True)backupCount = trfh.backupCountlog_to_remove = loglist[backupCount:] if len(loglist) > backupCount else []for ltr in log_to_remove:os.remove(os.path.join(logdir,ltr))

trfLog.yaml 日志配置文件,handlers.trfhandler 下配置了一个自定义的处理程序

version: 1
disable_existing_loggers: false
formatters:simple:format: '[%(asctime)s - %(name)s - %(levelname)-8s] %(message)s'
handlers:console:class: logging.StreamHandlerformatter: simplelevel: DEBUGstream: ext://sys.stdouttrfhandler:# 通过()键,引用一个自定义的处理程序# ext:// 用来告诉dicConfig(),它后面的config.rtfHandler.my_rotating_file_handler 是配置以外的对象(): ext://config.trfHandler.my_timed_rotating_file_handlerlevel: DEBUGformatter: simple# 下面的标量都是提供给自定义的处理程序方法的参数filename: timed_rotated.logwhen: Sinterval: 2backupCount: 2encoding: utf8delay: Falseutc: FalseatTime: None
loggers:mylogger:level: DEBUGhandlers: [console,trfhandler]propagate: no

trfLogger.py 封装日志模块,使用dictConfig()读取日志配置文件以完成日志配置

# -*- coding:utf-8 -*-
import logging.config
import yaml
import osclass Logger():def __init__(self,logger_name=''):self.logger_name = logger_namecur_dir = os.path.dirname(__file__)log_conf = os.path.join(cur_dir, 'logconf', 'trflog.yaml')with open(log_conf, 'r', encoding="utf8") as f:config = yaml.safe_load(f.read())logging.config.dictConfig(config)def logger(self):logger = logging.getLogger(self.logger_name)return logger

main.py 主程序,测试日志功能

# -*- coding:utf-8 -*-
import logging
from config.trfLogger import Logger
import timemlogger = Logger('mylogger').logger()for i in range(10):mlogger.info(f'Message no. {i + 1}')time.sleep(1)

运行main.py程序,输出:

日志轮转,自定义备份文件命名规则



参考资料:

using-a-rotator-and-namer-to-customize-log-rotation-processing

customizing-handlers-with-dictconfig

logging-config-dict-externalobj

相关文章:

Python 在logging.config.dictConfig()日志配置方式下,使用自定义的Handler处理程序

文章目录 一、基于 RotatingFileHandler 的自定义处理程序二、基于 TimedRotatingFileHandler 的自定义处理程序 Python logging模块的基本使用、进阶使用详解 Python logging.handlers模块,RotatingFileHandler、TimedRotatingFileHandler 处理器各参数详细介绍 …...

Anaconda, Python, Jupyter和PyCharm介绍

目录 1 Anaconda, Python, Jupyter和PyCharm介绍 2 macOS通过Anaconda安装Python, Jupyter和PyCharm 3 使用终端创建虚拟环境并安装PyTorch 4 安装PyCharm并导入Anaconda虚拟环境 5 Windows操作系统下Anaconda与PyCharm安装 6 通过 Anaconda Navigator 创建 TensorFlow 虚…...

axios 各种方式的请求 示例

GET请求 示例一&#xff1a; 服务端代码 GetMapping("/f11") public String f11(Integer pageNum, Integer pageSize) {return pageNum " : " pageSize; }前端代码 <template><div class"home"><button click"getFun1…...

基于开源模型搭建实时人脸识别系统(四):人脸质量

续人脸识别实战之基于开源模型搭建实时人脸识别系统&#xff08;三&#xff09;&#xff1a;人脸关键点、对齐模型概览与模型选型_CodingInCV的博客-CSDN博客 不论对于静态的人脸识别还是动态的人脸识别&#xff0c;我们都会面临一个问题&#xff0c;就是输入的人脸图像的质量可…...

【开发笔记】ubuntu部署指定版本的前后端运行环境(npm nodejs mysql)

目录 1 背景2 环境要求3 部署流程3.1 npm的安装3.2 nodejs的安装3.3 MySQL的安装 4 可能的问题 1 背景 在远程服务器上的Ubuntu系统中&#xff0c;部署指定版本的前后端项目的运行环境 2 环境要求 npm 9.5.1Nodejs v18.16.1MySQL 8.0.33 3 部署流程 3.1 npm的安装 通过安…...

用于优化开关性能的集成异质结二极管的4H-SiC沟道MOSFET

标题&#xff1a;4H-SiC Trench MOSFET with Integrated Heterojunction Diode for Optimizing Switching Performance 摘要 本研究提出了一种新型的4H-SiC沟道MOSFET&#xff0c;其在栅槽底部集成了异质结二极管&#xff08;HJD-TMOS&#xff09;&#xff0c;并通过TCAD模拟进…...

优化个人博客总结

前面学习完怎么搭建个人博客&#xff0c;后面要做的就是排版优化自己的博客了&#xff0c;今天通过教程学习到了然后更爱美化其中的效果&#xff0c;还通过改写代码来带到基本的效果展示&#xff0c;同时也把最开始学习的计算速成课的笔记输出在上面&#xff0c;这也是一个很好…...

从零构建深度学习推理框架-9 再探Tensor类,算子输入输出的分配

再探Tensor类&#xff1a; 第二节中我们编写的Tensor类其实并不能满足我们的使用需要&#xff0c;我们将在这一节以代码阅读的方式来看看一个完全版本的Tensor应该具备怎样的要素&#xff0c;同时我们对Tensor类的分析来看看在C中一个设计好的类应该是怎么样的。 Tensor<fl…...

Vue使用element-ui

main.js配置 //引入Vue import Vue from vue //引入App import App from ./App.vue//完整引入 //引入ElementUI组件库 // import ElementUI from element-ui; //引入ElementUI全部样式 // import element-ui/lib/theme-chalk/index.css;//按需引入 import { Button,Row,DatePi…...

使用ApplicationRunner简化Spring Boot应用程序的初始化和启动

ApplicationRunner这个接口&#xff0c;我们一起来了解这个组件&#xff0c;并简单使用它吧。&#x1f92d; 引言 在开发Spring Boot应用程序时&#xff0c;应用程序的初始化和启动是一个重要的环节。ApplicationRunner是Spring Boot提供的一个有用的接口&#xff0c;可以帮助…...

Vue 2.x 项目升级到 Vue 3详细指南【修改清单】

文章目录 前言0.迁移过程1. 安装 Vue 32. 逐一处理迁移中的警告3. 迁移全局和内部 API4. 迁移 Vue Router 和 Vuex5. 处理其他的不兼容变更 1. Vue3特性1. Composition API2. 更好的性能3. 更好的 TypeScript 支持4. 多个根元素5. Suspense 组件6. Teleport 组件7. 全局 API 的…...

【算法日志】贪心算法刷题:重叠区问题(day31)

代码随想录刷题60Day 目录 前言 无重叠区间&#xff08;筛选区间&#xff09; 划分字母区间&#xff08;切割区间&#xff09; 合并区间 前言 今日的重点是掌握重叠区问题。 无重叠区间&#xff08;筛选区间&#xff09; int eraseOverlapIntervals(vector<vector<in…...

基于Jenkins构建生产CICD环境、jenkins安装

目录 Jenkins简介 安装配置Jenkins Jenkins简介 Jenkins是一个用Java编写的开源的持续集成工具。在与Oracle发生争执后&#xff0c;项目从Hudson项目独立。官方网站&#xff1a;https://jenkins.io/。 Jenkins提供了软件开发的持续集成服务。它运行在Servlet容器中&#xff…...

基于Java SpringBoot+vue+html 的地方美食系统(2.0版本)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,csdn、博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统流程的分析3.1 用户管理的流程3.2个人中心管理流程3.3登录流程 4系统设计…...

opencv-gpu版本编译(添加java支持,可选)实现硬解码

目录 opencv gpu版本编译&#xff0c;实现硬解码&#xff0c;加速rtsp视频流读取1、准备文件2、复制 NVCUVID 头文件到 cuda 安装目录 include3、安装相关依赖4、 执行cmake5、编译安装6、测试 opencv gpu版本编译&#xff0c;实现硬解码&#xff0c;加速rtsp视频流读取 前置条…...

数据分析问答总结

一、SQL窗口函数 1.是什么 OLAP&#xff08;Online Anallytical Processing联机分析处理&#xff09;&#xff0c;对数据库数据进行实时分析处理。 2.基本语法&#xff1a; <窗口函数>OVER &#xff08;PARTITION BY <用于分组的列名> ORDER BY <用于排序的…...

Python学习笔记_实战篇(二)_django多条件筛选搜索

多条件搜索在很多网站上都有用到&#xff0c;比如京东&#xff0c;淘宝&#xff0c;51cto&#xff0c;等等好多购物教育网站上都有&#xff0c;当然网上也有很多开源的比楼主写的好的多了去了&#xff0c;仅供参考&#xff0c;哈哈 先来一张效果图吧&#xff0c;不然幻想不出来…...

【生态经济学】利用R语言进行经济学研究技术——从数据的收集与清洗、综合建模评价、数据的分析与可视化、因果推断等方面入手

查看原文>>>如何快速掌握利用R语言进行经济学研究技术——从数据的收集与清洗、综合建模评价、数据的分析与可视化、因果推断等方面入手 近年来&#xff0c;人工智能领域已经取得突破性进展&#xff0c;对经济社会各个领域都产生了重大影响&#xff0c;结合了统计学、…...

xml中的vo是干什么用的

在Java中&#xff0c;VO&#xff08;Value Object&#xff09;是一种常见的设计模式&#xff0c;用于表示纯粹的数据对象。VO 通常用于在不同层或模块之间传递数据&#xff0c;并且它们的主要目的是封装和组织数据&#xff0c;而不包含业务逻辑。 VO 在Java中的具体作用有以下…...

现代企业数据泄露的原因分析与建议

近年来&#xff0c;随着信息技术的飞速发展&#xff0c;数据已经成为现代企业不可或缺的发展资源。然而&#xff0c;随之而来的数据泄露危机&#xff0c;给个人、企业甚至整个社会带来了巨大的风险与威胁。本文将综合探讨企业数据泄露的主要途径和原因&#xff0c;并提出防护建…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...