如何让Python logging日志在MacOS自带Console.app中正常显示
问题原因
MacOS 10.12及以上版本采用统一日志系统(Unified Logging)替代了传统syslog服务。Python标准库自带的logging.handlers.SysLogHandler走旧版syslog协议发送日志,这类日志会被系统默认标记为低优先级遗留日志,不会在Console.app默认视图展示,调整address、facility参数无法绕过该过滤规则。
解决方案
方案1:无额外依赖(适合快速调试)
直接调用系统自带的logger命令发送日志到统一日志系统,不需要安装第三方库:
import logging import subprocess import time logger = logging.getLogger() logger.setLevel(logging.INFO) # 对接系统logger命令,-t指定日志标识,-i自动附带进程PID log_pipe = subprocess.Popen( ['logger', '-t', 'MyPythonApp', '-i'], stdin=subprocess.PIPE, text=True ).stdin handler = logging.StreamHandler(log_pipe) handler.setFormatter(logging.Formatter('%(message)s')) logger.addHandler(handler) while True: logger.info('I am visible from Console.app now :)') time.sleep(1)
运行代码后打开Console.app,选中当前设备,在搜索框输入你设置的日志标识(示例中为MyPythonApp),即可看到每秒输出的日志及对应时间、PID等元信息。
方案2:原生接口对接(适合正式应用)
安装官方系统框架的Python绑定,直接调用MacOS原生os_log接口,支持子系统分类、级别过滤等完整特性,性能更优:
- 先安装依赖:
pip3 install pyobjc-framework-OSLog
- 代码实现:
import logging import time from OSLog import OS_LOG_TYPE_INFO, os_log_create, os_log_with_type class MacOSConsoleHandler(logging.Handler): def __init__(self, subsystem_id, category): super().__init__() self._logger = os_log_create(subsystem_id, category) def emit(self, record): log_msg = self.format(record) # 必须加{public}标记,否则动态字符串会被系统隐藏显示为<private> os_log_with_type(self._logger, OS_LOG_TYPE_INFO, "%{public}s", log_msg) if __name__ == "__main__": logger = logging.getLogger() logger.setLevel(logging.INFO) # 替换为你自己的应用反向ID作为子系统标识 logger.addHandler(MacOSConsoleHandler("com.yourdomain.yourapp", "runtime")) while True: logger.info('I am visible from Console.app now :)') time.sleep(1)
运行后可以在Console.app中按子系统ID、类别过滤日志,日志会被系统正常索引、归档,支持导出功能。
内容的提问来源于stack exchange,提问作者SolomidHero
相关产品推荐
相关产品推荐

