问题

封装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. [FAQ] IDE: Goland 注释符后面添加空行

    如图所示,Code Style 对应语言 Go 勾选上注释空行的选项. Refer:Goland官网 Goland下载 Link:https://www.cnblogs.com/farwish/p/1 ...

  2. Phpstrom开发工具Sftp的使用

  3. HTML页面 IE 兼容性设置

    网页第一行: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/html ...

  4. width:100%与width:auto区别

    小知识 width:100%与width:auto区别 width:100% : 子元素的 content 撑满父元素的content,如果子元素还有 padding.border等属性,或者是在父元 ...

  5. 多进程池Flask实战应用

    多进程池Flask实战应用 import json import math import flask from concurrent.futures import ProcessPoolExecuto ...

  6. Vue——模板语法

    Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据.所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析 ...

  7. 莫烦tensorflow学习记录 (1)session会话控制、variable变量、placeholder传入值

    https://mofanpy.com/tutorials/machine-learning/tensorflow/session/ Session 会话控制 #https://mofanpy.com ...

  8. 微服务新体验之Aspire初体验

    安装aspire 查看vs版本 我这的版本是17.9.7,不支持aspire,所以需要升级 更新VS 点击 帮助->检查更新 点击更新 静等安装升级 创建aspire项目 项目创建成功,如下图 ...

  9. Js实现任意位置缩放图片,深入理解背后原理

    前言 本文将用一个简单的例子详细讲解如何用原生JS一步步实现完整的任意位置缩放图片功能,无任何第三方依赖,指针事件 进行多端统一的事件监听,干货满满. 完整代码 为提升阅读体验,正文中代码展示有部分省 ...

  10. bashrc和profile区别

    转载请注明出处: 作用与目的: .bashrc:这个文件主要用于配置和自定义用户的终端环境和行为.每次启动新的终端时,.bashrc文件都会被执行,加载用户设置的环境变量.别名.函数等.这使得用户能够 ...