From 74cc59eb62a2019863c90339c3c7c29c02ec09a0 Mon Sep 17 00:00:00 2001 From: Lan_zhijiang Date: Wed, 4 Nov 2026 21:29:20 +0800 Subject: [PATCH] =?UTF-8?q?docs(observability):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E9=87=87=E9=9B=86=E6=9F=A5=E8=AF=A2=E4=B8=8E=20Web=20=E8=A7=82?= =?UTF-8?q?=E6=B5=8B=E4=BD=93=E9=AA=8C=E5=A5=91=E7=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 10-prd/behavior/capabilities.md | 6 +++ 10-prd/behavior/observability.md | 23 ++++++++++ 10-prd/behavior/workflows.md | 4 ++ 10-prd/index.md | 1 + 20-product-tdd/core-app-boundary.md | 2 +- 20-product-tdd/observability-contract.md | 58 +++++++++++++++++++++--- 6 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 10-prd/behavior/observability.md diff --git a/10-prd/behavior/capabilities.md b/10-prd/behavior/capabilities.md index 5feaee2..8d31be8 100644 --- a/10-prd/behavior/capabilities.md +++ b/10-prd/behavior/capabilities.md @@ -65,3 +65,9 @@ 切换只改变后续交互的当前目标,不迁移或合并信息库,也不把已经绑定目标的待办或持续收入任务 改投新库。前台内容须与当前连接一致,不能把旧连接的结果显示为新库内容。后台任务是否继续执行 由对应能力的生命周期约定决定;切换不能被当作取消旧任务的操作。 + +## 能力:理解运行与诊断问题 + +- 使用者通过统一观测记录理解执行过程、定位异常并返回业务对象。 +- 内置与外部存储对采集和查询调用方保持相同语义,Web 提供共同的筛选与关联体验。 +- 行为与范围由 [可观测性](observability.md) 拥有;观测记录不取得业务状态或完整审计的权威。 diff --git a/10-prd/behavior/observability.md b/10-prd/behavior/observability.md new file mode 100644 index 0000000..a5a9598 --- /dev/null +++ b/10-prd/behavior/observability.md @@ -0,0 +1,23 @@ +# 理解运行与诊断问题 + +使用者需要知道工作是否开始、在哪个执行者上运行、何时结束,以及哪里出现问题。观测界面应能从一个 Job、Peer 或关联标识展开对应记录,也能从近期异常回到业务对象;业务对象的状态仍由业务数据决定。 + +## 统一基建 + +未配置外部观测存储时,记录存入内置信息库,并从同一存储读取。部署选择外部后端后,采集和查询使用该后端。业务生产者、普通库消费者和界面调用者不需要识别供应商或自行选择不同的查询逻辑。 + +后端选择不授予内容外发权限。默认记录运行阶段、结果类别、时长和关联身份等元数据;详细内容采集需要自己的明确配置。可观测性故障不改变业务成功、失败或重试语义;记录可能丢失,因此观测系统不能成为完整审计账本。 + +## Web 观测视图 + +工作区提供时间范围、严重度、记录种类、业务身份和文本筛选,展示记录详情与关联执行时间线。Job 页面使用同一查询能力,不另建只查特定存储的日志入口。用户可以检查当前后端与能力状态,区分配置存在、采集启用和查询可用。 + +空记录、查询失败、窗口被截断和历史不在当前后端是不同事实。页面不把加载失败显示成“没有日志”,不把当前窗口中的数量或时长概况标成整个部署的统计,不把缺失时长或用量显示成零。 + +历史成功 Job 没有记录时,保留其真实业务状态和时间,并说明没有观测记录;不得根据状态生成看似当时采集的日志。切换后端不会自动迁移或删除历史,界面说明只查询当前选中的存储。 + +## 范围与演进 + +基建和视图围绕同一记录、过滤、关联和错误语义演进。首次交付覆盖结构化日志、运行事件和操作摘要;标准分布式 Trace、指标导出仍可作为独立能力使用。操作摘要不冒充完整 Span 树;抽样或有界查询不承诺全量指标、账单、告警或确定性回放。 + +后端支持范围由实现明确列出,不能把“能够接收导出”描述成“能够查询”。新增后端需要实际写入和读取的双向映射,而不是要求使用者在界面添加供应商判断。跨实现合同见 [可观测性契约](../../20-product-tdd/observability-contract.md)。 diff --git a/10-prd/behavior/workflows.md b/10-prd/behavior/workflows.md index df60a9c..3795bb0 100644 --- a/10-prd/behavior/workflows.md +++ b/10-prd/behavior/workflows.md @@ -63,3 +63,7 @@ - normal flow: a versioned product adapter maps the request to memo-family graph commands; successful primary mutation is persisted, and native reads are rebuilt from resolver output - exception flow: unsupported protocol behavior or unresolved graph meaning fails explicitly; a failed or partially cleaned command may leave documented graph residue without claiming complete-server compatibility - observable outcome: the client observes a compatible result and the memo remains represented only by blocks, relations, and storage-backed actual content in the info-base + +## 流程:从异常或业务执行进入观测 + +用户从近期异常、Job 或 Peer 进入观测工作区,限定时间与关联身份,阅读记录和操作摘要,必要时缩窄被截断的窗口。界面明确展示读取失败、当前存储和历史范围,返回业务对象时沿用该对象的真实状态。具体行为见 [可观测性](observability.md)。 diff --git a/10-prd/index.md b/10-prd/index.md index df33884..2091b05 100644 --- a/10-prd/index.md +++ b/10-prd/index.md @@ -22,6 +22,7 @@ This package records shared product truth for InKCre: product purpose, observabl - `behavior/workflows.md` - `behavior/rules-and-invariants.md` - `behavior/scope.md` + - `behavior/observability.md` - domain structure: - `domain-structure/derived-boundaries.md` - `domain-structure/cross-domain-interactions.md` diff --git a/20-product-tdd/core-app-boundary.md b/20-product-tdd/core-app-boundary.md index b8102b0..54782c0 100644 --- a/20-product-tdd/core-app-boundary.md +++ b/20-product-tdd/core-app-boundary.md @@ -37,7 +37,7 @@ Core 可以执行 I/O、持有缓存和运行任务,也可以直接使用其 | Extension Host | 可复用加载/启停机制、兼容性检查、注册与释放规则,可独立选用 | 第一方分发组合、进程内安装/重启策略、平台资源和 UI 挂载 | | 具体业务 | 已由产品确立的通用领域能力可按需提供;不强制各语言实现同样广度 | Capture、Mail、Local Files 等具体业务由相应扩展拥有 | | 凭据与连接 | 接受明确配置与凭据;执行认证;有实际复用价值的凭据/连接持久化可以直接作为库能力 | 应用环境读取、当前选中连接、表单与授权交互政策 | -| 可观测性 | 传播上下文、记录库操作的事件;遵守既有内容边界 | 安装 exporter、选择目的地和资源预算、管理进程观测生命周期 | +| 可观测性 | 传播上下文、规范化事件、查询与存储机制;遵守既有内容边界 | 选择后端、持有私密凭据、安装 exporter、设置资源预算并管理生命周期 | | 运维与发布 | 声明需要的协议范围;提供普通运行所需的协议类型 | 数据库初始化/升级、部署、打包、签名、公证与服务启动 | 产品架构只规定 Core/App 的消费方向,并保留 Extension 的业务所有权,不增加统一的“平台适配层”。代码使用平台 API 本身不是归属判据:数据库驱动、Keychain 或浏览器存储可以实现一项有用的库能力;它们是否进入 core,取决于公开用途、依赖代价和支持的平台。 diff --git a/20-product-tdd/observability-contract.md b/20-product-tdd/observability-contract.md index fbe90bc..172e155 100644 --- a/20-product-tdd/observability-contract.md +++ b/20-product-tdd/observability-contract.md @@ -2,9 +2,11 @@ 本契约定义 InKCre 各 Peer 共同消费的观测身份、传播、持久 Job 因果关联及数据边界。它描述实现应满足的行为,不单独证明当前运行版本已具备这些能力。各 Unit 拥有采集实现,部署 owner 拥有采集出口、存储、查询与保留;SDK 版本、配置、后端限制和验收证据留在相应实现或部署文档。 -新增遥测必须由每个 Peer 的本地配置显式启用,缺省关闭;共享部署配置只描述身份和目的地,endpoint 或凭据存在不能自动开启。关闭时不初始化新增采集/导出,不新增 Trace Context 注入、提取或 Job carrier 捕获,仍保持现有日志与业务行为。开启也不自动替换、停用或桥接既有日志 writer;默认 PostgreSQL 日志及按 Job 查询继续可用。 +基础观测与额外 OTLP 出口是两个配置维度。基础观测使用统一记录/查询接口,缺省以内置数据库承接;部署明确选择外部存储后,新采集与当前查询使用该后端,不再强制双写 PostgreSQL。Job 执行开始和终态、已支持操作的摘要不依赖 OTLP 开关。旧记录不删除、不迁移,也不补造历史。 -本地开关在进程启动或客户端连接重新初始化时生效;首版不承诺热切换。开启所需配置不足时报告遥测初始化问题,但不使业务 readiness 失败;关闭不能删除已有日志或持久 carrier。 +额外 OpenTelemetry 导出与 W3C 上下文采集仍由每个 Peer 的本地配置显式启用,缺省关闭。关闭该出口不关闭基础观测;关闭时不新增 Trace Context 注入、提取或 Job carrier 捕获。原文内容的额外采集权限独立于以上开关。 + +后端配置在客户端或进程初始化时形成明确快照,不承诺透明热切换。选择外部但配置不完整、后端不可达或没有就绪的执行 Peer 时,查询明确失败,采集按有界策略报告丢弃,不能静默退回内置存储。观测故障不能使业务 readiness 失败。 ## 权威与身份 @@ -14,7 +16,7 @@ 部署标识、Peer 标识、运行实例与业务 ID 各有意义。部署配置 owner 提供稳定、非秘密的观测部署标识,同一部署的 Peer 与可选采集转发组件使用一致归属;不从凭据、数据库地址或观测产品的项目 ID 派生。重启与原部署恢复保持标识,独立 preview、克隆或新 owner 的部署分配新标识。配置尚不可用的记录可缺少该关联,不能伪造身份或以此阻止启动。 -共享部署配置使用 key `inkcre.observability`、schema `inkcre.observability.v1`;value 含 `deployment_id` UUID,以及可选、无凭据的 `otlp_http_endpoints` 对象与 `diagnostics_url`。出口对象按需声明 traces、logs、metrics 的完整 OTLP/HTTP URL;本地启用后缺省信号仍不导出,不要求所有信号共享一个 base URL;共享 value 不携带启用开关。部署启用步骤仅在缺失时创建身份,Peer 不各自生成;服务端私密采集凭据仅从运行配置提供,不进入客户端;客户端直连需使用适合其公开环境的受限写入能力,否则经过受控转发。凭据不进入该非秘密配置。各 Unit 注册和读取同一 schema;关闭的 Peer 不为新增遥测读取配置或初始化身份,开启时配置尚不可用只暂停新增遥测。 +共享部署配置使用 key `inkcre.observability`、schema `inkcre.observability.v1`;value 含 `deployment_id` UUID,以及可选、无凭据的 `otlp_http_endpoints` 对象与 `diagnostics_url`。出口对象按需声明 traces、logs、metrics 的完整 OTLP/HTTP URL;本地启用后缺省信号仍不导出,不要求所有信号共享一个 base URL;共享 value 不携带启用开关。部署启用步骤仅在缺失时创建身份,Peer 不各自生成;服务端私密采集凭据仅从运行配置提供,不进入客户端;客户端直连需使用适合其公开环境的受限写入能力,否则经过受控转发。凭据不进入该非秘密配置。各 Unit 注册和读取同一 schema;关闭额外 OTLP 的 Peer 不为该出口读取配置或初始化身份,开启时配置尚不可用只暂停该出口。基础记录的后端选择使用独立配置,不依赖 OTLP 身份初始化。 Peer 复用现有身份,运行实例区分进程或客户端运行期,Job、Thread、ToolCall 与实体保留业务 ID。Trace/Span ID 由标准 SDK 管理,不能用业务 ID 替代。可变业务 ID 适合日志与 Trace 关联,不进入无界指标标签。资源属性用于筛选和诊断,不提供认证或权限证明。 @@ -34,11 +36,11 @@ Job 的提交和执行可以属于不同 Peer、进程与时间段。公共持 Python、浏览器直写及其它直接数据库生产者采用同一提交语义。HTTP 创建入口从当前标准上下文捕获,不要求旧创建 body 接受新遥测字段。Cron 在实际创建一次 Job 时捕获该次发生的上下文,不永久继承最初创建 Cron 的请求。 -开启且成功领取的执行器建立独立执行 trace,用 Span Link 连接有效的提交上下文,并在诊断记录中保留同一 Job ID。领取失败不记成实际执行。没有 carrier 的旧 Job 仍可执行;通过普通结构约束但 W3C 语义无效的 carrier 只失去因果 link,不使持久 Job 挂起。关闭的执行器不产出新增 span,但领取和关闭必须保留行中已有 carrier。不同 Peer 的开关可以不同,因而允许提交或执行 Trace 缺失,不影响业务执行。查询可始终按 Job ID 关联,不以提交 trace 仍在保留期内为前提。 +开启且成功领取的执行器建立独立执行 trace,用 Span Link 连接有效的提交上下文,并在诊断记录中保留同一 Job ID。领取失败不记成实际执行。没有 carrier 的旧 Job 仍可执行;通过普通结构约束但 W3C 语义无效的 carrier 只失去因果 link,不使持久 Job 挂起。关闭额外 OTLP 的执行器不产出标准执行 Trace,但领取和关闭必须保留行中已有 carrier。不同 Peer 的开关可以不同,因而允许提交或执行 Trace 缺失,不影响业务执行。查询可始终按 Job ID 关联,不以提交 trace 仍在保留期内为前提。 普通字段的类型、允许表面和大小边界仍有效;观测容错不意味着接受任意输入。可选字段不自动授予跨版本运行能力。生产者与执行器必须满足[Peer 数据库运行契约](peer-database-runtime-contract.md)的准入要求,交付明确支持的 runtime/schema 组合与顺序;禁止通过写失败后重放 Job 来探测兼容。Job 的领取、取消、终态、timeout 和 Cron 发生语义仍由[知识能力契约](knowledge-capability-contract.md)拥有。 -现有 PostgreSQL 日志及其按 Job 查询能力持续保留;新增后端是按需启用的诊断增强,开启/关闭均不自动停旧 writer、搬迁历史、删除表或改变原日志关联 ID。新查询通过不构成退役旧日志的授权。 +现有 PostgreSQL 日志保留为历史记录,按既有 Job 关联 ID 映射到统一查询。选择外部后,当前查询只覆盖该后端;切换不自动搬迁历史、删除表或改变原日志关联 ID,也不自动退回旧存储读取。没有生命周期记录的旧 Job 只展示真实业务状态,不补写虚构事件。 ## AI 诊断与结果证据 @@ -52,7 +54,7 @@ Usage 以 provider 实际返回为依据,覆盖流式结束阶段。未提供 [共享安全模型](security-boundary-model.md)定义 actor 与权限。这里需要限定的路径是:外部输入或异常携带内容、凭据,经采集写入观测存储,再被超出预期范围的读者或外部运营者取得。Trace Context、Peer/resource 属性及 CORS 均不构成授权。 -新增 OTLP 基础模式只采集声明的元数据和关联 ID。Prompt、query、工具参数/结果、引用内容、任意请求响应 body、SQL 参数和异常原文不因打开 tracing 自动获得保存许可;Authorization、Cookie、provider 配置和签名 URL 也不自动采集。基础出口只接入声明来源、字段和值来源的结构化记录,策略覆盖 span 名称、status、events、Resource 与 log body,不能仅过滤 headers 或在远端补做清洗。应用、SDK 和第三方的任意原文日志不得自动桥接;既有 PG/其它已配置 writer 按原配置保持内容行为,不要求为了保留它们再次启用新内容模式。“原文默认关闭”只约束新增 OTLP 出口,不代表整个部署无内容副本。 +新增 OTLP 基础模式只采集声明的元数据和关联 ID。Prompt、query、工具参数/结果、引用内容、任意请求响应 body、SQL 参数和异常原文不因打开 tracing 自动获得保存许可;Authorization、Cookie、provider 配置和签名 URL 也不自动采集。基础出口只接入声明来源、字段和值来源的结构化记录,策略覆盖 span 名称、status、events、Resource 与 log body,不能仅过滤 headers 或在远端补做清洗。应用、SDK 和第三方的任意原文日志不得自动桥接到额外 OTLP。基础统一记录也不因选择外部后端自动扩大内容权限;新结构化采集按允许的元数据字段产生固定说明。既有原文日志属于历史,读取它们不宣称已脱敏,存量内容不自动搬往外部。 内容启用独立于基础性能元数据,并明确用途、可访问者、大小与截断、保留和删除。已有 debug 开关不能自动授权向新增观测出口发送内容。删除业务源数据不会天然删除遥测副本,启用内容时必须处理这个差别。 @@ -60,6 +62,48 @@ Usage 以 provider 实际返回为依据,覆盖流式结束阶段。未提供 ## 后端可替换性与验证 -应用采集依赖 OpenTelemetry、OTLP 和公共业务语义,不依赖供应商 SDK、项目或 datasource ID,持久业务 schema/carrier 不保存供应商身份;后端替换应发生在出口配置、存储与消费侧,不要求改写业务采集逻辑。OTLP 兼容不保证历史数据、查询和仪表盘可以无成本迁移。部署交付记录属性映射、必要因果字段、保留或损失的协议信息、导出能力及查询迁移方法;不可恢复的字段损失不能通过默认值伪装成原始观测。 +额外 Trace/指标出口依赖 OpenTelemetry、OTLP,基础记录依赖下述公共语义;业务采集不依赖供应商 SDK、项目或 datasource ID,持久业务 schema/carrier 不保存供应商身份;后端替换应发生在出口配置、存储与消费侧,不要求改写业务采集逻辑。OTLP 兼容不保证历史数据、查询和仪表盘可以无成本迁移。部署交付记录属性映射、必要因果字段、保留或损失的协议信息、导出能力及查询迁移方法;不可恢复的字段损失不能通过默认值伪装成原始观测。 准入应从独立后端查询核对关键字段的可消费语义、缺失与真零、必要因果关联及指标聚合,声明类型投影和损失,并覆盖持久化后的消费。发送成功不算持久化证明。故障验收还需比较真实业务结果,检查应用及可选 Collector 的队列、关闭、丢弃与恢复;只停后端、只测 SDK 或只读取数据库模型不能替代端到端验收。 + +## 统一记录、查询与执行能力 + +产品行为由 [可观测性](../10-prd/behavior/observability.md) 拥有。Core 提供记录、查询和存储机制,也拥有标准遥测 SDK 与 OTLP 导出机制;App 持有后端私密配置、装配资源并管理关闭,Web 只消费公共接口。业务代码不绕过 Core 单独连接 OTLP;同一操作的采集入口在 Core 内协调基础记录与按配置启用的标准信号。这里的存储替换边界来自真实的内置/外部消费者,不要求其他 Core 能力统一抽象平台适配器。 + +非秘密后端选择使用独立配置 key `inkcre.observability.backend`、schema `inkcre.observability.backend.v1`,value 为 `{ "backend": "postgresql" }` 或 `{ "backend": "loki" }`。缺少该记录时使用 `postgresql`;未知 schema 或后端明确不支持,不能视为缺省。原 `inkcre.observability.v1` 的 OTLP 配置形状不变,以兼容严格校验的已发布消费者。 + +首个双向外部实现为 Loki;其它已配置的日志 writer 或 OTLP endpoint 不能仅凭存在就冒充统一查询后端。Loki URL、认证和租户信息由具备能力的服务 Peer 私密持有,公共配置与浏览器均不携带它们。多个服务 Peer 必须装配同一部署选中的存储;同一公共选择不允许在不同 Peer 上代表不同租户的数据。 + +各实现通过 `core.observability.v1` 精确 Peer 能力提供 `POST /observability`,沿用已有 Peer 认证、发现与 HTTP 协议。请求包含 `action`:`status`、`query` 或 `ingest`。委派的 `query`/`ingest` 必须附上 `expected_backend`,服务将其与本实例选择原子核对;不匹配返回 409,不把请求写入另一个存储。候选状态探测不能代替这次接收边界检查。数据库模式的客户端可以直接使用已准入数据库协议实现同一接口;外部模式通过具备私密配置的 Peer 执行,业务请求不因此集中到该 Peer。调用者不能指定任意外部 URL、请求头或原生查询语言。 + +### 公共 JSON + +记录 `ObservationRecord`: + +- `id`:不透明字符串;旧数据库数字身份加命名空间后投影,不作为跨后端自增序号。 +- `timestamp`:带时区的 ISO 时间;`kind` 为 `log`、`event` 或 `span`。 +- `severity_number`、`severity_text`:沿用已有 OTEL 1–24 严重度(INFO 9、WARN 13、ERROR 17、FATAL 21),不直接使用 Python logging 的 10/20/30/40/50;`body` 为可展示说明。 +- `event_name`、`trace_id`、`span_id` 可为 null。既有 `job.` 关联可继续使用,不将其伪装为标准 W3C Trace ID。 +- `attributes` 承载声明的元数据;公共关联键包含 `inkcre.peer.id`、`inkcre.job.id`、`inkcre.operation`、`duration_ms`、`outcome`。时长和用量缺失不补零。`span` 在此表示操作摘要,不承诺完整 Trace 树。 + +查询 `query` 包含 `since`、`until`、`limit`(1 至 500),可选 `kind`、`severity_min`、`job_id`、`trace_id`、`peer_id`、`operation`、`text`。输入在接收边界校验,时间窗最多 31 天,起点包含而终点不包含,文本不是正则或后端查询语言。结果为 `{ records, truncated, since, until, backend }`,按时间倒序返回。所有过滤由后端语义一致地执行;不先任意截断再把过滤后的子集冒充完整查询。 + +窗口可能被截断。接口不提供虚假的跨后端稳定 cursor,特别不能用最后一条时间戳跳过同刻记录。界面提示缩小时间或过滤范围;摘要只描述返回窗口,不用于全局分位数、账单或审计计数。 + +`status` 返回 `{ backend, configured, recording, queryable, scope: "selected_backend", history, dropped, error }`。配置存在不等于网络已验证;`queryable` 表示当前实现具备查询所需配置/能力,实际查询仍可失败。`dropped` 属于报告实例已知的丢弃数,不冒充部署总数;不支持该统计的消费者返回 null。错误使用无凭据、无上游响应原文的诊断。 + +`ingest` 包含 `records`(最多 100 条,整体最多 256 KiB),返回 `{ accepted, dropped }`;接受表示进入有界处理,不等于已持久化。不得以采集失败重放业务写入。服务需要限制并发、记录大小、元数据容量和关闭时限。 + +### 生命周期与历史 + +对象绑定目标部署与后端选择,进行中的写入/查询不随 UI 切换改投另一目标。App 重建实例以采用新配置;Web 忽略旧连接返回的延迟结果。外部后端失败不切换查询源,退出仅释放本实例拥有的队列、连接和任务。 + +成功领取 Job 后记录开始,完成、失败、超时、取消记录实际终态。观测失败不能推翻数据库已提交的状态,不能把没有记录视为没有执行。采集仅覆盖实际经过已接入实现的执行;旧 Peer 或未采集的信号允许缺失。 + +### Web 消费 + +全局工作区和 Job 详情复用同一查询客户端。过滤、关联详情、操作时间线和当前窗口摘要不包含供应商分支。状态面板展示当前存储、配置/能力、历史说明及读取故障;加载、空、错误和截断分别呈现。外部完整 Trace/指标系统可通过已配置诊断入口访问,不用当前窗口的操作摘要假装实现完整 APM。 + +### 变更验证 + +内置与外部后端使用同一合同样例核对记录、过滤、时间、关联、截断和错误;覆盖配置缺失、未知选择、外部不可用、目标切换和资源关闭。局部模拟传输只证明编解码与控制流,真实持久化、部署路由和跨 Peer 数据读取需要单独的端到端证据。旧合同“始终并行保留 PG writer”的要求由本节替代;数据保留及既有业务协议权限不变。