Skip to main content

icydb_core/metrics/sink/
events.rs

1//! Module: metrics::sink::events
2//! Responsibility: stable instrumentation event taxonomy for metrics sinks.
3//! Does not own: global metrics state mutation or report rendering.
4//! Boundary: exposes event enums consumed by metrics sinks and runtime instrumentation.
5
6use crate::error::ErrorClass;
7use std::rc::Rc;
8
9///
10/// ExecKind
11///
12
13#[derive(Clone, Copy, Debug)]
14#[remain::sorted]
15pub enum ExecKind {
16    Delete,
17    Load,
18    Save,
19}
20
21///
22/// ExecOutcome
23///
24
25#[derive(Clone, Copy, Debug)]
26#[remain::sorted]
27pub enum ExecOutcome {
28    Aborted,
29    ErrorConflict,
30    ErrorCorruption,
31    ErrorIncompatiblePersistedFormat,
32    ErrorInternal,
33    ErrorInvariantViolation,
34    ErrorNotFound,
35    ErrorUnsupported,
36    Success,
37}
38
39///
40/// CacheKind
41///
42
43#[derive(Clone, Copy, Debug)]
44#[remain::sorted]
45pub enum CacheKind {
46    SharedQueryPlan,
47    SqlCompiledCommand,
48}
49
50///
51/// CacheOutcome
52///
53
54#[derive(Clone, Copy, Debug)]
55#[remain::sorted]
56pub enum CacheOutcome {
57    Hit,
58    Insert,
59    Miss,
60}
61
62///
63/// CacheMissReason
64///
65/// Stable cache miss reason buckets for cache identities that already have a
66/// scoped entity path. These categories explain why a lookup missed without
67/// exposing query text, field names, or schema hashes in the metrics report.
68///
69
70#[derive(Clone, Copy, Debug, Eq, PartialEq)]
71#[remain::sorted]
72pub enum CacheMissReason {
73    Cold,
74    DistinctKey,
75    SchemaFingerprint,
76    SchemaVersion,
77    Surface,
78    Visibility,
79}
80
81impl ExecOutcome {
82    // Map the crate's typed runtime error taxonomy into stable metrics buckets.
83}
84
85///
86/// SaveMutationKind
87///
88
89#[derive(Clone, Copy, Debug)]
90#[remain::sorted]
91pub enum SaveMutationKind {
92    Insert,
93    Replace,
94    Update,
95}
96
97///
98/// MutationCommitClass
99///
100
101#[derive(Clone, Copy, Debug, Eq, PartialEq)]
102#[remain::sorted]
103pub enum MutationCommitClass {
104    DurableOnly,
105    LiveOnly,
106    MixedDurableAndLive,
107}
108
109///
110/// SchemaReconcileOutcome
111///
112/// Stable startup/metadata reconciliation outcomes for the schema trust
113/// boundary. The enum is intentionally low-cardinality so metrics can explain
114/// schema acceptance failures without exposing field names or diagnostic text.
115///
116
117#[derive(Clone, Copy, Debug, Eq, PartialEq)]
118#[remain::sorted]
119pub enum SchemaReconcileOutcome {
120    ExactMatch,
121    FirstCreate,
122    LatestSnapshotCorrupt,
123    RejectedFieldSlot,
124    RejectedOther,
125    RejectedRowLayout,
126    RejectedSchemaVersion,
127    StoreWriteError,
128}
129
130///
131/// SchemaTransitionOutcome
132///
133/// Stable schema transition policy buckets. These counters isolate the policy
134/// decision for an existing accepted snapshot from broader reconciliation
135/// outcomes such as first-create writes, corrupt stores, or store failures.
136///
137
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
139#[remain::sorted]
140pub enum SchemaTransitionOutcome {
141    AddExpressionIndex,
142    AddFieldPathIndex,
143    AppendOnlyFields,
144    ConstraintActivation,
145    ExactMatch,
146    MetadataOnlyFieldDefault,
147    MetadataOnlyIndexRename,
148    RejectedEntityIdentity,
149    RejectedFieldContract,
150    RejectedFieldSlot,
151    RejectedRowLayout,
152    RejectedSchemaVersion,
153    RejectedSnapshot,
154}
155
156///
157/// SqlCompileRejectPhase
158///
159/// Stable SQL compile rejection buckets. These counters identify the broad
160/// admission phase that rejected a SQL command without exposing SQL text,
161/// parser diagnostics, field names, or lowered query details.
162///
163
164#[derive(Clone, Copy, Debug, Eq, PartialEq)]
165#[remain::sorted]
166pub enum SqlCompileRejectPhase {
167    CacheKey,
168    Parse,
169    Semantic,
170}
171
172///
173/// SqlWriteKind
174///
175
176#[derive(Clone, Copy, Debug, Eq, PartialEq)]
177#[remain::sorted]
178pub enum SqlWriteKind {
179    Delete,
180    Insert,
181    InsertSelect,
182    Update,
183}
184
185///
186/// PlanKind
187///
188
189#[derive(Clone, Copy, Debug)]
190#[remain::sorted]
191pub enum PlanKind {
192    ByKey,
193    ByKeys,
194    FullScan,
195    IndexBranchSet,
196    IndexMultiLookup,
197    IndexPrefix,
198    IndexRange,
199    Intersection,
200    KeyRange,
201    Union,
202}
203
204///
205/// PlanChoiceReason
206///
207/// Stable selected-route reason buckets for non-index and primary-key access
208/// choices. These counters explain why a query did not land on a secondary
209/// index route without exposing predicates, literals, or index names.
210///
211
212#[derive(Clone, Copy, Debug, Eq, PartialEq)]
213#[remain::sorted]
214pub enum PlanChoiceReason {
215    ConflictingPrimaryKeyChildrenAccessPreferred,
216    ConstantFalsePredicate,
217    EmptyChildAccessPreferred,
218    FullScanAccess,
219    IntentKeyAccessOverride,
220    LimitZeroWindow,
221    NonIndexAccess,
222    PlannerCompositeNonIndex,
223    PlannerFullScanFallback,
224    PlannerKeySetAccess,
225    PlannerPrimaryKeyLookup,
226    PlannerPrimaryKeyRange,
227    RequiredOrderPrimaryKeyRangePreferred,
228    SingletonPrimaryKeyChildAccessPreferred,
229}
230
231///
232/// GroupedPlanExecutionMode
233///
234/// Canonical grouped-plan mode carried by metrics events.
235/// This keeps grouped metrics classification structured without routing
236/// through string codes that the sink would immediately decode again.
237///
238#[derive(Clone, Copy, Debug, Eq, PartialEq)]
239#[remain::sorted]
240pub enum GroupedPlanExecutionMode {
241    HashMaterialized,
242    OrderedStreaming,
243}
244
245///
246/// MetricsEvent
247///
248
249#[derive(Clone, Debug)]
250#[remain::sorted]
251pub enum MetricsEvent {
252    AcceptedSchemaFootprint {
253        entity_path: Rc<str>,
254        fields: u64,
255        nested_leaf_facts: u64,
256    },
257    Cache {
258        entity_path: Rc<str>,
259        kind: CacheKind,
260        outcome: CacheOutcome,
261    },
262    CacheEntries {
263        kind: CacheKind,
264        entries: u64,
265    },
266    CacheMissReason {
267        entity_path: Rc<str>,
268        kind: CacheKind,
269        reason: CacheMissReason,
270    },
271    ExecError {
272        kind: ExecKind,
273        entity_path: Rc<str>,
274        outcome: ExecOutcome,
275    },
276    ExecFinish {
277        kind: ExecKind,
278        entity_path: Rc<str>,
279        rows_touched: u64,
280        inst_delta: u64,
281        outcome: ExecOutcome,
282    },
283    ExecStart {
284        kind: ExecKind,
285        entity_path: Rc<str>,
286    },
287    IndexDelta {
288        entity_path: Rc<str>,
289        inserts: u64,
290        removes: u64,
291    },
292    LoadRowEfficiency {
293        entity_path: Rc<str>,
294        candidate_rows_scanned: u64,
295        candidate_rows_filtered: u64,
296        result_rows_emitted: u64,
297    },
298    MutationCommitPlan {
299        entity_path: Rc<str>,
300        class: MutationCommitClass,
301    },
302    NonAtomicPartialCommit {
303        entity_path: Rc<str>,
304        committed_rows: u64,
305    },
306    Plan {
307        entity_path: Rc<str>,
308        kind: PlanKind,
309        grouped_execution_mode: Option<GroupedPlanExecutionMode>,
310    },
311    PlanChoice {
312        entity_path: Rc<str>,
313        reason: PlanChoiceReason,
314    },
315    PreparedShapeAlreadyFinalized {
316        entity_path: Rc<str>,
317    },
318    RelationValidation {
319        entity_path: Rc<str>,
320        reverse_lookups: u64,
321        blocked_deletes: u64,
322    },
323    ReverseIndexDelta {
324        entity_path: Rc<str>,
325        inserts: u64,
326        removes: u64,
327    },
328    RowsAggregated {
329        entity_path: Rc<str>,
330        rows_aggregated: u64,
331    },
332    RowsEmitted {
333        entity_path: Rc<str>,
334        rows_emitted: u64,
335    },
336    RowsFiltered {
337        entity_path: Rc<str>,
338        rows_filtered: u64,
339    },
340    RowsScanned {
341        entity_path: Rc<str>,
342        rows_scanned: u64,
343    },
344    SaveMutation {
345        entity_path: Rc<str>,
346        kind: SaveMutationKind,
347        rows_touched: u64,
348    },
349    SchemaReconcile {
350        entity_path: Rc<str>,
351        outcome: SchemaReconcileOutcome,
352    },
353    SchemaStoreFootprint {
354        encoded_bytes: u64,
355        entity_path: Rc<str>,
356        latest_snapshot_bytes: u64,
357        snapshots: u64,
358    },
359    SchemaTransition {
360        entity_path: Rc<str>,
361        outcome: SchemaTransitionOutcome,
362    },
363    SqlCompileReject {
364        entity_path: Rc<str>,
365        phase: SqlCompileRejectPhase,
366    },
367    SqlWrite {
368        entity_path: Rc<str>,
369        kind: SqlWriteKind,
370        staged_rows: u64,
371        matched_rows: u64,
372        mutated_rows: u64,
373        returning_rows: u64,
374    },
375    SqlWriteError {
376        entity_path: Rc<str>,
377        kind: SqlWriteKind,
378        class: ErrorClass,
379    },
380    UniqueViolation {
381        entity_path: Rc<str>,
382    },
383}