khora_core/telemetry/event.rs
1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Event types for engine-wide telemetry.
16
17use crate::control::gorna::AgentId;
18use crate::telemetry::metrics::{MetricId, MetricValue};
19use crate::telemetry::monitoring::{GpuReport, HardwareReport, ResourceUsageReport};
20
21/// A high-level telemetry event produced by the Hot Path or hardware sensors.
22#[derive(Debug, Clone)]
23pub enum TelemetryEvent {
24 /// A single metric sample update.
25 MetricUpdate {
26 /// The metric identifier.
27 id: MetricId,
28 /// The new value.
29 value: MetricValue,
30 },
31 /// A hardware resource usage report (typically bytes/memory).
32 ResourceReport(ResourceUsageReport),
33 /// A physical hardware health report (thermal, CPU load).
34 HardwareReport(HardwareReport),
35 /// A GPU performance report (frame timings, draw calls, triangles).
36 GpuReport(GpuReport),
37 /// A change in the execution phase signaled by the engine.
38 PhaseChange(String),
39 /// A per-agent execution-cost sample: the workload size `n` an agent
40 /// processed this frame and the wall-clock time it took. The DCC feeds
41 /// these to a per-agent cost model (`c·f(n)`) so it can *forecast* a budget
42 /// breach ("at this growth rate the frame budget breaks at ~N") instead of
43 /// only reacting. Published once per agent per frame from the hot path.
44 AgentCost {
45 /// The agent that produced the sample.
46 id: AgentId,
47 /// Workload size processed this frame (e.g. live entity count).
48 n: f64,
49 /// Wall-clock execution time, in milliseconds.
50 time_ms: f64,
51 },
52 /// The scheduler's per-frame **wave plan**: how the agents will actually be
53 /// grouped for execution. Each inner list is one wave — agents that run
54 /// concurrently (an `Isolated` set plus at most one `SharedWorld` agent);
55 /// a singleton list is a serially-executed agent. Published only when
56 /// parallel execution is enabled (serial execution needs no grouping — the
57 /// DCC then falls back to summing per-agent costs).
58 ///
59 /// The DCC uses it to cost a concurrent wave by its **critical path**
60 /// (`max` of its members) instead of the sum, so budget fitting doesn't
61 /// leave frame time on the table for work that overlaps.
62 WavePlan {
63 /// Agent ids grouped by wave, in execution order.
64 waves: Vec<Vec<AgentId>>,
65 },
66 /// A per-component access-pattern snapshot from the ECS, for the layout
67 /// advisor (AGDF). Cumulative counters, sampled at a low rate (not every
68 /// frame); the DCC turns them into a read-only layout recommendation.
69 ComponentAccess {
70 /// Component type name (for the glass-box report).
71 type_name: String,
72 /// Component size in bytes (`size_of`).
73 size_bytes: usize,
74 /// Cumulative number of queries that touched this component.
75 query_count: u64,
76 /// Cumulative rows scanned across those queries.
77 rows_scanned: u64,
78 },
79}