10 — Core 业务接入埋点
1. 结论
业务接入埋点是 flare-im-contracts 给外部业务系统的非侵入式扩展面。它不把业务逻辑写进 Core,而是把 Core 主链中的关键事实转换为稳定事件,交给业务侧 Hook、Capability、MQ、Webhook 或 Sidecar 消费。
默认状态下,Core 使用 Noop 埋点实现;没有任何业务接入时,Core 仍可独立运行。
2. 埋点与 Hook 的区别
| 类型 | 目的 | 是否影响主链 | 典型场景 |
|---|---|---|---|
pre_send Hook | 决策/拦截 | 可以阻断 | 好友关系、群禁言、风控 |
post_send Hook | 发送后旁路 | 默认不阻断 | 审计、数据分析 |
| Business Probe | 标准事实埋点 | 不阻断 | 增长、BI、风控特征、账单、推荐 |
| Capability Dispatch | 命令/查询能力 | 调用方决定 | 业务能力调用 |
原则:
- 能用埋点解决的,不要写进 Core。
- 需要拒绝主链的,使用 Hook。
- 需要业务命令结果的,使用 Capability / Extension。
- 需要异步观察事实的,使用 Business Probe。
3. Core 标准埋点模型
Rust 公共类型位于 flare-im-core/crates/flare-im-contracts/src/instrumentation/mod.rs:
| 类型 | 说明 |
|---|---|
BusinessProbeEvent | 标准业务埋点事件 |
BusinessProbeKind | message / conversation / participant / hook / sync / push / capability 等分类 |
BusinessProbeDelivery | best_effort / reliable_async / blocking_audit |
BusinessProbeSink | 业务埋点投递端口 |
NoopBusinessProbeSink | 默认空实现,保证 Core 独立运行 |
事件核心字段:
| 字段 | 说明 |
|---|---|
name | 稳定事件名,如 core.message.send.accepted |
kind | 分类 |
delivery | 投递语义 |
schema | payload schema 版本 |
tenant_id / user_id | 来自 Ctx |
request_id / trace_id | 幂等和追踪 |
conversation_id / message_id / subject_id | 业务定位 |
attributes | 轻量标签 |
payload | JSON 业务载荷 |
4. 标准事件名
| 事件名 | 触发语义 |
|---|---|
core.hook.message.pre_send.invoked | 发前 Hook 被调用 |
core.hook.message.pre_send.allowed | 发前 Hook 放行 |
core.hook.message.pre_send.rejected | 发前 Hook 拒绝 |
core.hook.message.post_send.invoked | 发后 Hook 被调用 |
core.hook.message.delivery.observed | 送达 Hook 观测 |
core.hook.message.recall.invoked | 撤回 Hook 被调用 |
core.hook.message.read.observed | 已读 Hook 观测 |
core.hook.message.reaction.invoked | 表态 Hook 被调用 |
core.hook.conversation.lifecycle.observed | 会话生命周期 Hook 观测 |
core.hook.conversation.member.invoked | 会话成员 Hook 被调用 |
core.message.send.accepted | 发送请求通过校验并进入 Core 主链 |
core.message.send.rejected | 发送请求被 Hook 或 Core 校验拒绝 |
core.message.persisted | 消息完成持久化或入主队列 |
core.message.recalled | 消息撤回 |
core.conversation.created | 会话创建/ensure |
core.conversation.updated | 会话资料或生命周期更新 |
core.conversation.participants.changed | 会话参与者增加、移除、角色变化 |
core.sync.executed | 多端同步执行 |
core.push.enqueued | 推送任务入队 |
core.capability.dispatched | 能力调用执行 |
5. 接入方式
5.1 进程内 Sink
适合 Rust 部署或 sidecar 同进程:
use flare_im_contracts::{BusinessProbeEvent, BusinessProbeSink, Ctx};
use flare_server_core::error::Result;
pub struct KafkaProbeSink;
#[async_trait::async_trait]
impl BusinessProbeSink for KafkaProbeSink {
async fn emit(&self, ctx: &Ctx, event: BusinessProbeEvent) -> Result<()> {
// 写 Kafka / NATS / 审计库
Ok(())
}
}
5.2 HookPlugin
适合跨语言业务系统:
pre_send处理好友、群权限、风控等强门禁。post_send消费消息发送后事实。delivery/message_read消费送达和已读行为。message_reaction处理点赞、emoji、业务表态。conversation_lifecycle消费会话状态变化。conversation_member消费参与者变化。
消息和会话 Hook 的接入细节见 02-hook-plugin.md。
5.3 Capability / Extension
适合需要业务命令结果的场景:
- 计费:
billing.im.message_usage.record - 风控特征:
risk.feature.im_activity.append - 推荐特征:
rec.relation.interaction.update
5.4 MQ / Webhook
适合批处理、数据平台、增长分析:
- Core 侧投递
BusinessProbeEvent到 MQ。 - 业务侧按
name、tenant_id、schema消费。 - Webhook 只用于低 QPS 管理或审计场景。
6. 业务可实现的非侵入能力
| 业务能力 | 推荐埋点/扩展 |
|---|---|
| 消息发送统计 | core.message.send.accepted |
| 发送失败/拒绝分析 | core.message.send.rejected |
| 群活跃度 | core.message.persisted + conversation kind |
| 成员变更通知 | core.conversation.participants.changed |
| 群生命周期分析 | core.conversation.updated |
| 已读率 | message_read Hook / core.sync.executed |
| 推送到达分析 | delivery Hook / core.push.enqueued |
| 计费 | message / media / capability probe |
| 风控特征 | pre_send Hook + probe 旁路 |
| 推荐特征 | message / relation / conversation probe |
7. Hook 观测 payload 建议
Hook 观测事件建议使用 schema = "flare.im.hook_probe.v1",payload 保持可演进 JSON:
{
"hook_name": "social-policy-pre-send",
"operation": "flare.hook.v1.pre_send",
"decision": "allow",
"latency_ms": 12,
"error_policy": "fail_fast",
"require_success": true,
"deny_reason_code": "",
"conversation_type": "group",
"message_type": "text"
}
字段约定:
| 字段 | 说明 |
|---|---|
hook_name | 配置中的 Hook 名称 |
operation | HookPlugin operation |
decision | allow / reject / success / failed / timeout |
latency_ms | Hook 执行耗时 |
error_policy | fail_fast / retry / ignore |
require_success | 是否要求成功 |
deny_reason_code | 业务拒绝码 |
conversation_type / message_type | 选择器相关标签 |
8. 投递语义
| Delivery | 语义 | 主链影响 |
|---|---|---|
best_effort | 日志/指标即可 | 不影响 |
reliable_async | 进入 MQ 或审计库,失败可重试 | 不影响 |
blocking_audit | 严格审计点 | 只用于合规明确要求 |
生产默认:
- 消息、会话、同步埋点使用
reliable_async。 - 指标类使用
best_effort。 - 不要把普通 BI 埋点设置成
blocking_audit。
9. 独立运行保证
Core 独立运行时:
- 使用
NoopBusinessProbeSink。 - Hook 配置为空时跳过 Hook。
- Capability 未部署时不影响消息、会话、同步核心链路。
- 业务 bridge 不部署时,Core 只维护自身会话和参与者投影。
业务接入后:
- 通过配置注入 Sink / Hook / Capability。
- 业务失败按投递语义降级。
- Core 不依赖业务 crate,不因业务不可用而无法启动。
10. 后续落地建议
| 优先级 | 任务 |
|---|---|
| P0 | Orchestrator 在发送成功/拒绝处发 BusinessProbeEvent |
| P0 | Conversation 在参与者变更处发 BusinessProbeEvent |
| P1 | Gateway 统一记录 HTTP API probe |
| P1 | Capability 增加 probe sink adapter |
| P1 | MQ probe sink 与配置化开关 |
| P2 | 数据平台 schema registry 与采样策略 |