如何在Python 3中高效记录字节字符串日志?
Python3日志输出字节串的解决方案
Python3内置logging的核心限制
Python3的logging模块默认会将所有日志参数转换为字符串类型。当传入bytes对象时,会直接调用str(bytes),导致输出带b''标识的内容,无法像Python2那样直接输出原始字节内容。
解决方案
1. 自定义日志处理器与格式化器(推荐)
通过继承logging的处理器和格式化器,实现对bytes对象的直接输出,既保留Python3日志系统的原有功能,又兼容Python2的字节串输出逻辑。
代码示例:
import logging from logging import StreamHandler, Formatter class BytesFormatter(Formatter): def format(self, record): # 针对bytes类型消息直接格式化,不转换为str if isinstance(record.msg, bytes): return record.msg % record.args # 非bytes消息按原有逻辑处理 return super().format(record) class BytesStreamHandler(StreamHandler): def emit(self, record): try: msg = self.format(record) if isinstance(msg, bytes): # 直接写入字节串,追加换行符的字节形式 self.stream.write(msg) self.stream.write(self.terminator.encode('utf-8')) else: # 字符串消息按原有逻辑写入 self.stream.write(msg + self.terminator) self.flush() except RecursionError: raise except Exception: self.handleError(record) # 业务代码部分 tar_inc_page = 1024 elem = lambda: None elem.name = b'_demo_vec' elem.base = 0x2000003c elem.size = 4 # 日志配置 LOG = logging.getLogger(__name__) LOG.setLevel(logging.INFO) # 移除默认处理器,避免重复输出 for handler in LOG.root.handlers[:]: LOG.root.removeHandler(handler) # 添加自定义处理器和格式化器 handler = BytesStreamHandler() handler.setFormatter(BytesFormatter()) LOG.addHandler(handler) # 输出日志 LOG.info(b"using tar inc page size of %d" % tar_inc_page) LOG.info(b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size))
运行后输出与Python2一致:
INFO:main:using tar inc page size of 1024
INFO:main:_demo_vec = 0x2000003c + 0x0004
2. 显式解码字节串为字符串(最简单)
如果你的字节串均为UTF-8编码,直接在日志调用时将bytes解码为str即可,无需修改日志系统:
import logging logging.basicConfig(level=logging.INFO) LOG = logging.getLogger(__name__) # 业务代码同前... LOG.info((b"using tar inc page size of %d" % tar_inc_page).decode('utf-8')) LOG.info((b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size)).decode('utf-8'))
3. 使用跨版本兼容的第三方日志库
若需要全面兼容Python2和Python3,可使用loguru库——它原生支持Python2.7及Python3.5+,且能通过配置实现类似Python2的字节串输出效果。
安装命令:
pip install loguru
使用示例:
from loguru import logger # 业务代码同前... # 配置日志直接输出原始内容 logger.add(lambda msg: print(msg, end=''), format="{message}") logger.info(b"using tar inc page size of %d" % tar_inc_page) logger.info(b"%8s = 0x%08x + 0x%04x" % (elem.name, elem.base, elem.size))
总结
- Python3内置
logging默认不支持直接输出字节串,但可通过自定义处理器和格式化器实现。 - 最简便的方式是显式将UTF-8编码的字节串解码为字符串。
- 跨版本兼容场景可选择
loguru这类第三方库。
内容的提问来源于stack exchange,提问作者personal_cloud
相关产品推荐
相关产品推荐

