跳到主要内容

日志

通过 master.logs 访问日志视图,或通过 LogManager.instance().default_view 全局访问。​

运行日志由 SDK 各模块写入日志视图(只读列表);DLL 原生日志经 set_log_callback 回调推送给调用方。两者通道独立。

快速开始​

from darra_ethercat import EtherCATMaster, LogCategory

# 绑定到控制台输出
master.logs.on_updated = lambda: print(master.logs[-1]) if master.logs.count > 0 else None

# 只看错误和警告
master.logs.set_filter(LogCategory.ERROR, LogCategory.WARNING)

# 启用调试日志(默认关闭)
EtherCATMaster.set_debug_logging(True)

日志类别​

from enum import IntEnum

class LogCategory(IntEnum):
ERROR = 0 # 系统错误和异常
WARNING = 1 # 潜在问题
MESSAGE = 2 # 一般信息(状态切换等)
MAILBOX = 3 # CoE/SoE/FoE/EoE 邮箱通信(默认关闭)
PDO = 4 # PDO 数据变化日志(默认关闭)
DEBUG = 5 # 详细调试信息(默认关闭)
LOCAL = 6 # 控制台输出捕获

属性​

类别属性/方法类型读写说明
视图master.logsLogView只读实时日志视图(等价 LogManager.instance().default_view)
on_updatedOptional[Callable[[], None]]读写数据变化回调(无参函数),新增/清空/过滤器变化时触发
countint只读过滤后的日志条数
retainbool读写是否保留所有日志(默认 False)
set_filter(*categories)None只写设置类别过滤器,只显示指定类别
get_all()List[LogEntry]只读获取所有日志条目(无视过滤器)
logs[i] / 迭代LogEntry只读按索引取 / 遍历(均为过滤后视图)
回调master.set_log_callback(callback)None只写注册 DLL 原生日志回调 (category, message),传 None 清除
master.set_crash_callback(callback)None只写注册崩溃通知回调 (severity, message),传 None 清除

master.logs​

@property
def logs(self) -> LogView

实时日志视图(只读列表)。

LogEntry 数据类:

@dataclass
class LogEntry:
timestamp: datetime # 日志时间戳
category: LogCategory # 日志类别
message: str # 日志消息内容

on_updated​

master.logs.on_updated = callback   # callback() 无参,返回 None

日志数据变化时触发(新增/清空/过滤器变化)。

容量与保留策略

日志列表上限 10000 条,超出时自动移除最旧的 2000 条。

保留策略: master.logs.retain 默认 False——LogManager.instance().begin_operation() 进入首层操作时自动清空旧日志,只保留当前操作的日志;设 retain = True 则累积保留,不在操作边界清空。操作边界用 begin_operation() / end_operation() 标记。

PDO 日志

PDO 日志只在 PDO 数据发生变化时输出,不会每个周期都产生日志。适合调试 PDO 映射问题。

过滤​

set_filter()​

def set_filter(self, *categories: LogCategory) -> None

设置过滤器,只显示指定类别的日志。

示例:

# 只看错误和警告
master.logs.set_filter(LogCategory.ERROR, LogCategory.WARNING)

# 切换为只看邮箱通信
master.logs.set_filter(LogCategory.MAILBOX)

get_all()​

def get_all(self) -> List[LogEntry]

获取所有日志条目(无视过滤器)。

日志回调​

set_log_callback()​

def set_log_callback(self, callback: Optional[Callable[[int, str], None]]) -> None

注册 DLL 原生日志回调(进程级)。回调参数 (category, message)——category 为 LogCategory 取值(int),message 为日志文本。多 master 互不覆盖:重复调用只替换本实例上次注册的回调,传 None 清除。

set_crash_callback()​

def set_crash_callback(self, callback: Optional[Callable[[int, str], None]]) -> None

注册崩溃通知回调(进程级)。回调参数 (severity, message),传 None 清除本实例的注册。

日志开关​

Mailbox、PDO、Debug 三类日志默认关闭,需要时手动启用。

EtherCATMaster.set_pdo_logging(True)
EtherCATMaster.set_mailbox_logging(True)
EtherCATMaster.set_debug_logging(True)

日志开关详解​

set_pdo_logging()​

EtherCATMaster.set_pdo_logging(enable: bool) -> None

启用 PDO 日志。仅在 PDO 数据变化时输出,影响实时性能,慎用。

set_mailbox_logging()​

EtherCATMaster.set_mailbox_logging(enable: bool) -> None

启用邮箱日志(CoE/SoE/FoE/EoE 邮箱通信日志)。

set_debug_logging()​

EtherCATMaster.set_debug_logging(enable: bool) -> None

启用调试日志(详细调试信息)。

完整示例​

from darra_ethercat import EtherCATMaster, LogCategory

# 1. 绑定控制台输出
master.logs.on_updated = lambda: print(master.logs[-1]) if master.logs.count > 0 else None

# 2. 启用调试日志
EtherCATMaster.set_debug_logging(True)
EtherCATMaster.set_mailbox_logging(True)

# 3. 过滤日志
master.logs.set_filter(LogCategory.ERROR, LogCategory.DEBUG)

# 4. 导出所有日志(无视过滤器)
all_logs = master.logs.get_all()
with open("debug.log", "w", encoding="utf-8") as f:
for entry in all_logs:
f.write(f"{entry}\n")
tkinter / PyQt 绑定

on_updated 在非 UI 线程触发,更新 UI 时需要同步:

# tkinter
master.logs.on_updated = lambda: root.after(0, lambda: listbox.insert("end", str(master.logs[-1])))

# PyQt
from PyQt5.QtCore import QMetaObject, Qt, Q_ARG
master.logs.on_updated = lambda: QMetaObject.invokeMethod(
widget, "append_log", Qt.QueuedConnection, Q_ARG(str, str(master.logs[-1])))