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中的具体作用有以下…...
现代企业数据泄露的原因分析与建议
近年来,随着信息技术的飞速发展,数据已经成为现代企业不可或缺的发展资源。然而,随之而来的数据泄露危机,给个人、企业甚至整个社会带来了巨大的风险与威胁。本文将综合探讨企业数据泄露的主要途径和原因,并提出防护建…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
