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