Python日志打印失效?一招解决控制台无输出、无法记录到日志文件

Python日志打印失效解决方案
部署运行你感兴趣的模型镜像

问题:如下源代码无法在控制台打印输出消息

import logging
from config.conf import cm

class Log:
    def __init__(self):
        # self.logger = logging.getLogger()
        if not self.logger.handlers:
            self.logger.setLevel(logging.DEBUG)

            # 创建一个handle写入文件
            fh = logging.FileHandler(cm.log_file, encoding='utf-8')
            fh.setLevel(logging.DEBUG)

            # 创建一个handle输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)

            # 定义输出的格式
            formatter = logging.Formatter(self.fmt)
            fh.setFormatter(formatter)
            ch.setFormatter(formatter)

            # 添加到handle
            self.logger.addHandler(fh)
            self.logger.addHandler(ch)

    @property
    def fmt(self):
        return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'


logT = Log().logger

if __name__ == '__main__':
    logT.info('hello world')

解决方法:在getLogger方法中增加记录log名称如“jxc_logger”,其会重新初使化一个全新对象,否则会传递出一个已存在对象。

import logging
from config.conf import cm

class Log:
    def __init__(self):
        self.logger = logging.getLogger('jxc_logger')
        if not self.logger.handlers:
            self.logger.setLevel(logging.DEBUG)

            # 创建一个handle写入文件
            fh = logging.FileHandler(cm.log_file, encoding='utf-8')
            fh.setLevel(logging.DEBUG)

            # 创建一个handle输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)

            # 定义输出的格式
            formatter = logging.Formatter(self.fmt)
            fh.setFormatter(formatter)
            ch.setFormatter(formatter)

            # 添加到handle
            self.logger.addHandler(fh)
            self.logger.addHandler(ch)

    @property
    def fmt(self):
        return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'


logT = Log().logger

if __name__ == '__main__':
    logT.info('hello world')

雷区分析:

logging.getLogger('jxc_logger')与logging.getLogger()的不同表现:
logging.getLogger('jxc_logger')中getLogger方法如果添加了“名称name:jxc_logger”参数值,则logging会重新实例化一个全新对象赋值传递给新记录变量,其self.logger.handlers的长度length等于0;
而如果logging.getLogger()中getLogger方法没有传“name名称”参数值,则logging会将已创建存在的logging对象赋值传递给新记录变量,其self.logger.handlers的长度length大于0,则if分支后面语句无法执行。

另它:

在项目根目录或测试文件根目录,添加pytest.ini文件
配置如下:
[pytest]

log_cli = 1
log_cli_level = DEBUG
log_cli_format = %(asctime)s - %(filename)s:%(lineno)d - %(funcName)s - %(levelname)s - %(message)s

分享:

实例1

a、新建API_log.py

import logging
from config.conf import cm

class loger():
    def logering(self):
        # 创建logger对象
        logger = logging.getLogger('test_logger')

        # 设置日志等级
        logger.setLevel(logging.DEBUG)

        # 追加写入文件a ,设置utf-8编码防止中文写入乱码
        # test_log = logging.FileHandler('test.log', 'a', encoding='utf-8')
        test_log = logging.FileHandler(cm.log_file, encoding='utf-8')

        # 向文件输出的日志级别
        test_log.setLevel(logging.DEBUG)

        # 向文件输出的日志信息格式
        formatter = logging.Formatter(
            '%(asctime)s | %(filename)s | %(funcName)s | line:%(lineno)d | %(levelname)s | %(message)s ')

        test_log.setFormatter(formatter)

        # 加载文件到logger对象中
        logger.addHandler(test_log)

        return logger


if __name__ == "__main__":
    pass
log_test = loger().logering()

b、新建melogs.py调用API_log.loger

import pytest
import utils.API_log as API_log

# 实例化日志方法
logger = API_log.log_test

# 请求登陆接口,获取session状态
def test_001():
    url = 'http://127.0.0.1:5000/login'

    data = {
        'username': 'admin',
        'password': 'admin123'
    }
    logger.info(f"请求路径:{url} , 请求参数 {data}")
    assert 1==1

if __name__ == '__main__':
    pytest.main(["-v", "meTest/metrytest.py"])

实例2

a、新建logger.py

import logging
from config.conf import cm

class Log:
    def __init__(self):
        
        self.logger = logging.getLogger('jxc_logger')

        if not self.logger.handlers:
            self.logger.setLevel(logging.DEBUG)

            # 创建一个handle写入文件
            fh = logging.FileHandler(cm.log_file, encoding='utf-8')
            fh.setLevel(logging.DEBUG)

            # 创建一个handle输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)

            # 定义输出的格式
            formatter = logging.Formatter(self.fmt)
            fh.setFormatter(formatter)
            ch.setFormatter(formatter)

            # 添加到handle
            self.logger.addHandler(fh)
            self.logger.addHandler(ch)

    @property
    def fmt(self):
        return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'


log = Log().logger

if __name__ == '__main__':
    log.info('hello world')

b、新建metrypytest.py调用logger.log

import pytest
from utils.logger import log

def test_addition():
    log.info("ME 1")
    assert 1 + 1 == 2

def test_subtraction():
    log.info("ME 2")
    assert 5 - 3 == 2

if __name__ == '__main__':
    pytest.main(["-v","meTest/metrytest.py"])

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BatyTao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值