Skip to content

Latest commit

 

History

History
110 lines (83 loc) · 5.84 KB

observability.md

File metadata and controls

110 lines (83 loc) · 5.84 KB
title Observability 开发规范
description 使用稳定字段、正确的 correlation 和 failure isolation 添加 operational events。

Observability 开发规范

新增 log、metric 或 span 前,先确定它回答什么问题,以及哪个 boundary 拥有这项 observation。 字段名称、单位、outcome、error category 和 correlation 语义遵循 operational field contract。 RFC 0046 定义 privacy 与 signal ownership。

新增 operational event

使用 module logger 和 powercontext._logging.log_safely。Message 使用固定文本,批准的诊断值放入 structured fields。 优先记录有用的状态变化和失败;详细的 stage completion 通常使用 DEBUG。 已有 transport/application instrumentation 会统计次数和耗时,不要重复创建这些工作单元。

import logging
from time import perf_counter

from powercontext._logging import log_safely

logger = logging.getLogger(__name__)


def record_search_completion(started_at: float) -> None:
    log_safely(
        logger,
        logging.DEBUG,
        "Memory search completed",
        extra={
            "event": "memory.search.completed",
            "operation": "memory.search",
            "unit": "stage",
            "outcome": "success",
            "duration_ms": max(perf_counter() - started_at, 0) * 1000,
        },
    )

在所属 search stage 成功完成后调用。这里的 operation 与 Runtime stage name 一致;application events 使用 HTTP contract 声明的 operation ID,例如 search_memory,HTTP 和 MCP 使用相同名称。 示例中的字段已在 allowlist 中,不需要修改 formatter。它不是 public instrumentation API。

在观察到 failure 或 cancellation 的 boundary 记录结果。No-op 和 policy block 与 error 保持区别。 使用已登记的 diagnostic code,以及可用时实际映射的 status,由 adapter 派生有限取值的 error_category。 不要把任意 exception message 当作 code。Cancellation 必须继续向上传播。

复用 execution identity

Server filter 从已绑定的 request context 补充缺失的 request_id,并关联当前 trace/span IDs。 Event 显式提供的 request ID 会保留。不要在 Runtime 方法中生成 request ID。 关闭 recording/export 后仍可能存在 trace ID,因此 correlation ID 本身不能证明 backend 保存了 trace。

Spawn runner 为 child events 绑定 assignment 拥有的 worker fields。Supervisor 使用同一个 worker_id 关联该 attempt;每个进程有自己的 service_instance_id。Scheduled work 清除偶然继承的 request correlation。 在已配置的 worker 内只需输出自己的 event,不要重新生成这些 identities。

artifact_processing.worker.returned 表示 child 返回结果; artifact_processing.worker.acknowledged 才表示 supervisor 验证了 durable acknowledgement。 新增 lifecycle event 时保留这一区别,不能仅凭 process exit 判断业务完成。

扩展 structured fields

JSON formatter 会忽略未登记的 extras。确需新增字段时:

  1. 定义含义、类型、单位、允许值和 privacy boundary。Count 必须说明统计单元; RSS high-water mark 不能描述为单次 request allocation。
  2. 更新 src/powercontext/server/logging.py 中适用的 allowlist:通用字段为 _OPERATIONAL_FIELDS, processing 为 _PROCESSING_FIELDS,code.* events 为 _CODE_FIELDS。
  3. 验证 JSON 和 console 输出。_HumanContextFilter 使用相同的 allowlists;request、trace 和 service identity 使用专用 console rendering,code 专用字段仅在 code.* events 中输出。
  4. 更新中英文 operational field contract,并补充针对可观察输出的 regression test。 重命名或删除已发布字段、event name 前,必须检查 compatibility。

Service identity 来自 src/powercontext/server/telemetry.py,logs 和 traces 共用同一 resource identity。 Error classification 来自 powercontext._logging.error_category;blocked 等 domain-owned category 由所属 boundary 明确设置。各 adapter 不应自行定义不同词汇。

保持 privacy 和 ownership

不要记录 Source/Memory content、query、prompt、response、vector、credential、authorization header、 完整 database URL 或敏感 filesystem path。Allowlist 只控制字段,不会自动对值脱敏。 这些值也不能拼入 message 或原样包含在 provider exception 中。 只有确认 error values 和关联上下文不含敏感数据后,才使用 exc_info。

Server 配置 handlers 和 format,通过 worker_initializer 向自动构建的 spawn workers 注入可序列化的 WorkerLogging bootstrap。Custom bindings 自己管理 launcher initialization。 通过 SDK 导入或运行 Runtime 时,不得配置 global logging。 Runtime observations 不依赖 Server settings、Prometheus 或 OTel implementation types。

Operational logs 保持 best-effort。Server handler 隔离 filter、formatter 和 write failures, 每个 handler 最多输出一次无内容的 failure notification。 不要把 logs 或 sampled traces 当作 durable audit、billing 或 commit ledger。 Request、trace、scope、source 和 worker identities 不作为 metric labels。

验证行为

运行 logging 与真实 worker 的 focused checks:

uv run pytest tests/test_server_logging.py tests/e2e/test_worker_logging.py -q

新增 instrumentation 时,验证可能回归的可观察结果:success、适用的 failure/cancellation、必要字段输出、 敏感值排除和 failure isolation。跨进程支持必须用真实 spawned worker 验证; 直接调用 hook 或替换 worker entrypoint 不能证明内置 worker 的完整覆盖。 Model provider 或 OTLP backend 的支持声明需要各自的真实执行证据。交付前运行 make check。