问题

封装logging文件名称为:A.py

调用A模块的文件名称为:B.py

二次封装了logging日志模块,根据需要,传入level,判断等级,调用logging模块的info、debug等日志输出的方法;使用过程中发现,在B文件调用logging模块的方法,打印的filename为A.py,就是还是在日志封装文件,而非是调用的文件,导致出错,也只能看到是日志封装文件,而不知道具体是哪个文件报错了;

输出的日志文件,filename不是xx_mysql.py,而是my_log.py

原始代码_打印的filename不对

原始的my_log.py文件的代码_打印的filename不对

class MyLog:
def my_log(self, level, msg):
my_logger = logging.getLogger("logsMessage") my_logger.setLevel("DEBUG") # 设置日志的收集级别 # 设置日志的输出格式
formatter = logging.Formatter('%(asctime)s-%(levelname)s-%(filename)s-%(name)s-日志信息:%(message)s') # ---- === 日志可输出到日志和具体的文件 ===
ch = logging.StreamHandler()
ch.setFormatter(formatter) # 2、 输出到制定文件,将日志信息收集到文件
# 3、 输出到文件拓展,每天生成一个文件,保存近5天的的log文件,防止文件过大的
logs_path = os.path.join(project_path.logs_path_day, 'log') # 先将when改成Minutes,每隔2分钟,生成一个文件 interval=1,
file_hander = TimedRotatingFileHandler(filename=logs_path, when='midnight') # 设置生成日志文件名的格式,以年-月-日来命名
# suffix设置,会生成文件名为log.2020-02-25.log # 按时间S的 命名格式 %Y-%m-%d %H-%M-%S.log
file_hander.suffix = "%Y-%m-%d.log" # extMatch是编译好正则表达式,用于匹配日志文件名后缀
# 需要注意的是suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。
file_hander.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
file_hander.setFormatter(formatter) # 日志收集器添加一个渠道,分别将输出到控制台、输出到具体文件的日志收集器,添加到渠道
my_logger.addHandler(ch)
my_logger.addHandler(file_hander) # 传进日志级别,根据级别,输出对应的级别的日志信息
if level == 'DEBUG':
my_logger.debug(msg)
elif level == 'INFO':
my_logger.info(msg)
elif level == 'WARNING':
my_logger.warning(msg)
elif level == 'ERROR':
my_logger.error(msg)
elif level == 'EXCEPTION':
my_logger.exception(msg)
elif level == 'CRITICAL':
my_logger.critical(msg) my_logger.removeHandler(ch)
my_logger.removeHandler(file_hander) def debug(self, msg):
"""
输出日志级别为debug的日志
msg:日志信息
"""
self.my_log("DEBGU", msg)

原因是,请参考logging的源码

https://blog.csdn.net/qq_34026204/article/details/125810425

解决方法_使用logger使用

不再进行info、debug等方法的二次封装,直接通过logger.info(),输出日志,打印的文件名正确

遇到问题:结合pytest使用时,pytest有带log,导致pytest执行用例时,不输出日志,日志也没有写入到文件;

文件Log_print.py

class LogPrint:
def __init__(self):
# my_logger,获取到getLogger().info(),获取到的filename正确,但通过封装后,filename则是当前logname
self.logger = logging.getLogger() # 设置日志的收集级别, 必须要设置为DEBUG,默认收集warning级别以上的错误(不设置收集不到info error的日志)
self.logger.setLevel("DEBUG") # 当前已有handler,则不再新增,使用已有的handlers打印和输出日志
     !!! 结合pytest使用时,pytest有带log,导致pytest执行用例时,不输出日志,日志也没有写入到文件
if not self.logger.handlers:
formatter = logging.Formatter('%(asctime)s-%(levelname)s-[%(filename)s:%(lineno)s]-日志信息:%(message)s') # === 1、设置控制台的输出渠道 设置日志输出的格式===
ch = logging.StreamHandler()
ch.setFormatter(formatter) # === 2、设置定期生成的日志文件的渠道 ====
logs_path = os.path.join(GetPath.logs_path_day, 'log')
file_hander = TimedRotatingFileHandler(filename=logs_path, when='midnight', backupCount=7) # suffix和extMatch要与设置的when匹配,若设置为日,则传入的正则suffix应该是日:"%Y-%m-%d.log"
file_hander.suffix = "%Y-%m-%d.log" # suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。 re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
file_hander.extMatch = r"^\d{4}-\d{2}-\d{2}.log$"
file_hander.extMatch = re.compile(file_hander.extMatch)
file_hander.setFormatter(formatter) # 将设置好的渠道,添加到日志收集器
self.logger.addHandler(ch)
self.logger.addHandler(file_hander)

再次优化的log:

优化,初始化log时,将现有的都移除掉,重新创建!!!

class LogPrint:

    def __init__(self):
self.logger = logging.getLogger()
self.logger.setLevel("DEBUG") # == 1、将现有的handlers移除,后面再创建 ==
while self.logger.hasHandlers():
for handler in
self.logger.handlers:
self.logger.removeHandler(handler)
self.log_colors_config = {
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red',
} self.color_fmt = colorlog.ColoredFormatter(
'%(log_color)s%(asctime)s [%(filename)s:%(funcName)s:%(lineno)s] [%(levelname)s]: %(message)s',
log_colors=self.log_colors_config) # -日志信息
self.formatter = logging.Formatter(
'%(asctime)s [%(filename)s:%(funcName)s:%(lineno)s] [%(levelname)s]: %(message)s') self.logger.addHandler(self.get_console_handler())
self.logger.addHandler(self.get_file_handler())

具体使用

        from Common.log_print import LogPrint
LogPrint().logger.info("log print test")

输出日志

参考:https://blog.csdn.net/Moonlight_16/article/details/123334339

python 二次封装logging,导致日志输出的filename错误及优化封装的更多相关文章

  1. Java学习-046-日志抓取合并后排序问题解决方案之 --- log4j 二次定制,实现日志输出添加延时10ms

    自3月25至今,已经好久没有写学习日志了,今天在写日志抓取合并的小方法,发现抓取后的日志并米有依据系统执行的日志顺序排序.日志抓取排列逻辑如下: 通过日志标识,从各个日志文件(例如 use.log,e ...

  2. 通配置文件的方式控制java.util.logging.Logger日志输出

    转自:http://zochen.iteye.com/blog/616151 简单的实现了下利用JDK中类java.util.logging.Logger来记录日志.主要在于仿照log4j方式用配置文 ...

  3. Python学习笔记:logging(日志处理)

    在一个软件中,日志是可以说必不可少的一个组成部分,通常会在定位客户问题或者记录软件使用情况等场景中会用到.logging模板块是Python的一个内置标准库,用于实现对日志的控制输出,对于平常的日志输 ...

  4. springboot(二).springboot整合logback用于日志输出

    springboot整合logback用于日志输出 我们项目的基本框架已经完成,http请求已经可以访问,现在给我们的框架添加日志记录的功能并能将每天的记录记录到文件中去 在这里,我们使用logbac ...

  5. Linux(7)- Nginx.conf主配置文件、Nginx虚拟主机/访问日志/限制访问IP/错误页面优化、Nginx反向代理、Nginx负载均衡

    一.Nginx.conf主配置文件 Nginx主配置文件conf/nginx.conf是一个纯文本类型的文件,整个配置文件是以区块的形式组织的.一般,每个区块以一对大括号{}来表示开始与结束. 核心模 ...

  6. python logging模块日志输出

    import logging logger = logging.getLogger(__name__) logger.setLevel(level = logging.INFO) handler = ...

  7. log4j学习(二)不同类的日志输出到不同的文件

    目的:一个应用中有两个不同作用的后台服务,我们需要把他们的日志分开,存放到2个不同的日志文件中. 办法:需要在log4j.properties文件中配置两个不同的logger和对应的appender ...

  8. python 自动化之路 logging日志模块

    logging 日志模块 http://python.usyiyi.cn/python_278/library/logging.html 中文官方http://blog.csdn.net/zyz511 ...

  9. ASP.NET Core 2.1 : 十二.内置日志、使用Nlog将日志输出到文件

    应用离不开日志,虽然现在使用VS有强大的调试功能,开发过程中不复杂的情况懒得输出日志了(想起print和echo的有木有),但在一些复杂的过程中以及应用日常运行中的日志还是非常有用. ASP.NET ...

  10. Django 日志输出及打印--logging

    Django使用python自带的logging作为日志打印工具. logging是线程安全的,主要分为4部分: Logger 用户使用的直接接口,将日志传递给Handler Handler 控制日志 ...

随机推荐

  1. 扎克伯格说,Llama3-8B还是太大了,量化、剪枝、蒸馏准备上!

    扎克伯格说,Llama3-8B还是太大了,不适合放到手机中,有什么办法? 量化.剪枝.蒸馏,如果你经常关注大语言模型,一定会看到这几个词,单看这几个字,我们很难理解它们都干了些什么,但是这几个词对于现 ...

  2. dotnet 警惕 Assembly.Location 返回空

    在大部分情况下,获取当前所运行的应用程序的所在路径时,常用的就是 Assembly.Location 属性,按照之前的经验,使用 Assembly.Location 是最为稳定的做法,然而在 dotn ...

  3. OpenTK 垂直同步对刷新率的影响

    本文将和大家介绍 Vsync 垂直同步的开启对 OpenTK 应用的刷新率的影响 在上一篇博客 OpenTK 入门 初始化窗口 告诉了大家如何初始化 OpenTK 承载 OpenGL 的窗口的应用,在 ...

  4. dotnet 读 WPF 源代码笔记 渲染层是如何将字符 GlyphRun 画出来的

    从业务代码构建出来 GlyphRun 对象,在 WPF 的渲染层里,如何利用 GlyphRun 提供的数据将字符在界面呈现出来.本文将和大家聊聊从 WPF 的渲染层获取到 GlyphRun 数据,到调 ...

  5. kubernetes-1.26安装

    一.环境准备 k8s集群角色 IP 主机名 安装组件 配置 控制节点 192.168.10.10 master apiserver.controller-manager.scheduler.etcd. ...

  6. Centos下虚拟环境的创建以及python3安装

    1.python3自己安装 ln -s /usr/local/python3/bin/python3.6 /usr/bin/python3 ln -s /usr/local/python3/bin/p ...

  7. js原型,原型链(不断补充中)

    1.如何使用构造器? function Person(name, age) { this.name = name; this.age = age; } var man = new Person(&qu ...

  8. rails byebug

    Gemfile里添加 gem 'byebug' bundle install 在要打断点的地方写 byebug byebug -h #帮助 c 放行,入下走 n 单行调适 q 退出进行 启动异步任务推 ...

  9. vben集成keycloak

    前言 公司的项目是vben admin框架需要集成keycloak,那keycloak大家应该都不陌生了,就是统一认证的一个系统简称IDS.之前用过cas,并重构过cas的前端界面,所以对此也是比较熟 ...

  10. kettle使用4-使用Pan.bat执行转换、Kitchen.bat执行作业

    一.直接在spoon中执行作业 使用bat文件执行速度比执行在spoon.bat中执行慢很多,如果少数几个任务,可以直接在spoon中执行. 1.新建作业 2.在通用中,新建START 任务执行的时间 ...