Skip to main content

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}