事件
通过 device.events() 订阅运行态事件。
每个事件触发时都会再打 on_logged(等级跟随源事件),无论是否另订了对应事件。绑 on_logged 即可收到中文消息。
订阅后,调用 status_ex() 或 connected() 才会比对变化。第一次快照不触发(只记基线)。回调里 panic 不会把 SDK 弄停。每个事件只留一个回调:同名 on_* 再调一次是替换,不是追加。
网卡链路走事件:订阅 on_link_changed(服务端状态里没有 linkUp 字段时不触发)。链路快照另有 diag_snapshot().link_up。
IO 质量走 on_io_status_changed。第一次读到 IOPS 只记基线,不回调。inputIopsHex 与 outputIopsHex 都缺则不虚构、不回调。非 GOOD 字节计数变化才回调。六种语言同一口径,不是每次读都回调。
功能概览
| 类别 | 事件 | 说明 | 自动日志 |
|---|---|---|---|
| 连接 | on_connected_changed | 与 IO 控制器的周期交换通断 | ✓ |
| 运行态 | on_state_changed | 运行态变化 | ✓ |
| 运行错误 | on_error_occurred | 运行错误 | ✓ |
| 链路 | on_link_changed | 网卡物理链路 Up / Down | ✓ |
| IOPS | on_io_status_changed | 非 GOOD 字节计数变化 | ✓ |
| 日志 | on_logged | 上面每条事件都会再打这条 | — |
连接
on_connected_changed
pub fn on_connected_changed<F>(&self, cb: F)
where F: FnMut(&ConnectedChangedEvent) + 'static
周期数据交换通断时触发(connected == false 且 ever_connected == true = 掉线;ever_connected == false = 从未连上)。
回调参数:
pub struct ConnectedChangedEvent {
pub connected: bool, // 当前是否在换周期数据
pub ever_connected: bool, // 是否曾经连上过
pub level: EventLevel, // 连接 = Info;掉线 / 从未连上 = Warn
}
示例:
device.events().on_connected_changed(|e| {
if !e.connected && e.ever_connected {
println!("掉线");
}
});
运行态
on_state_changed
pub fn on_state_changed<F>(&self, cb: F)
where F: FnMut(&StateChangedEvent) + 'static
运行态变化时触发(SDK 只观测,不主动切状态)。old_state / new_state 类型是 ServiceState。
回调参数:
pub struct StateChangedEvent {
pub old_state: ServiceState, // 变化前,见 [ServiceState](./api#servicestate)
pub new_state: ServiceState, // 变化后
pub level: EventLevel, // Info
}
示例:
device.events().on_state_changed(|e| {
println!("{:?} → {:?}", e.old_state, e.new_state);
});
on_error_occurred
pub fn on_error_occurred<F>(&self, cb: F)
where F: FnMut(&ErrorOccurredEvent) + 'static
运行错误出现时触发;error_code 是 int 原值,枚举形态请用 device.error_code()。
回调参数:
pub struct ErrorOccurredEvent {
pub error_code: i32, // 运行错误原值(不是枚举)
pub message: String, // 中文消息;缺失为空串
pub level: EventLevel, // Warn
}
示例:
device.events().on_error_occurred(|e| {
println!("{}: {}", e.error_code, e.message);
});
链路
on_link_changed
pub fn on_link_changed<F>(&self, cb: F)
where F: FnMut(&LinkChangedEvent) + 'static
网卡物理链路 Up / Down 时触发。比对在 status_ex() / connected() 里做,第一次快照只记基线不触发。
服务端状态里没有 linkUp 字段时不触发 —— 不拿 connected 冒充物理链路,也不猜。
回调参数:
pub struct LinkChangedEvent {
pub link_up: bool, // 物理链路是否 Up
pub level: EventLevel, // Up = Info;Down = Warn
}
示例:
device.events().on_link_changed(|e| {
println!("链路 {}", if e.link_up { "Up" } else { "Down" });
});
过程数据质量
on_io_status_changed
pub fn on_io_status_changed<F>(&self, cb: F)
where F: FnMut(&IoStatusChangedEvent) + 'static
第一次读到 IOPS 只记基线,不回调。inputIopsHex 与 outputIopsHex 都缺则不虚构、不回调。非 GOOD 字节计数变化才回调。不是每次读都回调。
回调参数:
pub struct IoStatusChangedEvent {
pub iops_bad: bool, // true = 当前 IOPS 不是全 GOOD
pub level: EventLevel, // BAD = Warn;否则 Info
}
只带一个布尔量:没有逐子模块的 IOPS 明细,也没有 BAD 字节计数。
日志
on_logged
pub fn on_logged<F>(&self, cb: F)
where F: FnMut(EventLevel, &str) + 'static
每个事件触发时都会再打这条,等级跟随源事件。
回调参数:
level(EventLevel) — 日志级别message(&str) — 日志正文
EventLevel
日志级别。取值见 枚举参考。没有稳定的整数判别值,按枚举名用。
示例:
device.events().on_logged(|level, message| {
println!("[{level:?}] {message}");
});
完整示例
device.events().on_connected_changed(|e| {
if !e.connected && e.ever_connected {
println!("掉线");
}
});
device.events().on_state_changed(|e| {
println!("{:?} → {:?}", e.old_state, e.new_state);
});
device.events().on_error_occurred(|e| {
println!("{}: {}", e.error_code, e.message);
});
device.events().on_link_changed(|e| {
println!("链路 {}", if e.link_up { "Up" } else { "Down" });
});
device.events().on_logged(|level, message| {
println!("[{level:?}] {message}");
});
IO 质量见 on_io_status_changed。第一次读到 IOPS 只记基线,不回调;不是每次读都回调。