跳到主要内容

事件

通过 device.events() 订阅运行态事件。

自动日志

每个事件触发时都会再打 on_logged(等级跟随源事件),无论是否另订了对应事件。绑 on_logged 即可收到中文消息。

订阅后,调用 status_ex()connected() 才会比对变化。第一次快照不触发(只记基线)。回调里 panic 不会把 SDK 弄停。每个事件只留一个回调:同名 on_* 再调一次是替换,不是追加。

网卡链路走事件:订阅 on_link_changed(服务端状态里没有 linkUp 字段时不触发)。IOPS 不走事件on_io_status_changed 能订阅、能通过编译,但派发它的路径没有调用方,永远不会触发 —— 见 下节。要 IOPS 就轮询 io_status();链路快照另有 diag_snapshot().link_up

功能概览

类别事件说明自动日志
连接on_connected_changed与 IO 控制器的周期交换通断
运行态on_state_changed运行态变化
运行错误on_error_occurred运行错误
链路on_link_changed网卡物理链路 Up / Down
IOPSon_io_status_changed收不到,别订
日志on_logged上面每条事件都会再打这条
危险
on_io_status_changed 订了也不会响

它能通过编译、能注册成功、不给任何报错,但回调一次都不会被调用。注册完一直没动静不等于 IOPS 一直是好的。拿不准就轮询 io_status()。详见 IOPS 订阅

连接

on_connected_changed

pub fn on_connected_changed<F>(&self, cb: F)
where F: FnMut(&ConnectedChangedEvent) + 'static

周期数据交换通断时触发(connected == falseever_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);
});

链路

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
订了永远不响

回调注册得进去,也通过编译,但一次都不会被调用:喂这条事件的解析路径(原先读 GET /api/io)现在没有调用方。

所以「订了 on_io_status_changed 之后一直没动静」不能当成「IOPS 一直是好的」。要看 IOPS 质量请轮询 io_status()

回调参数:(当前不会被构造,列在这里只为对照类型)

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}");
});

IOPS 不进这份列表 —— on_io_status_changed 订了不会响,想要 IOPS 在循环里读 io_status()