Skip to content

Commit

Permalink
feat(signer): add metrics (Commit-Boost#197)
Browse files Browse the repository at this point in the history
* Add endpoints metrics

* Add grafana dashboard

* Add more stats to dashboard

* Fix clippy

* Fix doc comments

* Make signer metrics function private

* Export signer dashboard for public use
  • Loading branch information
ManuelBilbao authored Dec 9, 2024
1 parent 5cc8000 commit f0b73ad
Show file tree
Hide file tree
Showing 10 changed files with 994 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ publish = false

[dependencies]
cb-common.workspace = true
cb-metrics.workspace = true

# ethereum
alloy.workspace = true
Expand All @@ -21,6 +22,7 @@ tokio.workspace = true

# telemetry
tracing.workspace = true
prometheus.workspace = true

# crypto
blst.workspace = true
Expand Down
3 changes: 3 additions & 0 deletions crates/signer/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub const GET_PUBKEYS_ENDPOINT_TAG: &str = "get_pubkeys";
pub const GENERATE_PROXY_KEY_ENDPOINT_TAG: &str = "generate_proxy_key";
pub const REQUEST_SIGNATURE_ENDPOINT_TAG: &str = "request_signature";
2 changes: 2 additions & 0 deletions crates/signer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod constants;
pub mod error;
pub mod manager;
mod metrics;
pub mod service;
34 changes: 34 additions & 0 deletions crates/signer/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! Metrics for Signer module
use axum::http::Uri;
use cb_common::commit::constants::{
GENERATE_PROXY_KEY_PATH, GET_PUBKEYS_PATH, REQUEST_SIGNATURE_PATH,
};
use lazy_static::lazy_static;
use prometheus::{register_int_counter_vec_with_registry, IntCounterVec, Registry};

use crate::constants::{
GENERATE_PROXY_KEY_ENDPOINT_TAG, GET_PUBKEYS_ENDPOINT_TAG, REQUEST_SIGNATURE_ENDPOINT_TAG,
};

lazy_static! {
pub static ref SIGNER_METRICS_REGISTRY: Registry =
Registry::new_custom(Some("cb_signer".to_string()), None).unwrap();

/// Status code returned by endpoint
pub static ref SIGNER_STATUS: IntCounterVec = register_int_counter_vec_with_registry!(
"signer_status_code_total",
"HTTP status code returned by signer",
&["http_status_code", "endpoint"],
SIGNER_METRICS_REGISTRY
).unwrap();
}

pub fn uri_to_tag(uri: &Uri) -> &str {
match uri.path() {
GET_PUBKEYS_PATH => GET_PUBKEYS_ENDPOINT_TAG,
GENERATE_PROXY_KEY_PATH => GENERATE_PROXY_KEY_ENDPOINT_TAG,
REQUEST_SIGNATURE_PATH => REQUEST_SIGNATURE_ENDPOINT_TAG,
_ => "unknown endpoint",
}
}
23 changes: 21 additions & 2 deletions crates/signer/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@ use cb_common::{
constants::COMMIT_BOOST_VERSION,
types::{Jwt, ModuleId},
};
use cb_metrics::provider::MetricsProvider;
use eyre::{Context, Result};
use headers::{authorization::Bearer, Authorization};
use tokio::{net::TcpListener, sync::RwLock};
use tracing::{debug, error, info, warn};
use uuid::Uuid;

use crate::{error::SignerModuleError, manager::SigningManager};
use crate::{
error::SignerModuleError,
manager::SigningManager,
metrics::{uri_to_tag, SIGNER_METRICS_REGISTRY, SIGNER_STATUS},
};

/// Implements the Signer API and provides a service for signing requests
pub struct SigningService;
Expand Down Expand Up @@ -72,13 +77,15 @@ impl SigningService {
info!(version = COMMIT_BOOST_VERSION, modules =? module_ids, port =? config.server_port, loaded_consensus, loaded_proxies, "Starting signing service");

let state = SigningState { manager: RwLock::new(manager).into(), jwts: config.jwts.into() };
SigningService::init_metrics()?;

let app = axum::Router::new()
.route(REQUEST_SIGNATURE_PATH, post(handle_request_signature))
.route(GET_PUBKEYS_PATH, get(handle_get_pubkeys))
.route(GENERATE_PROXY_KEY_PATH, post(handle_generate_proxy))
.with_state(state.clone())
.route_layer(middleware::from_fn_with_state(state.clone(), jwt_auth));
.route_layer(middleware::from_fn_with_state(state.clone(), jwt_auth))
.route_layer(middleware::from_fn(log_request));
let status_router = axum::Router::new().route(STATUS_PATH, get(handle_status));

let address = SocketAddr::from(([0, 0, 0, 0], config.server_port));
Expand All @@ -88,6 +95,10 @@ impl SigningService {
.await
.wrap_err("signer server exited")
}

fn init_metrics() -> Result<()> {
MetricsProvider::load_and_run(SIGNER_METRICS_REGISTRY.clone())
}
}

/// Authentication middleware layer
Expand All @@ -109,6 +120,14 @@ async fn jwt_auth(
Ok(next.run(req).await)
}

/// Requests logging middleware layer
async fn log_request(req: Request, next: Next) -> Result<Response, SignerModuleError> {
let url = &req.uri().clone();
let response = next.run(req).await;
SIGNER_STATUS.with_label_values(&[response.status().as_str(), uri_to_tag(url)]).inc();
Ok(response)
}

/// Status endpoint for the Signer API
async fn handle_status() -> Result<impl IntoResponse, SignerModuleError> {
Ok((StatusCode::OK, "OK"))
Expand Down
File renamed without changes.
Loading

0 comments on commit f0b73ad

Please sign in to comment.