diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index d90d241a1..66e446276 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,18 @@ +## 2026-07-15 — P0-OBS-002 production OTLP/gRPC runtime closure + +**完成內容**: +- 在 Gitea CD `#5117` Success、production readback matched、API generation `10622` 連續 `3m22s` 維持 `2/2 Ready` 且 restart delta `0` 後,以 `P0-OBS-002-20260715T013800+0800` 執行 bounded apply。 +- 新增並啟用獨立 user-systemd gRPC compatibility bridge:`.188:24317 -> .110:4317`,僅允許 `.120/.121`;未變更 application endpoint、firewall、HTTP bridge `.24318` 或 producer active route。 +- 600 秒真實應用 post-verifier 通過:OpenAPI canary `200`、API restart delta `0`、trace/metric exporter errors `0`、`awoooi-api` traces `1098`、metric samples `60180`,rollback `not_required`。 +- 獨立旁路監看至 01:58:30:bridge MainPID 固定、NRestarts `0`、API 維持 `2/2`、post-bridge exporter errors `0/0`,freshness 每輪前進。 +- 新增 `ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml`,把 source、CD baseline、apply、post-verifier、rollback 與 remaining blockers 分層保存。 + +**仍維持**: +- 這只關閉 production application OTLP/gRPC transport asset;program 仍為 `partial_degraded`,active route 仍是 incumbent,producer promotion `0/5`。 +- organization 尚未初始化、direct ingress policy 尚未收斂、legacy HTTP bridge 尚未 supervised、filelog normalization 修正版尚未 runtime canary、Wave B 尚未進行。 +- `#5117` baseline source 為 `72bcbd788...`、marker `b49a1ec...`;其後 Gitea main 已前進到 `31de3a709...`,不得把本 receipt 倒推成較新 main 的 CD closure。 +- 本輪未讀 secret/token/`.env`/raw sessions/SQLite/auth,未使用 GitHub/`gh`,未改 firewall、DB、stateful volume、DNS 或 producer route。 + ## 2026-07-15 — P0-OBS-002 SigNoz canonical route Wave A **完成內容**: diff --git a/ops/signoz/organization-canonical-route-migration.yaml b/ops/signoz/organization-canonical-route-migration.yaml index 66dcb8ef0..e7e61f648 100644 --- a/ops/signoz/organization-canonical-route-migration.yaml +++ b/ops/signoz/organization-canonical-route-migration.yaml @@ -97,22 +97,29 @@ wave_b_gates: runtime_observations: logs_fresh: true metrics_fresh: true - traces_fresh: false - bridge_supervisor: legacy_orphan_process + traces_fresh: true + http_bridge_supervisor: legacy_orphan_process + grpc_bridge_supervisor: user_systemd_enabled_active application_otlp_grpc: endpoint: http://192.168.0.188:24317 root_cause: missing_incumbent_grpc_bridge + runtime_status: restored_verified confidence: 0.99 api_pods_ready_at_audit: 2 - recent_awoooi_api_trace_count: 0 + recent_awoooi_api_trace_count: 1098 + recent_awoooi_api_metric_sample_count: 60180 http_only_verifier_blind_spot: true + runtime_receipt: ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml source_fix: bridge: scripts/reboot-recovery/signoz-188-otlp-grpc-bridge.sh unit: ops/systemd/user/awoooi-signoz-otlp-grpc-bridge.service post_verifier: scripts/reboot-recovery/verify-signoz-otel-grpc-runtime.sh check_run_id: P0-OBS-002-grpc-bridge-check-20260715T012000+0800 check_terminal: pass - runtime_apply_status: check_pass_pending_stable_cd_window + runtime_run_id: P0-OBS-002-20260715T013800+0800 + runtime_apply_status: applied_post_verifier_pass + runtime_verifier_window_seconds: 600 + runtime_verifier_terminal: pass filelog_normalization: source_fix_canary_pending filelog_normalization_error_readback: window: 10m @@ -151,7 +158,6 @@ terminal: blockers: - organization_not_initialized - direct_ingress_policy_not_closed - - traces_not_fresh - - bridge_not_supervised + - http_bridge_not_supervised - filelog_normalization_degraded - wave_b_not_authorized diff --git a/ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml b/ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml new file mode 100644 index 000000000..7c75d3d17 --- /dev/null +++ b/ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml @@ -0,0 +1,93 @@ +schema: awoooi_signoz_grpc_runtime_receipt_v1 +work_item_id: P0-OBS-002 +trace_id: P0-OBS-002 +run_id: P0-OBS-002-20260715T013800+0800 +written_at: "2026-07-15T02:00:43+08:00" + +source_truth: + feature_branch: codex/p0-obs-002-20260715 + applied_source_sha: 88a457892ebfd89187d84f64a7f058a2822636e0 + merged_gitea_main_at_writeback: 31de3a709815f33a11ba6de6e78b771b7160a245 + baseline_cd: + run: 5117 + status: success + source_sha: 72bcbd7882f02990bfca6eaf67ea68cfa233c334 + deploy_marker_sha: b49a1ec164db6c90dd5db5661f0ce6db328f86df + production_readback_matched: true + job_succeeded: true + success_notification: true + later_main_cd_inferred: false + note: >- + Main advanced after baseline CD closure. This receipt proves the bounded gRPC + runtime run; it does not claim later-main deployment closure. + +preconditions: + api_generation: 10622 + api_ready: 2 + api_expected: 2 + stable_window_seconds: 202 + api_restart_delta: 0 + listen_192_168_0_188_24317_busy: false + upstream_192_168_0_110_4317_tcp_ready: true + source_range: 192.168.0.120/31 + incumbent_http_bridge_24318_changed: false + +controlled_apply: + risk: medium + execution: pass + listener: 192.168.0.188:24317 + upstream: 192.168.0.110:4317 + supervisor: user-systemd + supervisor_enabled: true + supervisor_active: true + source_nodes_verified: + - 192.168.0.120 + - 192.168.0.121 + firewall_changed: false + application_endpoint_changed: false + producer_route_promoted: false + secret_read: false + database_write: false + +post_verifier: + terminal: pass + window_seconds: 600 + canary_http_status: 200 + api_ready: 2 + api_expected: 2 + api_restart_delta: 0 + exporter_trace_errors: 0 + exporter_metric_errors: 0 + awoooi_api_trace_count: 1098 + awoooi_api_metric_sample_count: 60180 + bridge_restart_count: 0 + rollback: not_required + terminal_detail: real_application_otlp_grpc_trace_metric_freshness_closed + +independent_monitor: + terminal: pass + observed_until: "2026-07-15T01:58:30+08:00" + api_restart_delta: 0 + post_bridge_trace_export_errors: 0 + post_bridge_metric_export_errors: 0 + freshness_advanced_each_poll: true + +completion: + grpc_runtime_asset: closed + program: partial_degraded + active_route: incumbent + producer_canary_completed: 0 + producer_count: 5 + organization_initialized: false + wave_b_authorized: false + remaining_blockers: + - organization_not_initialized + - direct_ingress_policy_not_closed + - http_bridge_not_supervised + - filelog_normalization_degraded + - wave_b_not_authorized + learning_writeback: + machine_readable_receipt: pass + gitea_feature_ref_readback: pending_after_push + gitea_main_acknowledgement: pending + km_rag_mcp_acknowledgement: pending diff --git a/scripts/reboot-recovery/signoz-canonical-route-preflight.py b/scripts/reboot-recovery/signoz-canonical-route-preflight.py index bae9358e8..223786dc6 100644 --- a/scripts/reboot-recovery/signoz-canonical-route-preflight.py +++ b/scripts/reboot-recovery/signoz-canonical-route-preflight.py @@ -20,8 +20,7 @@ SCHEMA = "awoooi_signoz_canonical_route_preflight_v1" EXPECTED_BLOCKERS = [ "organization_not_initialized", "direct_ingress_policy_not_closed", - "traces_not_fresh", - "bridge_not_supervised", + "http_bridge_not_supervised", "filelog_normalization_degraded", "wave_b_not_authorized", ] diff --git a/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py b/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py index 3dbb4d8ed..e082704c9 100644 --- a/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py +++ b/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py @@ -22,6 +22,7 @@ FILELOG_CANARY = ROOT / "ops/signoz/filelog-normalization-canary.yaml" GRPC_BRIDGE = ROOT / "scripts/reboot-recovery/signoz-188-otlp-grpc-bridge.sh" GRPC_UNIT = ROOT / "ops/systemd/user/awoooi-signoz-otlp-grpc-bridge.service" GRPC_VERIFIER = ROOT / "scripts/reboot-recovery/verify-signoz-otel-grpc-runtime.sh" +GRPC_RUNTIME_RECEIPT = ROOT / "ops/signoz/p0-obs-002-grpc-runtime-receipt.yaml" def test_wave_a_contract_keeps_active_route_and_all_producers_on_incumbent() -> None: @@ -242,14 +243,28 @@ def test_grpc_runtime_verifier_uses_real_service_aggregates_and_ten_minute_gate( contract = yaml.safe_load(CONTRACT.read_text(encoding="utf-8")) grpc = contract["runtime_observations"]["application_otlp_grpc"] assert grpc["root_cause"] == "missing_incumbent_grpc_bridge" + assert grpc["runtime_status"] == "restored_verified" assert grpc["confidence"] == 0.99 - assert grpc["recent_awoooi_api_trace_count"] == 0 + assert grpc["recent_awoooi_api_trace_count"] == 1098 + assert grpc["recent_awoooi_api_metric_sample_count"] == 60180 assert grpc["http_only_verifier_blind_spot"] is True assert grpc["source_fix"]["check_terminal"] == "pass" assert ( grpc["source_fix"]["runtime_apply_status"] - == "check_pass_pending_stable_cd_window" + == "applied_post_verifier_pass" ) + assert grpc["source_fix"]["runtime_verifier_terminal"] == "pass" + + receipt = yaml.safe_load(GRPC_RUNTIME_RECEIPT.read_text(encoding="utf-8")) + assert receipt["run_id"] == grpc["source_fix"]["runtime_run_id"] + assert receipt["post_verifier"]["window_seconds"] == 600 + assert receipt["post_verifier"]["exporter_trace_errors"] == 0 + assert receipt["post_verifier"]["exporter_metric_errors"] == 0 + assert receipt["post_verifier"]["awoooi_api_trace_count"] == 1098 + assert receipt["post_verifier"]["awoooi_api_metric_sample_count"] == 60180 + assert receipt["post_verifier"]["rollback"] == "not_required" + assert receipt["completion"]["grpc_runtime_asset"] == "closed" + assert receipt["completion"]["program"] == "partial_degraded" def test_managed_promotion_and_bridge_retirement_fail_closed_without_receipts() -> None: