1. 使用的系统/方案
本仓库为基于 MicroPython 的掌控板固件,日志系统由两部分组成:
Python 层:在
firmware/port/modules/logging.py和esp32s3/firmware/modules/logging.py中实现了 Python 标准库logging的一个精简子集(兼容 MicroPython 环境),提供Logger、getLogger、basicConfig、DEBUG/INFO/WARNING/ERROR/CRITICAL常量及debug/info/warning/error/critical/exc/exception方法。C 层:通过
sys.stderr作为默认输出流,底层实际依赖 MicroPython 运行时将print()/_stream.write()重定向到 REPL 或串口调试输出;C 扩展 builtins 未实现独立的日志框架,仅通过sys.print_exception输出异常堆栈。
该实现是 MicroPython 官方 logging 模块的精简移植,并非自研框架。
2. 关键文件
文件 |
层级 |
作用 |
|---|---|---|
|
Python 扩展模块(ESP32 端口) |
提供 |
|
Python 扩展模块(ESP32-S3 端口) |
同上,与 ESP32 端口完全一致 |
|
Python 扩展模块 |
使用 |
|
Python 扩展模块 |
同上 |
|
文件系统 Python 模块 |
同上,用于 SD/Flash 上的用户代码 |
3. 架构与约定
日志级别
采用与 Python 标准库一致的数值定义:NOTSET=0, DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50。每个 Logger 实例维护自己的 level,若未设置则回退到模块级全局 _level(默认 INFO)。判断条件为 level >= (self.level or _level)。
输出格式
每条日志输出形如 LEVEL:name:msg,其中 level 标签映射为 CRIT/ERROR/WARN/INFO/DEBUG,未知级别显示为 LVL<n>。名称来自 getLogger(name) 传入的模块名或 None。
输出目标
默认输出流 _stream = sys.stderr,可通过 basicConfig(stream=...) 替换。filename 和 format 参数被显式忽略并打印提示:logging.basicConfig: filename arg is not supported / format arg is not supported。
Logger 缓存
模块内维护 _loggers = {} 字典,getLogger(name) 按 name 复用 Logger 实例,避免重复创建。
异常输出
exc(e, msg) 先以 ERROR 级别输出消息,再调用 sys.print_exception(e, _stream) 输出完整堆栈;exception(msg) 从当前异常上下文获取异常对象后委托给 exc。
顶层便捷函数
logging.info() 和 logging.debug() 直接操作一个默认的 getLogger(None) 实例,便于快速输出。
4. 使用模式与约束
模块级 logger 模式:
uwebsockets等模块通过LOGGER = logging.getLogger(__name__)获取命名 logger,并以__debug__条件开关控制 debug 级别输出,这是仓库中观察到的唯一使用方式。无结构化字段:日志输出仅为字符串拼接,不支持结构化字段(JSON、键值对等)。
无多 sink:仅支持单一
sys.stderr输出,无法同时写入文件、网络或 SPIFFS/LittleFS。无异步/线程安全:实现为同步单进程模型,未考虑并发保护。
C 层无独立日志:C 扩展 builtins(
firmware/port/builtins/、esp32s3/firmware/builtins/)未发现自定义日志宏或ESP_LOG*调用,C 层调试依赖 MicroPython 运行时的printf/REPL 输出。与 MicroPython 行为对齐:该实现遵循 MicroPython 对
logging的标准裁剪策略——保留核心 API,移除 handler/formatter 等重量组件。
5. 结论
仓库的日志系统是一个轻量级的 Python 层 logging 适配,面向资源受限的嵌入式 MicroPython 环境,输出统一走 sys.stderr(即串口/REPL)。它不具备生产级日志系统的特性(多 sink、结构化、异步、过滤链),但足以满足开发调试阶段按级别过滤的文本日志需求。