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.xxx,xxx为数字。
接下来将使用自定义处理程序,将生成的备份日志文件的后缀改为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.xxx,xxx为格式化的日期时间,如: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请求 示例一: 服务端代码 GetMapping("/f11") public String f11(Integer pageNum, Integer pageSize) {return pageNum " : " pageSize; }前端代码 <template><div class"home"><button click"getFun1…...
基于开源模型搭建实时人脸识别系统(四):人脸质量
续人脸识别实战之基于开源模型搭建实时人脸识别系统(三):人脸关键点、对齐模型概览与模型选型_CodingInCV的博客-CSDN博客 不论对于静态的人脸识别还是动态的人脸识别,我们都会面临一个问题,就是输入的人脸图像的质量可…...
【开发笔记】ubuntu部署指定版本的前后端运行环境(npm nodejs mysql)
目录 1 背景2 环境要求3 部署流程3.1 npm的安装3.2 nodejs的安装3.3 MySQL的安装 4 可能的问题 1 背景 在远程服务器上的Ubuntu系统中,部署指定版本的前后端项目的运行环境 2 环境要求 npm 9.5.1Nodejs v18.16.1MySQL 8.0.33 3 部署流程 3.1 npm的安装 通过安…...
用于优化开关性能的集成异质结二极管的4H-SiC沟道MOSFET
标题:4H-SiC Trench MOSFET with Integrated Heterojunction Diode for Optimizing Switching Performance 摘要 本研究提出了一种新型的4H-SiC沟道MOSFET,其在栅槽底部集成了异质结二极管(HJD-TMOS),并通过TCAD模拟进…...
优化个人博客总结
前面学习完怎么搭建个人博客,后面要做的就是排版优化自己的博客了,今天通过教程学习到了然后更爱美化其中的效果,还通过改写代码来带到基本的效果展示,同时也把最开始学习的计算速成课的笔记输出在上面,这也是一个很好…...
从零构建深度学习推理框架-9 再探Tensor类,算子输入输出的分配
再探Tensor类: 第二节中我们编写的Tensor类其实并不能满足我们的使用需要,我们将在这一节以代码阅读的方式来看看一个完全版本的Tensor应该具备怎样的要素,同时我们对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这个接口,我们一起来了解这个组件,并简单使用它吧。🤭 引言 在开发Spring Boot应用程序时,应用程序的初始化和启动是一个重要的环节。ApplicationRunner是Spring Boot提供的一个有用的接口,可以帮助…...
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 目录 前言 无重叠区间(筛选区间) 划分字母区间(切割区间) 合并区间 前言 今日的重点是掌握重叠区问题。 无重叠区间(筛选区间) int eraseOverlapIntervals(vector<vector<in…...
基于Jenkins构建生产CICD环境、jenkins安装
目录 Jenkins简介 安装配置Jenkins Jenkins简介 Jenkins是一个用Java编写的开源的持续集成工具。在与Oracle发生争执后,项目从Hudson项目独立。官方网站:https://jenkins.io/。 Jenkins提供了软件开发的持续集成服务。它运行在Servlet容器中ÿ…...
基于Java SpringBoot+vue+html 的地方美食系统(2.0版本)
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,csdn、博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统流程的分析3.1 用户管理的流程3.2个人中心管理流程3.3登录流程 4系统设计…...
opencv-gpu版本编译(添加java支持,可选)实现硬解码
目录 opencv gpu版本编译,实现硬解码,加速rtsp视频流读取1、准备文件2、复制 NVCUVID 头文件到 cuda 安装目录 include3、安装相关依赖4、 执行cmake5、编译安装6、测试 opencv gpu版本编译,实现硬解码,加速rtsp视频流读取 前置条…...
数据分析问答总结
一、SQL窗口函数 1.是什么 OLAP(Online Anallytical Processing联机分析处理),对数据库数据进行实时分析处理。 2.基本语法: <窗口函数>OVER (PARTITION BY <用于分组的列名> ORDER BY <用于排序的…...
Python学习笔记_实战篇(二)_django多条件筛选搜索
多条件搜索在很多网站上都有用到,比如京东,淘宝,51cto,等等好多购物教育网站上都有,当然网上也有很多开源的比楼主写的好的多了去了,仅供参考,哈哈 先来一张效果图吧,不然幻想不出来…...
【生态经济学】利用R语言进行经济学研究技术——从数据的收集与清洗、综合建模评价、数据的分析与可视化、因果推断等方面入手
查看原文>>>如何快速掌握利用R语言进行经济学研究技术——从数据的收集与清洗、综合建模评价、数据的分析与可视化、因果推断等方面入手 近年来,人工智能领域已经取得突破性进展,对经济社会各个领域都产生了重大影响,结合了统计学、…...
xml中的vo是干什么用的
在Java中,VO(Value Object)是一种常见的设计模式,用于表示纯粹的数据对象。VO 通常用于在不同层或模块之间传递数据,并且它们的主要目的是封装和组织数据,而不包含业务逻辑。 VO 在Java中的具体作用有以下…...
现代企业数据泄露的原因分析与建议
近年来,随着信息技术的飞速发展,数据已经成为现代企业不可或缺的发展资源。然而,随之而来的数据泄露危机,给个人、企业甚至整个社会带来了巨大的风险与威胁。本文将综合探讨企业数据泄露的主要途径和原因,并提出防护建…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
