Skip to content

Commit 7b0b6e2

Browse files
committed
feat: M4 infrastructure completion - audit sinks, OTEL spans, CI fixes
- M4-A.1.2: Fix CI coverage threshold and mypy failures - M4-C.1-C.5: OTEL span instrumentation complete - M4-D.1-D.2: Sandbox security assertions and CI integration - M4-E.1-E.7: Audit sinks (Postgres, ObjectStore) with degradation - M4-F.1-F.3: Config sync and documentation - Add performance benchmarks for audit write and OTEL spans - Update AGENTS.md, TODO.md with M4 completion status - Update unit tests for audit sinks, storage backends, runtime factory
1 parent e0e49bd commit 7b0b6e2

15 files changed

Lines changed: 4296 additions & 4296 deletions

AGENTS.md

Lines changed: 187 additions & 187 deletions
Large diffs are not rendered by default.

TODO.md

Lines changed: 212 additions & 212 deletions
Large diffs are not rendered by default.

agentManager/observability/audit.py

Lines changed: 386 additions & 386 deletions
Large diffs are not rendered by default.

agentManager/runtime/factory.py

Lines changed: 306 additions & 306 deletions
Large diffs are not rendered by default.

agentManager/storage/postgres.py

Lines changed: 324 additions & 324 deletions
Large diffs are not rendered by default.
Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
1-
# 审计写入性能基准测试报告
2-
3-
**测试日期:** 2026-06-02
4-
**任务:** M4-F.3.2 - 测量审计写入对关键路径的性能影响
5-
**样本数:** 每种模式 1000 次
6-
7-
## 测试方法
8-
9-
该基准直接调用 `record_audit_event()`
10-
`disabled` 模式通过临时空 sink 集合测量函数框架开销。
11-
`log` 模式使用真实 logger。
12-
`db``object_storage` 模式使用 mock repository/object store,
13-
避免结果依赖外部 PostgreSQL 或 S3 网络状态。
14-
15-
## 结果
16-
17-
| 模式 | P50 (ms/event) | P99 (ms/event) | Mean (ms/event) | 阈值 | 结果 |
18-
|------|----------------|----------------|-----------------|------|------|
19-
| disabled | 0.0097 | 0.0574 | 0.0119 | < 0.1 | PASS |
20-
| log | 0.0110 | 0.0504 | 0.0140 | < 0.1 | PASS |
21-
| db | 0.0437 | 0.5462 | 0.1039 | < 5.0 | PASS |
22-
| object_storage | 0.0613 | 0.3698 | 0.0766 | < 50.0 | PASS |
23-
24-
## 结论
25-
26-
验收阈值:log sink P99 < 0.1ms/event,db sink P99 < 5ms/event,
27-
object_storage sink P99 < 50ms/event。
28-
db/object_storage 的本地结果代表框架映射与调用开销;
29-
真实服务延迟需在部署环境继续观测。
1+
# 审计写入性能基准测试报告
2+
3+
**测试日期:** 2026-06-02
4+
**任务:** M4-F.3.2 - 测量审计写入对关键路径的性能影响
5+
**样本数:** 每种模式 1000 次
6+
7+
## 测试方法
8+
9+
该基准直接调用 `record_audit_event()`
10+
`disabled` 模式通过临时空 sink 集合测量函数框架开销。
11+
`log` 模式使用真实 logger。
12+
`db``object_storage` 模式使用 mock repository/object store,
13+
避免结果依赖外部 PostgreSQL 或 S3 网络状态。
14+
15+
## 结果
16+
17+
| 模式 | P50 (ms/event) | P99 (ms/event) | Mean (ms/event) | 阈值 | 结果 |
18+
|------|----------------|----------------|-----------------|------|------|
19+
| disabled | 0.0097 | 0.0574 | 0.0119 | < 0.1 | PASS |
20+
| log | 0.0110 | 0.0504 | 0.0140 | < 0.1 | PASS |
21+
| db | 0.0437 | 0.5462 | 0.1039 | < 5.0 | PASS |
22+
| object_storage | 0.0613 | 0.3698 | 0.0766 | < 50.0 | PASS |
23+
24+
## 结论
25+
26+
验收阈值:log sink P99 < 0.1ms/event,db sink P99 < 5ms/event,
27+
object_storage sink P99 < 50ms/event。
28+
db/object_storage 的本地结果代表框架映射与调用开销;
29+
真实服务延迟需在部署环境继续观测。
Lines changed: 148 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,148 @@
1-
#!/usr/bin/env python3
2-
"""Measure audit event write overhead for configured sink modes."""
3-
4-
from __future__ import annotations
5-
6-
import statistics
7-
import time
8-
from dataclasses import dataclass
9-
from pathlib import Path
10-
from unittest.mock import MagicMock
11-
12-
from agentManager.observability import audit
13-
from agentManager.observability.audit import (
14-
AuditEvent,
15-
AuditEventType,
16-
configure_audit_sinks,
17-
record_audit_event,
18-
reset_audit_sinks,
19-
)
20-
21-
ITERATIONS = 1000
22-
REPORT_PATH = Path(__file__).with_suffix(".md")
23-
24-
25-
@dataclass
26-
class Result:
27-
mode: str
28-
p50: float
29-
p99: float
30-
mean: float
31-
threshold_ms: float
32-
threshold_passed: bool
33-
34-
35-
def _percentile(values: list[float], percentile: float) -> float:
36-
ordered = sorted(values)
37-
index = min(len(ordered) - 1, int(len(ordered) * percentile))
38-
return ordered[index]
39-
40-
41-
def _sample_event(index: int) -> AuditEvent:
42-
return AuditEvent(
43-
event_type=AuditEventType.TASK_EXECUTED,
44-
actor="benchmark",
45-
resource=f"task-{index}",
46-
outcome="success",
47-
detail={"duration_ms": index % 10, "token": "secret"},
48-
timestamp="2026-06-02T00:00:00+00:00",
49-
)
50-
51-
52-
def _measure(mode: str, threshold_ms: float, setup) -> Result:
53-
reset_audit_sinks()
54-
original_get_sinks = audit._get_audit_sinks
55-
try:
56-
setup()
57-
latencies: list[float] = []
58-
for index in range(ITERATIONS):
59-
start = time.perf_counter()
60-
record_audit_event(_sample_event(index))
61-
latencies.append((time.perf_counter() - start) * 1000)
62-
finally:
63-
audit._get_audit_sinks = original_get_sinks
64-
reset_audit_sinks()
65-
66-
p50 = statistics.median(latencies)
67-
p99 = _percentile(latencies, 0.99)
68-
return Result(
69-
mode=mode,
70-
p50=p50,
71-
p99=p99,
72-
mean=statistics.mean(latencies),
73-
threshold_ms=threshold_ms,
74-
threshold_passed=p99 < threshold_ms,
75-
)
76-
77-
78-
def _render_report(results: list[Result]) -> str:
79-
rows = "\n".join(
80-
"| {mode} | {p50:.4f} | {p99:.4f} | {mean:.4f} | < {threshold:.1f} | {status} |".format(
81-
mode=result.mode,
82-
p50=result.p50,
83-
p99=result.p99,
84-
mean=result.mean,
85-
threshold=result.threshold_ms,
86-
status="PASS" if result.threshold_passed else "FAIL",
87-
)
88-
for result in results
89-
)
90-
return "\n".join(
91-
[
92-
"# 审计写入性能基准测试报告",
93-
"",
94-
"**测试日期:** 2026-06-02",
95-
"**任务:** M4-F.3.2 - 测量审计写入对关键路径的性能影响",
96-
f"**样本数:** 每种模式 {ITERATIONS} 次",
97-
"",
98-
"## 测试方法",
99-
"",
100-
"该基准直接调用 `record_audit_event()`。",
101-
"`disabled` 模式通过临时空 sink 集合测量函数框架开销。",
102-
"`log` 模式使用真实 logger。",
103-
"`db` 和 `object_storage` 模式使用 mock repository/object store,",
104-
"避免结果依赖外部 PostgreSQL 或 S3 网络状态。",
105-
"",
106-
"## 结果",
107-
"",
108-
"| 模式 | P50 (ms/event) | P99 (ms/event) | Mean (ms/event) | 阈值 | 结果 |",
109-
"|------|----------------|----------------|-----------------|------|------|",
110-
rows,
111-
"",
112-
"## 结论",
113-
"",
114-
"验收阈值:log sink P99 < 0.1ms/event,db sink P99 < 5ms/event,",
115-
"object_storage sink P99 < 50ms/event。",
116-
"db/object_storage 的本地结果代表框架映射与调用开销;",
117-
"真实服务延迟需在部署环境继续观测。",
118-
"",
119-
]
120-
)
121-
122-
123-
def main() -> None:
124-
results = [
125-
_measure(
126-
"disabled",
127-
0.1,
128-
lambda: setattr(audit, "_get_audit_sinks", lambda: frozenset()),
129-
),
130-
_measure("log", 0.1, lambda: configure_audit_sinks("log")),
131-
_measure(
132-
"db",
133-
5.0,
134-
lambda: configure_audit_sinks("db", repository=MagicMock()),
135-
),
136-
_measure(
137-
"object_storage",
138-
50.0,
139-
lambda: configure_audit_sinks("object_storage", object_store=MagicMock()),
140-
),
141-
]
142-
report = _render_report(results)
143-
REPORT_PATH.write_text(report, encoding="utf-8")
144-
print(report)
145-
146-
147-
if __name__ == "__main__":
148-
main()
1+
#!/usr/bin/env python3
2+
"""Measure audit event write overhead for configured sink modes."""
3+
4+
from __future__ import annotations
5+
6+
import statistics
7+
import time
8+
from dataclasses import dataclass
9+
from pathlib import Path
10+
from unittest.mock import MagicMock
11+
12+
from agentManager.observability import audit
13+
from agentManager.observability.audit import (
14+
AuditEvent,
15+
AuditEventType,
16+
configure_audit_sinks,
17+
record_audit_event,
18+
reset_audit_sinks,
19+
)
20+
21+
ITERATIONS = 1000
22+
REPORT_PATH = Path(__file__).with_suffix(".md")
23+
24+
25+
@dataclass
26+
class Result:
27+
mode: str
28+
p50: float
29+
p99: float
30+
mean: float
31+
threshold_ms: float
32+
threshold_passed: bool
33+
34+
35+
def _percentile(values: list[float], percentile: float) -> float:
36+
ordered = sorted(values)
37+
index = min(len(ordered) - 1, int(len(ordered) * percentile))
38+
return ordered[index]
39+
40+
41+
def _sample_event(index: int) -> AuditEvent:
42+
return AuditEvent(
43+
event_type=AuditEventType.TASK_EXECUTED,
44+
actor="benchmark",
45+
resource=f"task-{index}",
46+
outcome="success",
47+
detail={"duration_ms": index % 10, "token": "secret"},
48+
timestamp="2026-06-02T00:00:00+00:00",
49+
)
50+
51+
52+
def _measure(mode: str, threshold_ms: float, setup) -> Result:
53+
reset_audit_sinks()
54+
original_get_sinks = audit._get_audit_sinks
55+
try:
56+
setup()
57+
latencies: list[float] = []
58+
for index in range(ITERATIONS):
59+
start = time.perf_counter()
60+
record_audit_event(_sample_event(index))
61+
latencies.append((time.perf_counter() - start) * 1000)
62+
finally:
63+
audit._get_audit_sinks = original_get_sinks
64+
reset_audit_sinks()
65+
66+
p50 = statistics.median(latencies)
67+
p99 = _percentile(latencies, 0.99)
68+
return Result(
69+
mode=mode,
70+
p50=p50,
71+
p99=p99,
72+
mean=statistics.mean(latencies),
73+
threshold_ms=threshold_ms,
74+
threshold_passed=p99 < threshold_ms,
75+
)
76+
77+
78+
def _render_report(results: list[Result]) -> str:
79+
rows = "\n".join(
80+
"| {mode} | {p50:.4f} | {p99:.4f} | {mean:.4f} | < {threshold:.1f} | {status} |".format(
81+
mode=result.mode,
82+
p50=result.p50,
83+
p99=result.p99,
84+
mean=result.mean,
85+
threshold=result.threshold_ms,
86+
status="PASS" if result.threshold_passed else "FAIL",
87+
)
88+
for result in results
89+
)
90+
return "\n".join(
91+
[
92+
"# 审计写入性能基准测试报告",
93+
"",
94+
"**测试日期:** 2026-06-02",
95+
"**任务:** M4-F.3.2 - 测量审计写入对关键路径的性能影响",
96+
f"**样本数:** 每种模式 {ITERATIONS} 次",
97+
"",
98+
"## 测试方法",
99+
"",
100+
"该基准直接调用 `record_audit_event()`。",
101+
"`disabled` 模式通过临时空 sink 集合测量函数框架开销。",
102+
"`log` 模式使用真实 logger。",
103+
"`db` 和 `object_storage` 模式使用 mock repository/object store,",
104+
"避免结果依赖外部 PostgreSQL 或 S3 网络状态。",
105+
"",
106+
"## 结果",
107+
"",
108+
"| 模式 | P50 (ms/event) | P99 (ms/event) | Mean (ms/event) | 阈值 | 结果 |",
109+
"|------|----------------|----------------|-----------------|------|------|",
110+
rows,
111+
"",
112+
"## 结论",
113+
"",
114+
"验收阈值:log sink P99 < 0.1ms/event,db sink P99 < 5ms/event,",
115+
"object_storage sink P99 < 50ms/event。",
116+
"db/object_storage 的本地结果代表框架映射与调用开销;",
117+
"真实服务延迟需在部署环境继续观测。",
118+
"",
119+
]
120+
)
121+
122+
123+
def main() -> None:
124+
results = [
125+
_measure(
126+
"disabled",
127+
0.1,
128+
lambda: setattr(audit, "_get_audit_sinks", lambda: frozenset()),
129+
),
130+
_measure("log", 0.1, lambda: configure_audit_sinks("log")),
131+
_measure(
132+
"db",
133+
5.0,
134+
lambda: configure_audit_sinks("db", repository=MagicMock()),
135+
),
136+
_measure(
137+
"object_storage",
138+
50.0,
139+
lambda: configure_audit_sinks("object_storage", object_store=MagicMock()),
140+
),
141+
]
142+
report = _render_report(results)
143+
REPORT_PATH.write_text(report, encoding="utf-8")
144+
print(report)
145+
146+
147+
if __name__ == "__main__":
148+
main()

0 commit comments

Comments
 (0)