aivcs_core/obs.rs
1//! Structured observability hooks for AIVCS run lifecycle events.
2//!
3//! This module provides:
4//! - Run-scoped tracing spans via `RunSpan` RAII guard
5//! - Emission functions for key lifecycle events: start, event append, finish, gate evaluation
6//!
7//! Events are emitted at `info!` level (configurable via `AIVCS_LOG` env var).
8//! For JSON output, set `AIVCS_LOG_FORMAT=json`.
9
10use tracing::info;
11
12/// RAII guard that enters a run-scoped tracing span for the duration of a run.
13///
14/// # Example
15///
16/// ```ignore
17/// let _span = RunSpan::enter("run-12345");
18/// // Now all tracing calls are automatically associated with run_id = "run-12345"
19/// ```
20pub struct RunSpan {
21 _span: tracing::span::EnteredSpan,
22}
23
24impl RunSpan {
25 /// Create and enter a span tagged with the run_id.
26 pub fn enter(run_id: &str) -> Self {
27 let span = tracing::info_span!("aivcs.run", run_id = %run_id);
28 Self {
29 _span: span.entered(),
30 }
31 }
32}
33
34/// Emit event: run started with agent name.
35///
36/// # Example
37///
38/// ```ignore
39/// emit_run_started("run-123", "my_agent");
40/// // logs: event=run.started run_id=run-123 agent_name=my_agent
41/// ```
42pub fn emit_run_started(run_id: &str, agent_name: &str) {
43 info!(event = "run.started", run_id = %run_id, agent_name = %agent_name);
44}
45
46/// Emit event: run finished with duration, total events, and success status.
47pub fn emit_run_finished(run_id: &str, duration_ms: u64, total_events: u64, success: bool) {
48 info!(
49 event = "run.finished",
50 run_id = %run_id,
51 duration_ms = duration_ms,
52 total_events = total_events,
53 success = success,
54 );
55}
56
57/// Emit event: a single event appended to the run.
58pub fn emit_event_appended(run_id: &str, event_kind: &str, seq: u64) {
59 info!(event = "run.event_appended", run_id = %run_id, kind = %event_kind, seq = seq);
60}
61
62/// Emit event: gate evaluation completed with pass rate and verdict.
63pub fn emit_gate_evaluated(run_id: &str, pass_rate: f32, passed: bool) {
64 info!(
65 event = "gate.evaluated",
66 run_id = %run_id,
67 pass_rate = pass_rate,
68 passed = passed,
69 );
70}
71
72/// Emit event: run finalization error (warning level).
73pub fn emit_run_finalize_error(run_id: &str, error: &dyn std::fmt::Display) {
74 tracing::warn!(event = "run.finalize_error", run_id = %run_id, error = %error);
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_run_span_create() {
83 // Just ensure RunSpan::enter doesn't panic
84 let _span = RunSpan::enter("test-run-id");
85 }
86}