解决 logging 写入文件报错 UnicodeEncodeError: ‘gbk‘ codec can‘t encode character

解决 logging 写入文件报错 UnicodeEncodeError: 'gbk' codec can't encode character

写作背景

承接 上文 ,今天跑程序,偶然发现了一个 bug,就是写入文件的时候报错编码不对,这也是我第一次遇到这个问题,写下这篇博客以提供解决思路。在这里插入图片描述

备注

后来我又将上文中的代码进行了微调,微调后的代码如下:

major_log_path = '主日志'
error_log_path = '记录报错的日志'
logging.basicConfig(
    format='%(asctime)s | %(filename)s[line:%(lineno)d] | %(levelname)s | Message: %(message)s',
    filename=major_log_path,
    filemode='a',
    level='INFO'
)
log.logger.logger.handlers = logging.getLogger().handlers
exc_info_logger = logging.getLogger('exc')
exc_info_logger.propagate = False
file_handler = logging.FileHandler(error_log_path)
file_handler.setFormatter(
    logging.Formatter(
        fmt='%(asctime)s | %(filename)s[line:%(lineno)d] | %(levelname)s | Message: %(message)s'
    )
)
exc_info_logger.addHandler(file_handler)

问题分析

既然出现这个问题,那一定是 写入日志内容的时候出错了 ,再一想,只有 FileHandler 会向文件中写入内容,所以我们先看一下 FileHandler 的源码,如下图所示。
在这里插入图片描述
可以看到,初始化的时候可以设置 encoding ,即 编码方式 ,那解决办法就是 在实例化 FileHandler 的时候指定编码格式就好了 。即

logging.FileHandler('【日志文件】', encoding='utf-8')

问题再现

设置编码以后,还是报了错,那说明不只是我的代码里明确的 FileHandler 没有指定编码,在我的代码中没有明确体现的地方也还有一个等待我指定编码。那么,最大的可疑之处就在 basicConfig 中。
看一下 basicConfig 的源码,如下图所示。
在这里插入图片描述
可以看到,光标处有实例化 FileHandler 的代码。

这里代码的逻辑是:

  1. 如果 root 没有 handler (确实没有,因为初始化 root 的时候就没有,而且代码运行到 basicConfig 的时候还未曾向其中添加 handler)就通过传入的参数添加 handler
  2. 我传入的参数中没有 handlersstream ,但是有 filename ,所以会根据我传入的 filenamefilemode 实例化 FileHandler

如果想要指定编码,那就要在这里的 FileHandler 中指定编码。

  1. 如果想要确定某一种编码,可以修改为:
    logging.FileHandler(filename, mode, encoding='【默认编码】')
    
  2. 如果想要根据自己的输入改变编码,则修改为:
    encoding = kwargs.pop('encoding', '【默认编码】')
    if filename:
        h = FileHandler(filename, mode, encoding)
    
    这时候就可以在设置 basicConfig 的时候指定编码了。
  • 注:默认编码 是要你自己设置一个喜欢的编码,而不是就叫做 “默认编码”,我设置的是 utf-8

再次尝试,成功完成任务!!!




结尾

有想要一起学习 python 的小伙伴可以 私信我 进群哦。

以上就是我要分享的内容,因为 学识尚浅会有不足,还 请各位大佬指正
有什么问题也可在评论区留言。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值