Skip to main content

noxu_observe/
lib.rs

1// Copyright (C) 2024-2025 Greg Burd.  Licensed under either of the
2// Apache License, Version 2.0 or the MIT license, at your option.
3// See LICENSE-APACHE and LICENSE-MIT at the root of this repository.
4// SPDX-License-Identifier: Apache-2.0 OR MIT
5
6//! > **Internal component of the [`noxu`](https://crates.io/crates/noxu) database.**
7//! >
8//! > This crate is published only so the `noxu` umbrella crate can depend on it.
9//! > Use `noxu` (`noxu = "3"`) in applications; depend on this crate directly only
10//! > if you are extending the engine internals. Its API may change without a major
11//! > version bump.
12//!
13//! Optional observability integration for Noxu DB.
14//!
15//! Enable with `features = ["observability"]` on the `noxu-db` crate.
16//! Uses the [`metrics`] crate facade — install any compatible recorder
17//! (prometheus, statsd, etc.) in your application to collect metrics.
18//! Uses the [`tracing`] crate for structured spans and events.
19//!
20//! When the `observability` feature is disabled on `noxu-db`, all
21//! instrumentation compiles away to zero-cost no-ops.
22
23pub use metrics;
24pub use tracing;
25
26#[cfg(feature = "otel")]
27pub use opentelemetry;
28#[cfg(feature = "otel")]
29pub use tracing_opentelemetry;
30
31// ─── Metrics helpers ─────────────────────────────────────────────────────────
32
33/// Describe all Noxu DB metrics. Call once at application startup after
34/// installing a metrics recorder.
35pub fn describe_metrics() {
36    use metrics::{Unit, describe_counter, describe_gauge, describe_histogram};
37
38    describe_counter!(
39        "noxu_db_operations_total",
40        Unit::Count,
41        "Total database operations (labels: op={get,put,delete,commit,abort})"
42    );
43    describe_histogram!(
44        "noxu_db_operation_duration_seconds",
45        Unit::Seconds,
46        "Duration of database operations (labels: op=...)"
47    );
48    describe_counter!(
49        "noxu_db_cache_hit_total",
50        Unit::Count,
51        "Total cache hits"
52    );
53    describe_counter!(
54        "noxu_db_cache_miss_total",
55        Unit::Count,
56        "Total cache misses"
57    );
58    describe_histogram!(
59        "noxu_db_lock_wait_duration_seconds",
60        Unit::Seconds,
61        "Time spent waiting to acquire locks"
62    );
63    describe_counter!(
64        "noxu_db_lock_deadlocks_total",
65        Unit::Count,
66        "Total deadlocks detected"
67    );
68    describe_histogram!(
69        "noxu_db_fsync_duration_seconds",
70        Unit::Seconds,
71        "Duration of fsync operations"
72    );
73    describe_histogram!(
74        "noxu_db_fsync_batch_size",
75        Unit::Count,
76        "Number of log entries coalesced per fsync"
77    );
78    describe_counter!(
79        "noxu_db_log_bytes_written_total",
80        Unit::Bytes,
81        "Total bytes written to the write-ahead log"
82    );
83    describe_gauge!(
84        "noxu_db_active_transactions",
85        Unit::Count,
86        "Number of currently active transactions"
87    );
88    describe_counter!(
89        "noxu_db_cleaner_runs_total",
90        Unit::Count,
91        "Total cleaner daemon runs"
92    );
93    describe_counter!(
94        "noxu_db_evictor_evictions_total",
95        Unit::Count,
96        "Total pages evicted from the cache"
97    );
98}
99
100// ─── Macros for conditional instrumentation ──────────────────────────────────
101//
102// These are exported for use within noxu-db. When the `observability` feature
103// is disabled, the noxu-db crate uses stub macros that expand to nothing.
104
105/// Increment a counter metric.
106#[macro_export]
107macro_rules! counter_inc {
108    ($name:expr, $labels:expr) => {
109        ::metrics::counter!($name, $labels).increment(1);
110    };
111    ($name:expr, $labels:expr, $val:expr) => {
112        ::metrics::counter!($name, $labels).increment($val);
113    };
114}
115
116/// Record a histogram value.
117#[macro_export]
118macro_rules! histogram_record {
119    ($name:expr, $labels:expr, $val:expr) => {
120        ::metrics::histogram!($name, $labels).record($val);
121    };
122}
123
124/// Increment a gauge.
125#[macro_export]
126macro_rules! gauge_inc {
127    ($name:expr) => {
128        ::metrics::gauge!($name).increment(1.0);
129    };
130}
131
132/// Decrement a gauge.
133#[macro_export]
134macro_rules! gauge_dec {
135    ($name:expr) => {
136        ::metrics::gauge!($name).decrement(1.0);
137    };
138}