mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-18 10:43:15 +00:00
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#![allow(non_upper_case_globals)] // FIXME
|
#![allow(non_upper_case_globals)] // FIXME
|
||||||
|
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
@@ -26,6 +27,30 @@ pub static GLOBAL_RUSTFS_ADDR: LazyLock<RwLock<String>> = LazyLock::new(|| RwLoc
|
|||||||
pub static GLOBAL_CONN_MAP: LazyLock<RwLock<HashMap<String, Channel>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
pub static GLOBAL_CONN_MAP: LazyLock<RwLock<HashMap<String, Channel>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||||
pub static GLOBAL_ROOT_CERT: LazyLock<RwLock<Option<Vec<u8>>>> = LazyLock::new(|| RwLock::new(None));
|
pub static GLOBAL_ROOT_CERT: LazyLock<RwLock<Option<Vec<u8>>>> = LazyLock::new(|| RwLock::new(None));
|
||||||
pub static GLOBAL_MTLS_IDENTITY: LazyLock<RwLock<Option<MtlsIdentityPem>>> = LazyLock::new(|| RwLock::new(None));
|
pub static GLOBAL_MTLS_IDENTITY: LazyLock<RwLock<Option<MtlsIdentityPem>>> = LazyLock::new(|| RwLock::new(None));
|
||||||
|
/// Global initialization time of the RustFS node.
|
||||||
|
pub static GLOBAL_INIT_TIME: LazyLock<RwLock<Option<DateTime<Utc>>>> = LazyLock::new(|| RwLock::new(None));
|
||||||
|
|
||||||
|
/// Set the global local node name.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `name` - A string slice representing the local node name.
|
||||||
|
pub async fn set_global_local_node_name(name: &str) {
|
||||||
|
*GLOBAL_LOCAL_NODE_NAME.write().await = name.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the global RustFS initialization time to the current UTC time.
|
||||||
|
pub async fn set_global_init_time_now() {
|
||||||
|
let now = Utc::now();
|
||||||
|
*GLOBAL_INIT_TIME.write().await = Some(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the global RustFS initialization time.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Option<DateTime<Utc>>` - The initialization time if set.
|
||||||
|
pub async fn get_global_init_time() -> Option<DateTime<Utc>> {
|
||||||
|
*GLOBAL_INIT_TIME.read().await
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the global RustFS address used for gRPC connections.
|
/// Set the global RustFS address used for gRPC connections.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use rustfs_madmin::metrics::ScannerMetrics as M_ScannerMetrics;
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::{
|
sync::{
|
||||||
Arc, OnceLock,
|
Arc, OnceLock,
|
||||||
@@ -115,7 +116,7 @@ pub enum Metric {
|
|||||||
|
|
||||||
impl Metric {
|
impl Metric {
|
||||||
/// Convert to string representation for metrics
|
/// Convert to string representation for metrics
|
||||||
pub fn as_str(self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::ReadMetadata => "read_metadata",
|
Self::ReadMetadata => "read_metadata",
|
||||||
Self::CheckMissing => "check_missing",
|
Self::CheckMissing => "check_missing",
|
||||||
@@ -460,6 +461,11 @@ impl Metrics {
|
|||||||
metrics.current_started = cycle.started;
|
metrics.current_started = cycle.started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace default start time with global init time if it's the placeholder
|
||||||
|
if let Some(init_time) = crate::get_global_init_time().await {
|
||||||
|
metrics.current_started = init_time;
|
||||||
|
}
|
||||||
|
|
||||||
metrics.collected_at = Utc::now();
|
metrics.collected_at = Utc::now();
|
||||||
metrics.active_paths = self.get_current_paths().await;
|
metrics.active_paths = self.get_current_paths().await;
|
||||||
|
|
||||||
@@ -489,8 +495,8 @@ impl Metrics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Type aliases for compatibility with existing code
|
// Type aliases for compatibility with existing code
|
||||||
pub type UpdateCurrentPathFn = Arc<dyn Fn(&str) -> Pin<Box<dyn std::future::Future<Output = ()> + Send>> + Send + Sync>;
|
pub type UpdateCurrentPathFn = Arc<dyn Fn(&str) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>;
|
||||||
pub type CloseDiskFn = Arc<dyn Fn() -> Pin<Box<dyn std::future::Future<Output = ()> + Send>> + Send + Sync>;
|
pub type CloseDiskFn = Arc<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>;
|
||||||
|
|
||||||
/// Create a current path updater for tracking scan progress
|
/// Create a current path updater for tracking scan progress
|
||||||
pub fn current_path_updater(disk: &str, initial: &str) -> (UpdateCurrentPathFn, CloseDiskFn) {
|
pub fn current_path_updater(disk: &str, initial: &str) -> (UpdateCurrentPathFn, CloseDiskFn) {
|
||||||
@@ -506,7 +512,7 @@ pub fn current_path_updater(disk: &str, initial: &str) -> (UpdateCurrentPathFn,
|
|||||||
|
|
||||||
let update_fn = {
|
let update_fn = {
|
||||||
let tracker = Arc::clone(&tracker);
|
let tracker = Arc::clone(&tracker);
|
||||||
Arc::new(move |path: &str| -> Pin<Box<dyn std::future::Future<Output = ()> + Send>> {
|
Arc::new(move |path: &str| -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||||
let tracker = Arc::clone(&tracker);
|
let tracker = Arc::clone(&tracker);
|
||||||
let path = path.to_string();
|
let path = path.to_string();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
@@ -517,7 +523,7 @@ pub fn current_path_updater(disk: &str, initial: &str) -> (UpdateCurrentPathFn,
|
|||||||
|
|
||||||
let done_fn = {
|
let done_fn = {
|
||||||
let disk_name = disk_name.clone();
|
let disk_name = disk_name.clone();
|
||||||
Arc::new(move || -> Pin<Box<dyn std::future::Future<Output = ()> + Send>> {
|
Arc::new(move || -> Pin<Box<dyn Future<Output = ()> + Send>> {
|
||||||
let disk_name = disk_name.clone();
|
let disk_name = disk_name.clone();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
global_metrics().current_paths.write().await.remove(&disk_name);
|
global_metrics().current_paths.write().await.remove(&disk_name);
|
||||||
|
|||||||
@@ -112,7 +112,10 @@ pub async fn collect_local_metrics(types: MetricType, opts: &CollectMetricsOpts)
|
|||||||
|
|
||||||
if types.contains(&MetricType::SCANNER) {
|
if types.contains(&MetricType::SCANNER) {
|
||||||
debug!("start get scanner metrics");
|
debug!("start get scanner metrics");
|
||||||
let metrics = global_metrics().report().await;
|
let mut metrics = global_metrics().report().await;
|
||||||
|
if let Some(init_time) = rustfs_common::get_global_init_time().await {
|
||||||
|
metrics.current_started = init_time;
|
||||||
|
}
|
||||||
real_time_metrics.aggregated.scanner = Some(metrics);
|
real_time_metrics.aggregated.scanner = Some(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -369,6 +369,9 @@ async fn run(opt: config::Opt) -> Result<()> {
|
|||||||
// 4. Mark as Full Ready now that critical components are warm
|
// 4. Mark as Full Ready now that critical components are warm
|
||||||
readiness.mark_stage(SystemStage::FullReady);
|
readiness.mark_stage(SystemStage::FullReady);
|
||||||
|
|
||||||
|
// Set the global RustFS initialization time to now
|
||||||
|
rustfs_common::set_global_init_time_now().await;
|
||||||
|
|
||||||
// Perform hibernation for 1 second
|
// Perform hibernation for 1 second
|
||||||
tokio::time::sleep(SHUTDOWN_TIMEOUT).await;
|
tokio::time::sleep(SHUTDOWN_TIMEOUT).await;
|
||||||
// listen to the shutdown signal
|
// listen to the shutdown signal
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ pub async fn start_http_server(
|
|||||||
TcpListener::from_std(socket.into())?
|
TcpListener::from_std(socket.into())?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let tls_acceptor = setup_tls_acceptor(opt.tls_path.as_deref().unwrap_or_default()).await?;
|
||||||
|
let tls_enabled = tls_acceptor.is_some();
|
||||||
|
let protocol = if tls_enabled { "https" } else { "http" };
|
||||||
// Obtain the listener address
|
// Obtain the listener address
|
||||||
let local_addr: SocketAddr = listener.local_addr()?;
|
let local_addr: SocketAddr = listener.local_addr()?;
|
||||||
let local_ip = match rustfs_utils::get_local_ip() {
|
let local_ip = match rustfs_utils::get_local_ip() {
|
||||||
@@ -186,11 +189,15 @@ pub async fn start_http_server(
|
|||||||
local_addr.ip()
|
local_addr.ip()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let tls_acceptor = setup_tls_acceptor(opt.tls_path.as_deref().unwrap_or_default()).await?;
|
|
||||||
let tls_enabled = tls_acceptor.is_some();
|
let local_ip_str = if local_ip.is_ipv6() {
|
||||||
let protocol = if tls_enabled { "https" } else { "http" };
|
format!("[{local_ip}]")
|
||||||
|
} else {
|
||||||
|
local_ip.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
// Detailed endpoint information (showing all API endpoints)
|
// Detailed endpoint information (showing all API endpoints)
|
||||||
let api_endpoints = format!("{protocol}://{local_ip}:{server_port}");
|
let api_endpoints = format!("{protocol}://{local_ip_str}:{server_port}");
|
||||||
let localhost_endpoint = format!("{protocol}://127.0.0.1:{server_port}");
|
let localhost_endpoint = format!("{protocol}://127.0.0.1:{server_port}");
|
||||||
let now_time = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
let now_time = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||||
if opt.console_enable {
|
if opt.console_enable {
|
||||||
@@ -198,7 +205,7 @@ pub async fn start_http_server(
|
|||||||
|
|
||||||
info!(
|
info!(
|
||||||
target: "rustfs::console::startup",
|
target: "rustfs::console::startup",
|
||||||
"Console WebUI available at: {protocol}://{local_ip}:{server_port}/rustfs/console/index.html"
|
"Console WebUI available at: {protocol}://{local_ip_str}:{server_port}/rustfs/console/index.html"
|
||||||
);
|
);
|
||||||
info!(
|
info!(
|
||||||
target: "rustfs::console::startup",
|
target: "rustfs::console::startup",
|
||||||
@@ -207,7 +214,7 @@ pub async fn start_http_server(
|
|||||||
);
|
);
|
||||||
|
|
||||||
println!("Console WebUI Start Time: {now_time}");
|
println!("Console WebUI Start Time: {now_time}");
|
||||||
println!("Console WebUI available at: {protocol}://{local_ip}:{server_port}/rustfs/console/index.html");
|
println!("Console WebUI available at: {protocol}://{local_ip_str}:{server_port}/rustfs/console/index.html");
|
||||||
println!("Console WebUI (localhost): {protocol}://127.0.0.1:{server_port}/rustfs/console/index.html",);
|
println!("Console WebUI (localhost): {protocol}://127.0.0.1:{server_port}/rustfs/console/index.html",);
|
||||||
} else {
|
} else {
|
||||||
info!(target: "rustfs::main::startup","RustFS API: {api_endpoints} {localhost_endpoint}");
|
info!(target: "rustfs::main::startup","RustFS API: {api_endpoints} {localhost_endpoint}");
|
||||||
|
|||||||
Reference in New Issue
Block a user