Genapsed
简介
发音:/dʒɛˈnæps-d/
—— “创世之初第一道苏醒的 脉冲 ,编织依赖的经纬、点燃组件的星火、汇聚日志的川流、守望异常的暗礁;它是贯穿万物的神经突触,亦是黄昏降临时最后熄灭的灯塔。”
系统主程序被加载后启动的第一个组件,用来检查环境是否满足其他组件依赖、检查更新、启动其他组件、管理插件、收集日志、异常退出、插件安装、系统和插件的更新等,同时负责系统各组件的通讯、权限管理。是系统的底层和核心组件之一。
当前代码架构
当前 Genapsed 已拆为核心协议复用层、运行时编排层和管理层。MQTT Broker 仍采用外部 Mosquitto,
Genapsed 通过 everpast_share 复用 Topic、MessageEnvelope、MQTT 适配和 MySQL 连接模型;
Docker Compose 基础设施生成、数据库初始化、组件数据库区域、配置数据库主源、配置文件渲染和权限授权由 Genapsed 管理。
开发模式下,Genapsed 作为第一个启动的应用层组件,先拉起基础设施、初始化数据库和配置,再启动
www-server、MiniVLM worker 和 NVR-Bridge worker,并在前台承接 MQTT 路由、配置更新和 Timeline 入库。
genapsed/
├── pyproject.toml
├── requirements.txt
├── src/genapsed/
│ ├── __init__.py
│ ├── core/
│ │ ├── components.py # 组件/插件注册表与健康状态
│ │ ├── config.py # 内部 Config Manager
│ │ ├── exceptions.py # 核心层异常
│ │ ├── messages.py # 复用 Share 标准消息信封
│ │ └── topics.py # 复用 Share MQTT Topic 规则与 QoS 策略
│ ├── runtime/
│ ├── ack.py # ACK 跟踪与重试调度
│ ├── exceptions.py # 运行时服务层异常
│ ├── files.py # 复用 Share 文件传输管理
│ ├── mqtt.py # paho-mqtt 适配器
│ ├── permissions.py # Topic 权限策略
│ ├── plugins.py # 插件清单、权限与运行计划
│ ├── router.py # 显式消息路由规则
│ └── service.py # 运行时服务编排
│ └── management/
│ ├── config.py # 配置数据库主源与配置文件渲染
│ ├── database.py # MySQL 初始化、组件库区、GRANT 和数据目录
│ ├── dev.py # 开发模式系统启动、组件拉起和监督
│ ├── docker.py # 项目内 Docker Compose 基础设施管理
│ ├── executors.py # 插件进程与 Docker 执行器
│ ├── health.py # 健康检查编排
│ ├── logs.py # JSONL 结构化日志
│ ├── mosquitto.py # Mosquitto 配置生成
│ ├── permissions.py # 插件权限授权
│ └── service.py # 管理层统一入口
└── tests/
分层原则
| 层级 | 当前状态 | 职责 |
|---|---|---|
genapsed.core | 已实现基础能力 | 组件注册、健康状态、配置接口;Topic 和消息信封复用 Share |
genapsed.runtime | 已实现基础能力 | MQTT 连接、ACK 跟踪、重试调度、权限校验、消息路由、Timeline 入库请求和配置更新请求处理 |
genapsed.management | 已实现基础能力 | 配置数据库主源、开发模式系统编排、Docker Compose 数据库管理、MySQL 初始化、组件库区授权、日志、健康检查、插件权限和执行入口 |
| 对外接口层 | 部分实现 | CLI 已覆盖开发模式启动、配置、Mosquitto 配置生成、Docker 数据库管理和 MySQL 初始化;HTTP API 由 www-server 暴露 |
| 前端管理页 | 由 WebUI / www-server 承载 | 系统状态、配置、日志和 MQTT 桥接查看 |
第一阶段已确定接口
- Topic 统一为
everpast/<component>/<message_type>/<priority>[/target],由core.topics.Topic解析和生成,后续代码不应手写拼接 Topic。 - 系统消息统一使用
core.messages.MessageEnvelope,其中模型或组件业务输出只能放在payload内,系统字段由信封层维护。 - Config Manager 是 Genapsed 内部模块,配置主源在 MySQL,组件配置文件只是 Genapsed 渲染出的运行产物。
- 组件与插件统一进入
core.components.ComponentRegistry,健康状态使用HealthSnapshot上报,便于后续通过 MQTT 发布到everpast/genapsed/status/normal。 - 运行时适配层采用 Mosquitto + paho-mqtt;结构化数据采用 MySQL + SQLAlchemy + PyMySQL;开发模式由 Genapsed 生成项目内 Compose 文件管理 MySQL 和 Mosquitto。
- MQTT 适配器只负责连接、订阅、发布和消息反序列化;权限校验、路由策略和 ACK 重试由上层运行时服务组合实现。
- ACK 跟踪模块只维护待确认消息、TTL、最大重试次数、到期重试队列和失败队列,不直接执行网络发送。
- Topic 权限策略第一阶段按组件命名空间隔离:插件只能发布到自己的
plugin.<id>Topic,只能接收 Genapsed 广播或明确发给自己的cmd消息。 - 路由器采用显式规则,不做隐式兜底路由;未匹配消息不会被转发,避免错误消息被悄悄送到下游。
MQTT 后端选型
第一阶段 MQTT 后端采用 Mosquitto + paho-mqtt:
| 模块 | 选型 | 边界 |
|---|---|---|
| MQTT Broker | Mosquitto | 作为外部消息代理服务部署,Genapsed 不自行实现 Broker 能力 |
| Python MQTT Client | paho-mqtt | 只在运行时适配层使用,用于连接、发布、订阅和重连 |
| Genapsed 应用层 | 自研 | 负责 Topic 规范、消息信封、ACK、重试、权限校验、路由和健康检查 |
选择 Mosquitto 的原因是部署轻量、实现成熟、适合单机和局域网第一阶段目标。若后续出现多节点部署、规则引擎、复杂 ACL、可视化运维或大规模插件生态需求,再评估 EMQX 等更重的 Broker 方案。
命名来源
- Gen- → Genesis (γένεσις):创世、起源——系统加载后第一个被唤醒的组件
- -aps- → Synapse (σύναψις):突触——神经元间传递信号的最底层微观结构;隐喻本组件作为所有其他组件之间通讯、调度、依赖传递的基础通道
- -d → Daemon (Unix/Linux):守护进程后缀——表明其以后台常驻服务形态运行,承担系统级监护与生命周期管理
对外接口
- 配置管理(Schema 注册 / 全局校验 / 变更通知)
- 检查更新
- 安装更新
- 组件(插件)健康检查
- 系统、组件、插件历史日志
- 系统、组件、插件实时日志
- 重启插件
- 系统、组件、插件版本号
- 安装插件
- 更新插件源
- 获取插件信息
消息网关
系统各组件使用 MQTT 通讯,Mosquitto 作为 Broker,Genapsed 负责应用层权限校验、路由、ACK 和入库编排。对于大文件,存储在共享文件系统目录中并合理设置权限,MQTT 只传共享目录相对路径。
MQTT Topic 设计规范
Topic 层级结构
everpast/<component>/<message_type>/<priority>[/target]
| 层级 | 说明 | 示例 |
|---|---|---|
everpast | 固定根前缀,避免冲突 | everpast |
<component> | 源组件/插件标识 | genapsed, frigate, minivlm, plugin.xxx |
<message_type> | 消息类型 | event, cmd, status, log, file |
<priority> | 消息优先级 | low, normal, high, critical |
[target] | 目标组件(可选,用于点对点通讯) | plugin.xxx |
Topic 定义
# 系统级
everpast/genapsed/status/normal # 系统状态广播
everpast/genapsed/cmd/critical/minivlm # 发往 MiniVLM 的高优先级指令
everpast/genapsed/log/low # 系统日志
# Frigate 原生事件由 NVR-Bridge 订阅,不作为 Everpast 标准 event 直接进入 Genapsed
everpast/frigate/events # Frigate 原生 MQTT topic
# 组件级
everpast/nvr_bridge/event/high # NVR-Bridge 归一化后的 Frigate 检测事件
everpast/nvr_bridge/status/normal # NVR-Bridge 运行状态
everpast/minivlm/event/normal # VLM 事件生成
everpast/minivlm/status/normal # VLM 运行状态
# 插件级
everpast/plugin.<id>/event/normal # 插件事件
everpast/plugin.<id>/status/normal # 插件状态
everpast/genapsed/cmd/normal/plugin.<id> # 发往插件的指令
消息格式规范
{
"msg_id": "[uuid-v4生成]",
"source": "frigate.cam01",
"target": "minivlm",
"type": "motion_detected",
"priority": "high",
"timestamp": 1741000000,
"payload": {
"camera_id": "cam01",
"confidence": 0.95,
"file_ref": "temp/share/private/msg-uuid-001/20260401_1200.mp4",
"thumbnail": "data:image/jpeg;base64,/9j/..."
},
"metadata": {
"requires_ack": true,
"ttl": 300,
"trace_id": "trace-uuid"
}
}
QoS 策略分级
| 消息类型 | QoS | 说明 |
|---|---|---|
| 控制指令 (cmd) | QoS 2 | 必须确保送达且仅一次 |
| 事件通知 (event) | QoS 1 | 允许重复但不可丢失 |
| 状态心跳 (status) | QoS 0 | 可丢失,最新状态优先 |
| 日志 (log) | QoS 0 | 可丢失 |
组件间通讯流程
- 组件 A 检测到事件,发布消息到
everpast/A/event/high - Genapsed 收到消息,根据路由规则转发到组件 B 的订阅 topic
- 组件 B 处理完成后发送 ACK 确认
- Genapsed 将 ACK 转发给组件 A
运行时特殊消息处理
当前运行时服务除显式路由规则外,已经内置三类应用层消息处理,不做隐式兜底:
| 入站消息类型 | 入口 Topic 示例 | 处理行为 | 结果 Topic |
|---|---|---|---|
motion_detected | everpast/nvr_bridge/event/high | 按显式路由规则转换为 analyze_task 并转发给 MiniVLM | everpast/genapsed/cmd/high/minivlm |
timeline_event_generated | everpast/minivlm/event/normal | 调用 Timeline 入库接口 ingest_envelope() | everpast/genapsed/result/<priority>/minivlm |
request_config_update | everpast/www_server/config/normal/genapsed | 调用配置更新入口 request_config_update(actor_id, component_id, config) | everpast/genapsed/result/<priority>/www_server |
request_component_command | everpast/www_server/cmd/<priority>/genapsed | 校验后以 Genapsed 身份转发标准组件命令 | everpast/genapsed/cmd/<priority>/<component_id> |
timeline_event_generated 入库成功后,Genapsed 发布 timeline_event_stored result,payload 中包含
item 和 source_msg_id;入库失败时发布 timeline_event_failed,随后继续抛出原始错误,避免用 fallback 掩盖写入问题。
request_config_update 成功后发布 config_update_applied,失败时发布 config_update_failed 并继续暴露异常。
配置变更真正的目标组件通知仍由 Config Manager 渲染配置后发布 config_updated 和 reload_config。
request_component_command 的 payload 必须包含:
{
"component_id": "minivlm",
"command_type": "reload_config",
"payload": {}
}
运行时会把它转换为:
Topic: everpast/genapsed/cmd/<priority>/minivlm
Type: reload_config
若入站消息设置 metadata.requires_ack = true,上述三类处理成功后都会由 Genapsed 返回 ACK;转发出的目标命令
会按照 Topic QoS 决定是否进入 ACK 跟踪队列。
文件传输机制
对于需要传输大文件的场景:
- 写入:发送方将文件复制到 Genapsed 管理的数据共享目录;
- 发送引用:通过 MQTT 发送轻量级消息,只包含共享目录相对路径;
- 读取:接收方解析消息后,到共享目录读取文件并复制到自己的组件数据目录。
默认数据根目录为主仓库下的 data/,该目录不进入 Git。实际运行时根目录由 Genapsed 的
--data-root 或配置主源确定,并写入组件配置 data_root_dir;Genapsed 拉起组件或插件时同时传入
EVERPAST_DATA_ROOT,组件再从该根目录派生自己的私有数据目录:
- 组件数据目录:
data/<component_id>,插件为data/plugin/<id>; - 数据库目录:
data/db; - Genapsed 管理的 Compose 文件:
data/genapsed/docker/compose.yaml; - Genapsed 生成的组件数据库凭据:
data/genapsed/database/credentials.json; - 默认凭据中包含
system.www_server.sqlalchemy_url,该账号只读everpast_system.component_configs,供 www-server 展示当前配置; - 公共共享目录:
data/temp/share/public/<msg-UUID>/<file>,所有组件可读写; - 私有共享目录:
data/temp/share/private/<msg-UUID>/<file>,不挂载给不可信 Docker 组件。
完整的数据存储标注,包括各目录的写入方、读取方、生命周期和是否进入 Git,以
系统架构设计 为准。
{
"event": "motion_detected",
"file_ref": "temp/share/private/msg-uuid-001/20260401_1200.mp4",
"timestamp": 1741000000
}
Docker 数据库管理
开发环境和普通部署环境中,Genapsed 优先生成项目内 Docker Compose 文件来管理基础数据库, 不修改系统级 Docker daemon 配置、不写入系统目录。当前已实现 MySQL 容器管理:
# 渲染 Compose 文件,不启动容器
genapsed docker database render --data-root data
# 启动并等待 MySQL 就绪
genapsed docker database up --data-root data --wait
# 查看容器状态
genapsed docker database status --data-root data
# 停止容器
genapsed docker database down --data-root data
默认行为:
- Compose 文件写入
data/genapsed/docker/compose.yaml; - MySQL 数据文件写入
data/db/mysql; - 容器名为
everpast-mysql; - 开发环境默认监听
127.0.0.1:3307,避免抢占本机系统 MySQL; - 默认镜像为
mysql:8.4,可通过--mysql-image指定完整镜像名; - 国内镜像环境可通过
--image-registry-prefix或EVERPAST_DOCKER_REGISTRY_PREFIX添加镜像仓库前缀,例如docker.m.daocloud.io。
数据库初始化由 Genapsed 继续负责:
genapsed database init --data-root data --host 127.0.0.1 --port 3307
该命令会创建 everpast_system、默认组件库、组件账号和 GRANT,并把组件连接信息写入
data/genapsed/database/credentials.json。若只需要审查 SQL,可使用 --dry-run 输出初始化计划而不连接数据库。
开发模式系统启动
开发模式推荐从主仓库根目录进入 genapsed 子模块,并用 uv 运行:
cd genapsed
PYTHONPATH=../Share/src:../Timeline/src:src:../www-server/src:../MiniVLM/src:../NVR-Bridge/src \
uv run python -m genapsed.cli start --mode dev --repo-root .. --data-root ../data
start --mode dev 让 Genapsed 作为前台监督进程运行,按顺序完成:
- 渲染
data/genapsed/dev/compose.yaml; - 将
--data-root解析结果写入开发默认配置,并通过EVERPAST_DATA_ROOT传给组件进程; - 启动当前开发计划需要的 Docker 依赖:MySQL、Mosquitto、Frigate;
- 初始化系统库、组件库、账号和 GRANT;
- 写入
data/genapsed/database/credentials.json; - 执行 Timeline 数据库迁移;
- 写入缺失的开发默认配置并渲染组件配置文件;
- 启动 Genapsed MQTT runtime,处理配置更新、组件命令转发和 Timeline 入库;
- 拉起
www-server、MiniVLM worker 和 NVR-Bridge worker 并监控进程状态。
停止时按反向生命周期执行:先停止 Genapsed 拉起的组件进程,再停止 MySQL、Mosquitto、
Frigate 等 Docker 依赖。开发调试需要复用 Docker 依赖时,可在 start --mode dev 或 dev down
中显式传入 --keep-infrastructure。MiniVLM 和 NVR-Bridge 已接入同一套开发模式启动/停止编排;
NVR-Bridge 订阅 Frigate 原生事件并输出标准分析任务,MiniVLM 接收任务后发布 timeline_event_generated。
首次启动允许 Frigate 没有摄像头;后续可通过 WebUI、配置文件或 Frigate UI 补充摄像头配置。
前台 start --mode dev 默认启用 Rich 控制台日志。Genapsed 会把 Docker 依赖日志和它拉起的组件 stdout
以简洁彩色格式打印到当前终端,同时继续写入 data/logs/<component>/YYYY-MM-DD.jsonl 或
data/logs/<component>/stdout.log。如果只想落盘不刷屏,可加 --no-console-logs;
后台启动使用 start --mode dev --background,默认不打印控制台日志,需要临时调试时可显式加
--console-logs。旧的 dev run / dev up 入口继续兼容已有脚本。
辅助命令:
uv run python -m genapsed.cli dev plan --repo-root .. --data-root ../data
uv run python -m genapsed.cli start --mode dev --repo-root .. --data-root ../data --background
uv run python -m genapsed.cli start --mode dev --repo-root .. --data-root ../data --no-console-logs
uv run python -m genapsed.cli dev status --repo-root .. --data-root ../data
uv run python -m genapsed.cli dev down --repo-root .. --data-root ../data
uv run python -m genapsed.cli dev down --repo-root .. --data-root ../data --keep-infrastructure
默认 WebUI 地址为 http://127.0.0.1:8080。国内镜像环境可在 start --mode dev 中传入
--image-registry-prefix docker.m.daocloud.io。
插件安全
第一阶段策略:插件默认视为可信,直接在宿主机上运行(使用独立 venv),降低初期复杂度。权限管控仍通过 Topic 隔离和文件目录限制实现。
架构拓展性:Genapsed 预留容器隔离接口,后续版本可启用 Docker 沙箱,对未认证或用户标记为不可信的插件进行容器级隔离。
后续容器隔离规划(一期不实现,仅预留接口):
- 未认证插件运行在独立 Docker 容器中;
- 每个容器有自己的临时目录,默认只挂载属于自己的临时目录;
- 用户可强制插件在宿主机运行但需自行承担安全隐患。
对于需要传输大文件的场景,Genapsed 将文件拷贝到文件传输临时目录并设置权限,插件需在接收后复制文件到自己的数据目录并返回接收成功结果到 Genapsed,Genapsed 收到后从临时目录删除文件完成本次文件传输。
对于容器,每个容器有自己的组件数据目录。公共共享目录可以挂载给需要文件传输的组件;私有共享目录只挂载给可信组件,不可信 Docker 组件不可读写其中数据。
宿主机的公共共享临时目录对所有宿主机组件可读写。可能包含监控录像原始数据等敏感内容时,应使用私有共享目录,并由 Genapsed 在运行计划中控制挂载范围。
权限管理
Topic 权限隔离
每个插件只能:
- 发布到自己的 topic: everpast/plugin.<id>/+/+
- 订阅 genapsed 广播:everpast/genapsed/+/+
- 订阅特定目标 topic: everpast/+/cmd/+/plugin.<id>
Genapsed 可以:
- 订阅所有:everpast/+/+/+/+
- 发布到所有
消息确认与重试机制
- 重要消息设置
requires_ack: true - 发送方启动定时器,超时未收到 ACK 则重试(最多 3 次)
- Genapsed 负责跟踪未确认消息并告警
消息追踪
每个请求生成唯一 trace_id,贯穿所有组件,便于调试和故障定位。
配置管理模块(Config Manager)
定位
Config Manager 是 Genapsed 内部模块,而非独立组件。它负责全系统配置的统一管理:Schema 注册、全局校验、数据库主源、配置文件渲染、变更通知、版本迁移。
配置主源存放在 Genapsed 管理的 MySQL 配置表中。组件配置文件是 Genapsed 根据数据库配置渲染出的运行产物; 任何组件(例如 WebUI)想修改另一个组件配置时,必须向 Genapsed 提交请求,由 Genapsed 校验权限、写入数据库、 渲染目标配置文件,并通过 MQTT 通知目标组件重载。
为什么不做独立组件?
| 考虑 | 说明 |
|---|---|
| 部署复杂度 | 独立进程需要 IPC 通信、进程间心跳、额外的端口管理,而 Genapsed 已经是常驻守护进程 |
| 启动顺序 | 如果配置管理是独立组件,Genapsed 必须等它就绪才能启动其他组件——这增加了一层依赖 |
| 当前规模 | 原型期组件数量有限(Genapsed + MiniVLM + Timeline + Query Engine),配置项不多,模块化即可 |
| 未来可提取 | 插件生态扩大后,如果配置管理逻辑足够复杂,可以从 Genapsed 中提取为独立组件 |
对外接口
Config Manager 以 Genapsed 的内部 API 形式暴露,不直接对外提供独立服务。
| 接口 | 调用方 | 说明 |
|---|---|---|
register_schema(component_id, schema) | 各组件/插件启动时 | 注册自己的配置 Schema |
validate(config, component_id) | Genapsed 启动时 | 校验指定组件的配置是否合规 |
load_component(component_id) | Genapsed 启动时 | 从数据库读取配置、校验并渲染组件配置文件 |
load_all_existing() | Genapsed 启动时 | 加载数据库中已有的组件配置 |
request_config_update(actor_id, component_id, config) | WebUI / 管理入口 | 跨组件配置修改请求 |
set_and_save(component_id, config) | Genapsed 内部流程 | 校验、写数据库、渲染文件并发布通知 |
ensure_default(component_id) | Genapsed 初始化 | 配置不存在时按 Schema 默认值创建配置 |
设计细节
Schema 注册格式
# 组件注册的 Schema 示例(组件 manifest 或配置声明中)
config_schema:
version: "1.0"
fields:
enabled:
type: boolean
default: true
description: "是否启用该组件"
sampling:
type: object
properties:
interval:
type: integer
min: 10
max: 3600
default: 60
description: "采样间隔(秒)"
mqtt:
type: object
properties:
topic:
type: string
pattern: "^everpast/[a-zA-Z0-9_]+/[a-zA-Z0-9_]+/[a-zA-Z0-9_]+$"
description: "MQTT topic 格式校验"
配置变更通知
当 Config Manager 接受配置更新后,先写 MySQL 配置主表,再渲染目标组件配置文件,并通过 MQTT 发布配置变更和重载命令:
Topic: everpast/genapsed/config/normal/<component_id>
Type: config_updated
{
"source": "genapsed",
"target": "minivlm",
"type": "config_updated",
"payload": {
"component_id": "minivlm",
"revision": 2,
"schema_version": "1",
"config_path": "data/minivlm/config.json",
"diff": {
"idle_interval_seconds": {
"old": 1800,
"new": 3600
}
}
}
}
Topic: everpast/genapsed/cmd/high/<component_id>
Type: reload_config
Payload: {"component_id": "minivlm", "revision": 2, "config_path": "data/minivlm/config.json"}
版本迁移
配置格式升级时,Config Manager 自动执行迁移脚本:
# 迁移脚本命名示例:migrations/config_v1_to_v2.py
def migrate(config: dict) -> dict:
# 将旧格式转换为新格式
config["sampling"]["idle_interval"] = config["sampling"].pop("idle_seconds")
config["_version"] = "2.0"
return config
迁移规则:
- 迁移脚本按版本号顺序执行;
- 每个迁移脚本必须是幂等的(可重复执行);
- 迁移失败时保留旧版本配置并告警;
- 用户可手动指定配置版本跳过迁移。
与权限系统的关系
插件注册 Schema 的权限受 Genapsed 权限系统管理:
- 插件只能注册自己命名空间下的配置字段;
- 多个组件不得注册冲突的全局字段;
- 系统核心组件(Frigate、MiniVLM)的 Schema 由 Genapsed 内置,插件不可覆盖;
- Config Manager 启动时对所有 Schema 做冲突检测。
文件生命周期管理
系统涉及多种文件类型,不同类型有不同的生命周期策略。Genapsed 负责协调各组件按以下策略管理文件的生命周期。
| 文件类型 | 生命周期建议 | 说明 |
|---|---|---|
| 原始录像 | 7 / 30 / 90 天(用户可配置) | 由 Frigate 管理,Genapsed 不做干预 |
| 事件截图 | 可长于原始录像(如 30 / 90 天) | 用于时间线缩略图展示和查询上下文 |
| 查询片段 | 临时生成,24 小时内清理 | 用户查询时由 Frigate 根据时间范围裁剪,用完即删 |
| 插件临时文件 | 插件处理完成后由 Genapsed 清理 | 插件通过 Genapsed 申请临时目录,使用完毕后通知清理 |
| 模型文件 | 跟随模型管理策略,手动或版本化更新 | MiniVLM 的模型文件,不自动删除 |
管理原则:
- Genapsed 不直接删除受 Frigate 或用户管理的文件——它只负责自己分配的临时目录和插件临时文件;
- 组件在自己职责范围内管理自己的文件生命周期;
- 磁盘空间低于预警阈值时,Genapsed 通知相关组件执行清理策略。
可观测性
健康检查
Genapsed 应定期检查以下组件的健康状态:
- Frigate 是否在线;
- MQTT Broker 是否可用;
- MiniVLM 是否可用;
- Genapsed 管理的 MySQL 是否可连接,组件库和授权是否可用;
- LLM 查询引擎是否可调用;
- 插件是否正常运行;
- 磁盘空间是否充足。
健康检查结果通过 MQTT 发布到 everpast/genapsed/status/normal,Supervisor(如存在)可以订阅此 topic 获取系统整体状态。
故障恢复策略
| 故障 | 恢复策略 |
|---|---|
| MQTT 断开 | 自动重连,必要时本地暂存事件,重连后补发 |
| MiniVLM 超时 | 发布预警,建议调高采样间隔或切换模型 |
| 时间线数据库不可写 | 暂停写入并告警,防止数据损坏 |
| 插件崩溃 | Genapsed 重启插件;连续崩溃超过阈值则禁用插件 |
| 磁盘空间不足 | 通知相关组件清理临时文件,如仍不足则暂停录像 |
| LLM API 不可用 | 查询引擎降级为关键词搜索和结构化字段过滤 |
日志覆盖范围
日志主源是 Genapsed 管理的本地 JSONL 文件,不写 MySQL。组件日志默认写入
data/logs/<component>/YYYY-MM-DD.jsonl,插件日志写入
data/logs/plugin/<id>/YYYY-MM-DD.jsonl。组件可以通过 everpast/<component>/log/<priority>
发送 structured_log 作为实时通知,Genapsed 校验来源和 Topic 权限并按需 ACK,但不再重复聚合落盘。
Genapsed 自身日志写入 data/logs/genapsed/YYYY-MM-DD.jsonl。开发模式下,Genapsed 同时启动 Docker 日志采集器,
把 MySQL、Mosquitto、Frigate 等 Compose 服务 stdout/stderr 转成结构化日志写入对应组件目录。
日志查询递归读取 data/logs,支持组件、来源、等级、关键词、trace_id、topic、时间范围和 cursor 分页;
清理策略默认按 14 天或 1GB 上限执行。
| 类型 | 示例 |
|---|---|
| 组件生命周期 | 启动、停止、重启、异常退出 |
| MQTT 消息 | 消息发送失败、ACK 超时、重试 |
| MiniVLM 推理 | 模型加载、推理耗时、解析失败 |
| 时间线写入 | 写入成功、重复事件、数据库错误 |
| 插件运行 | 插件异常、权限拒绝、资源超限 |
| 配置变更 | Schema 注册、配置更新、迁移执行 |