Add /status endpoints (#5857)
* Add /status endpoints * Bump package version * pub use instead of import
This commit is contained in:
Generated
+1
-1
@@ -6649,7 +6649,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-api"
|
||||
version = "3.0.0"
|
||||
version = "3.1.0"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-api"
|
||||
version = "3.0.0"
|
||||
version = "3.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
@@ -28,7 +28,7 @@ moka = { workspace = true, features = ["future"] }
|
||||
# Nym API: revert after Cheddar is out
|
||||
nym-contracts-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
nym-mixnet-contract-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
nym-bin-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
nym-bin-common = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar", features = ["openapi"]}
|
||||
nym-node-status-client = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
nym-crypto = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
nym-http-api-client = { git = "https://github.com/nymtech/nym.git", branch = "release/2025.11-cheddar" }
|
||||
|
||||
@@ -14,6 +14,7 @@ pub(crate) mod metrics;
|
||||
pub(crate) mod mixnodes;
|
||||
pub(crate) mod nym_nodes;
|
||||
pub(crate) mod services;
|
||||
pub(crate) mod status;
|
||||
pub(crate) mod summary;
|
||||
pub(crate) mod testruns;
|
||||
|
||||
@@ -39,7 +40,8 @@ impl RouterBuilder {
|
||||
.nest("/mixnodes", mixnodes::routes())
|
||||
.nest("/services", services::routes())
|
||||
.nest("/summary", summary::routes())
|
||||
.nest("/metrics", metrics::routes()),
|
||||
.nest("/metrics", metrics::routes())
|
||||
.nest("/status", status::routes()),
|
||||
)
|
||||
.nest(
|
||||
"/explorer/v3",
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
use axum::{extract::State, Json, Router};
|
||||
use nym_validator_client::models::BinaryBuildInformationOwned;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::http::{
|
||||
error::HttpResult,
|
||||
state::{AppState, HealthInfo},
|
||||
};
|
||||
|
||||
pub(crate) fn routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/build_information", axum::routing::get(build_information))
|
||||
.route("/health", axum::routing::get(health))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
tag = "Status",
|
||||
get,
|
||||
path = "/build_information",
|
||||
context_path = "/v2/status",
|
||||
responses(
|
||||
(status = 200, body = BinaryBuildInformationOwned)
|
||||
)
|
||||
)]
|
||||
#[instrument(level = tracing::Level::INFO, skip_all)]
|
||||
async fn build_information(
|
||||
State(state): State<AppState>,
|
||||
) -> HttpResult<Json<BinaryBuildInformationOwned>> {
|
||||
let build_info = state.build_information().to_owned();
|
||||
|
||||
Ok(Json(build_info))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
tag = "Status",
|
||||
get,
|
||||
path = "/health",
|
||||
context_path = "/v2/status",
|
||||
responses(
|
||||
(status = 200, body = HealthInfo)
|
||||
)
|
||||
)]
|
||||
#[instrument(level = tracing::Level::INFO, skip_all)]
|
||||
async fn health(State(state): State<AppState>) -> HttpResult<Json<HealthInfo>> {
|
||||
Ok(Json(state.health()))
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
use cosmwasm_std::Decimal;
|
||||
use itertools::Itertools;
|
||||
use moka::{future::Cache, Entry};
|
||||
use nym_bin_common::bin_info_owned;
|
||||
use nym_contracts_common::NaiveFloat;
|
||||
use nym_crypto::asymmetric::ed25519::PublicKey;
|
||||
use nym_mixnet_contract_common::NodeId;
|
||||
use nym_validator_client::nym_api::SkimmedNode;
|
||||
use semver::Version;
|
||||
use serde::Serialize;
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
use time::UtcDateTime;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{error, instrument, warn};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use super::models::SessionStats;
|
||||
use crate::{
|
||||
db::{queries, DbPool},
|
||||
http::models::{
|
||||
@@ -18,7 +23,7 @@ use crate::{
|
||||
monitor::{DelegationsCache, NodeGeoCache},
|
||||
};
|
||||
|
||||
use super::models::SessionStats;
|
||||
pub(crate) use nym_validator_client::models::BinaryBuildInformationOwned;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct AppState {
|
||||
@@ -28,6 +33,7 @@ pub(crate) struct AppState {
|
||||
agent_max_count: i64,
|
||||
node_geocache: NodeGeoCache,
|
||||
node_delegations: Arc<RwLock<DelegationsCache>>,
|
||||
bin_info: BinaryInfo,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -46,6 +52,7 @@ impl AppState {
|
||||
agent_max_count,
|
||||
node_geocache,
|
||||
node_delegations,
|
||||
bin_info: BinaryInfo::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +85,15 @@ impl AppState {
|
||||
.await
|
||||
.delegations_owned(node_id)
|
||||
}
|
||||
|
||||
pub(crate) fn health(&self) -> HealthInfo {
|
||||
let uptime = (UtcDateTime::now() - self.bin_info.startup_time).whole_seconds();
|
||||
HealthInfo { uptime }
|
||||
}
|
||||
|
||||
pub(crate) fn build_information(&self) -> &BinaryBuildInformationOwned {
|
||||
&self.bin_info.build_info
|
||||
}
|
||||
}
|
||||
|
||||
static GATEWAYS_LIST_KEY: &str = "gateways";
|
||||
@@ -631,3 +647,23 @@ async fn aggregate_node_info_from_db(
|
||||
|
||||
Ok(parsed_nym_nodes)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct BinaryInfo {
|
||||
startup_time: UtcDateTime,
|
||||
build_info: BinaryBuildInformationOwned,
|
||||
}
|
||||
|
||||
impl BinaryInfo {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
startup_time: UtcDateTime::now(),
|
||||
build_info: bin_info_owned!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub(crate) struct HealthInfo {
|
||||
uptime: i64,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user