|
1 mese fa | |
---|---|---|
.. | ||
src | 1 mese fa | |
Cargo.toml | 1 mese fa | |
README.md | 1 mese fa |
A small, focused crate that provides Prometheus metrics for CDK-based services. It bundles a ready-to-use metrics registry, a background HTTP server to expose metrics, helper functions for common CDK domains (HTTP, auth, Lightning, DB, mint operations), and an ergonomic macro for conditional metrics recording.
Add the crate to your Cargo.toml (replace the version as needed):
[dependencies] cdk-prometheus = { version = "0.1", features = ["system-metrics"] }
Note for downstream crates: the provided record_metrics! macro is gated at call-site by a feature named prometheus. If you use that macro, declare a prometheus feature in your application crate and enable it to compile the macro calls into real metrics (otherwise they no-op).
Start Prometheus and Grafana with docker-compose:
docker compose up -d prometheus grafana
Start your mintd
./mintd -w ~/.cdk-mintd
Check Prometheus and Grafana
curl localhost:9000/metrics
for checking CDK metricshttp://localhost:9090/targets?search=
checking the prometheus collector (you should see http://host.docker.internal:9000/metrics)http://localhost:3011/d/cdk-mint-dashboard/cdk-mint-dashboard
Grafana dashboard (default login: admin/admin)Expose a Prometheus endpoint with a default registry and CDK metrics:
use cdk_prometheus::start_default_server_with_metrics;
#[tokio::main] async fn main() -> anyhow::Result<()> { // Starts an HTTP server (default bind and path) and registers CDK metrics into its registry start_default_server_with_metrics().await?; Ok(()) }
Or start it in the background (e.g., from your application bootstrap):
use cdk_prometheus::start_background_server_with_metrics;
fn main() -> anyhow::Result<()> { let _handle = start_background_server_with_metrics()?; // Continue bootstrapping your application... Ok(()) }
You can record metrics using:
use cdk_prometheus::global;
fn handle_request() {
global::record_http_request("/health", "200"); global::record_http_request_duration(0.003, "/health");
global::record_auth_attempt();
global::record_auth_success();
// Lightning and DB
global::record_lightning_payment(1500.0, 2.0); // amount, fee (both in base units you track)
global::record_db_operation(0.015, "select_user");
global::set_db_connections_active(8);
// Mint operations
global::inc_in_flight_requests("get_payment_quote");
// ... do work ...
global::record_mint_operation("get_payment_quote", true);
global::record_mint_operation_histogram("get_payment_quote", true, 0.021);
global::dec_in_flight_requests("get_payment_quote");
// Errors
global::record_error();
}
use cdk_prometheus::METRICS;
fn do_db_work() { METRICS.record_db_operation(0.005, "update_user"); }
The macro lets you write grouped calls concisely and optionally pass an instance to use; if no instance is present, it automatically falls back to the global helpers. At call-site, wrap your invocations with a prometheus feature so they can be disabled in minimal builds.
use cdk_prometheus::record_metrics;
fn run_operation(metrics_opt: Option<cdk_prometheus::CdkMetrics>) { // Use instance if present, otherwise fallback to global record_metrics!(metrics_opt => { inc_in_flight_requests("make_payment"); record_mint_operation("make_payment", true); record_mint_operation_histogram("make_payment", true, 0.123); dec_in_flight_requests("make_payment"); });
// Or call directly on the global helpers
record_metrics!({
record_error();
});
}
If you just need sane defaults, use the convenience starters shown above. If you want finer control (bind address, path, system metrics), build the server explicitly:
use cdk_prometheus::{PrometheusBuilder, PrometheusServer, CdkMetrics, prometheus::Registry};
fn build_and_run() -> anyhow::Result<tokio::task::JoinHandle<anyhow::Result<()>>> { // Build a server wired up with the default CDK metrics let server = PrometheusBuilder::new().build_with_cdk_metrics()?; let handle = server.start_background(); Ok(handle) }
Notes:
The default CDK metrics instance (CdkMetrics) registers and maintains counters, histograms, and gauges for common areas:
You can use these immediately through the global helpers or the METRICS instance.
This crate re-exports the prometheus crate and exposes the underlying Registry so you can define and register your own metrics:
use cdk_prometheus::{prometheus, global};
fn register_custom_metric() -> Result<(), prometheus::Error> { let my_counter = prometheus::IntCounter::new("my_counter", "A custom counter")?; let registry = global::registry(); // Arcregistry.register(Box::new(my_counter.clone()))?;
my_counter.inc();
Ok(())
}
If you prefer instance-level control:
use std::sync::Arc; use cdk_prometheus::{create_cdk_metrics, prometheus};
fn with_instance() -> anyhow::Result<()> { let metrics = create_cdk_metrics()?; let registry: Arc[prometheus::Registry]() = metrics.registry();
let hist = prometheus::Histogram::with_opts(
prometheus::HistogramOpts::new("my_latency_seconds", "My op latency")
)?;
registry.register(Box::new(hist))?;
Ok(())
}
Example scrape_config:
scrape_configs:
- job_name: 'cdk'
scrape_interval: 15s
static_configs:
- targets: ['127.0.0.1:9090']
If you changed the bind address or path, make sure to update targets or the metrics_path in your Prometheus configuration accordingly.
Enable the system-metrics feature to export basic process/system metrics. The server updates these at a configurable interval.
cdk-prometheus = { version = "0.1", features = ["system-metrics"] }
Common error types surfaced by this crate include:
Handle these at startup and monitor logs during runtime.
MIT ```