跳到主要内容

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 桥接查看

第一阶段已确定接口

  1. Topic 统一为 everpast/<component>/<message_type>/<priority>[/target],由 core.topics.Topic 解析和生成,后续代码不应手写拼接 Topic。
  2. 系统消息统一使用 core.messages.MessageEnvelope,其中模型或组件业务输出只能放在 payload 内,系统字段由信封层维护。
  3. Config Manager 是 Genapsed 内部模块,配置主源在 MySQL,组件配置文件只是 Genapsed 渲染出的运行产物。
  4. 组件与插件统一进入 core.components.ComponentRegistry,健康状态使用 HealthSnapshot 上报,便于后续通过 MQTT 发布到 everpast/genapsed/status/normal
  5. 运行时适配层采用 Mosquitto + paho-mqtt;结构化数据采用 MySQL + SQLAlchemy + PyMySQL;开发模式由 Genapsed 生成项目内 Compose 文件管理 MySQL 和 Mosquitto。
  6. MQTT 适配器只负责连接、订阅、发布和消息反序列化;权限校验、路由策略和 ACK 重试由上层运行时服务组合实现。
  7. ACK 跟踪模块只维护待确认消息、TTL、最大重试次数、到期重试队列和失败队列,不直接执行网络发送。
  8. Topic 权限策略第一阶段按组件命名空间隔离:插件只能发布到自己的 plugin.<id> Topic,只能接收 Genapsed 广播或明确发给自己的 cmd 消息。
  9. 路由器采用显式规则,不做隐式兜底路由;未匹配消息不会被转发,避免错误消息被悄悄送到下游。

MQTT 后端选型

第一阶段 MQTT 后端采用 Mosquitto + paho-mqtt

模块选型边界
MQTT BrokerMosquitto作为外部消息代理服务部署,Genapsed 不自行实现 Broker 能力
Python MQTT Clientpaho-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可丢失

组件间通讯流程

  1. 组件 A 检测到事件,发布消息到 everpast/A/event/high
  2. Genapsed 收到消息,根据路由规则转发到组件 B 的订阅 topic
  3. 组件 B 处理完成后发送 ACK 确认
  4. Genapsed 将 ACK 转发给组件 A

运行时特殊消息处理

当前运行时服务除显式路由规则外,已经内置三类应用层消息处理,不做隐式兜底:

入站消息类型入口 Topic 示例处理行为结果 Topic
motion_detectedeverpast/nvr_bridge/event/high按显式路由规则转换为 analyze_task 并转发给 MiniVLMeverpast/genapsed/cmd/high/minivlm
timeline_event_generatedeverpast/minivlm/event/normal调用 Timeline 入库接口 ingest_envelope()everpast/genapsed/result/<priority>/minivlm
request_config_updateeverpast/www_server/config/normal/genapsed调用配置更新入口 request_config_update(actor_id, component_id, config)everpast/genapsed/result/<priority>/www_server
request_component_commandeverpast/www_server/cmd/<priority>/genapsed校验后以 Genapsed 身份转发标准组件命令everpast/genapsed/cmd/<priority>/<component_id>

timeline_event_generated 入库成功后,Genapsed 发布 timeline_event_stored result,payload 中包含 itemsource_msg_id;入库失败时发布 timeline_event_failed,随后继续抛出原始错误,避免用 fallback 掩盖写入问题。

request_config_update 成功后发布 config_update_applied,失败时发布 config_update_failed 并继续暴露异常。 配置变更真正的目标组件通知仍由 Config Manager 渲染配置后发布 config_updatedreload_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 跟踪队列。

文件传输机制

对于需要传输大文件的场景:

  1. 写入:发送方将文件复制到 Genapsed 管理的数据共享目录;
  2. 发送引用:通过 MQTT 发送轻量级消息,只包含共享目录相对路径;
  3. 读取:接收方解析消息后,到共享目录读取文件并复制到自己的组件数据目录。

默认数据根目录为主仓库下的 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-prefixEVERPAST_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 作为前台监督进程运行,按顺序完成:

  1. 渲染 data/genapsed/dev/compose.yaml
  2. --data-root 解析结果写入开发默认配置,并通过 EVERPAST_DATA_ROOT 传给组件进程;
  3. 启动当前开发计划需要的 Docker 依赖:MySQL、Mosquitto、Frigate;
  4. 初始化系统库、组件库、账号和 GRANT;
  5. 写入 data/genapsed/database/credentials.json
  6. 执行 Timeline 数据库迁移;
  7. 写入缺失的开发默认配置并渲染组件配置文件;
  8. 启动 Genapsed MQTT runtime,处理配置更新、组件命令转发和 Timeline 入库;
  9. 拉起 www-server、MiniVLM worker 和 NVR-Bridge worker 并监控进程状态。

停止时按反向生命周期执行:先停止 Genapsed 拉起的组件进程,再停止 MySQL、Mosquitto、 Frigate 等 Docker 依赖。开发调试需要复用 Docker 依赖时,可在 start --mode devdev 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.jsonldata/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

迁移规则:

  1. 迁移脚本按版本号顺序执行;
  2. 每个迁移脚本必须是幂等的(可重复执行);
  3. 迁移失败时保留旧版本配置并告警;
  4. 用户可手动指定配置版本跳过迁移。

与权限系统的关系

插件注册 Schema 的权限受 Genapsed 权限系统管理:

  1. 插件只能注册自己命名空间下的配置字段;
  2. 多个组件不得注册冲突的全局字段;
  3. 系统核心组件(Frigate、MiniVLM)的 Schema 由 Genapsed 内置,插件不可覆盖;
  4. Config Manager 启动时对所有 Schema 做冲突检测。

文件生命周期管理

系统涉及多种文件类型,不同类型有不同的生命周期策略。Genapsed 负责协调各组件按以下策略管理文件的生命周期。

文件类型生命周期建议说明
原始录像7 / 30 / 90 天(用户可配置)由 Frigate 管理,Genapsed 不做干预
事件截图可长于原始录像(如 30 / 90 天)用于时间线缩略图展示和查询上下文
查询片段临时生成,24 小时内清理用户查询时由 Frigate 根据时间范围裁剪,用完即删
插件临时文件插件处理完成后由 Genapsed 清理插件通过 Genapsed 申请临时目录,使用完毕后通知清理
模型文件跟随模型管理策略,手动或版本化更新MiniVLM 的模型文件,不自动删除

管理原则:

  1. Genapsed 不直接删除受 Frigate 或用户管理的文件——它只负责自己分配的临时目录和插件临时文件;
  2. 组件在自己职责范围内管理自己的文件生命周期;
  3. 磁盘空间低于预警阈值时,Genapsed 通知相关组件执行清理策略。

可观测性

健康检查

Genapsed 应定期检查以下组件的健康状态:

  1. Frigate 是否在线;
  2. MQTT Broker 是否可用;
  3. MiniVLM 是否可用;
  4. Genapsed 管理的 MySQL 是否可连接,组件库和授权是否可用;
  5. LLM 查询引擎是否可调用;
  6. 插件是否正常运行;
  7. 磁盘空间是否充足。

健康检查结果通过 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 注册、配置更新、迁移执行