mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-27 15:37:02 +00:00
Refactor: Add observability enable flag, improve comments, remove unused config params, and enhance run function error logging. (#689)
* improve code for dns log * fix * Improve comments, remove unused parameters in config.rs (opt), add observability enable flag, and enhance error logging in run function execution.
This commit is contained in:
@@ -126,12 +126,6 @@ pub const DEFAULT_LOG_FILENAME: &str = "rustfs";
|
|||||||
/// Default value: rustfs.log
|
/// Default value: rustfs.log
|
||||||
pub const DEFAULT_OBS_LOG_FILENAME: &str = concat!(DEFAULT_LOG_FILENAME, "");
|
pub const DEFAULT_OBS_LOG_FILENAME: &str = concat!(DEFAULT_LOG_FILENAME, "");
|
||||||
|
|
||||||
/// Default sink file log file for rustfs
|
|
||||||
/// This is the default sink file log file for rustfs.
|
|
||||||
/// It is used to store the logs of the application.
|
|
||||||
/// Default value: rustfs-sink.log
|
|
||||||
pub const DEFAULT_SINK_FILE_LOG_FILE: &str = concat!(DEFAULT_LOG_FILENAME, "-sink.log");
|
|
||||||
|
|
||||||
/// Default log directory for rustfs
|
/// Default log directory for rustfs
|
||||||
/// This is the default log directory for rustfs.
|
/// This is the default log directory for rustfs.
|
||||||
/// It is used to store the logs of the application.
|
/// It is used to store the logs of the application.
|
||||||
@@ -160,16 +154,6 @@ pub const DEFAULT_LOG_ROTATION_TIME: &str = "day";
|
|||||||
/// Environment variable: RUSTFS_OBS_LOG_KEEP_FILES
|
/// Environment variable: RUSTFS_OBS_LOG_KEEP_FILES
|
||||||
pub const DEFAULT_LOG_KEEP_FILES: u16 = 30;
|
pub const DEFAULT_LOG_KEEP_FILES: u16 = 30;
|
||||||
|
|
||||||
/// This is the external address for rustfs to access endpoint (used in Docker deployments).
|
|
||||||
/// This should match the mapped host port when using Docker port mapping.
|
|
||||||
/// Example: ":9020" when mapping host port 9020 to container port 9000.
|
|
||||||
/// Default value: DEFAULT_ADDRESS
|
|
||||||
/// Environment variable: RUSTFS_EXTERNAL_ADDRESS
|
|
||||||
/// Command line argument: --external-address
|
|
||||||
/// Example: RUSTFS_EXTERNAL_ADDRESS=":9020"
|
|
||||||
/// Example: --external-address ":9020"
|
|
||||||
pub const ENV_EXTERNAL_ADDRESS: &str = "RUSTFS_EXTERNAL_ADDRESS";
|
|
||||||
|
|
||||||
/// 1 KiB
|
/// 1 KiB
|
||||||
pub const KI_B: usize = 1024;
|
pub const KI_B: usize = 1024;
|
||||||
/// 1 MiB
|
/// 1 MiB
|
||||||
|
|||||||
+113
-23
@@ -38,7 +38,7 @@ pub const DISK_RESERVE_FRACTION: f64 = 0.15;
|
|||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref GLOBAL_RUSTFS_PORT: OnceLock<u16> = OnceLock::new();
|
static ref GLOBAL_RUSTFS_PORT: OnceLock<u16> = OnceLock::new();
|
||||||
static ref GLOBAL_RUSTFS_EXTERNAL_PORT: OnceLock<u16> = OnceLock::new();
|
static ref globalDeploymentIDPtr: OnceLock<Uuid> = OnceLock::new();
|
||||||
pub static ref GLOBAL_OBJECT_API: OnceLock<Arc<ECStore>> = OnceLock::new();
|
pub static ref GLOBAL_OBJECT_API: OnceLock<Arc<ECStore>> = OnceLock::new();
|
||||||
pub static ref GLOBAL_LOCAL_DISK: Arc<RwLock<Vec<Option<DiskStore>>>> = Arc::new(RwLock::new(Vec::new()));
|
pub static ref GLOBAL_LOCAL_DISK: Arc<RwLock<Vec<Option<DiskStore>>>> = Arc::new(RwLock::new(Vec::new()));
|
||||||
pub static ref GLOBAL_IsErasure: RwLock<bool> = RwLock::new(false);
|
pub static ref GLOBAL_IsErasure: RwLock<bool> = RwLock::new(false);
|
||||||
@@ -51,8 +51,6 @@ lazy_static! {
|
|||||||
pub static ref GLOBAL_TierConfigMgr: Arc<RwLock<TierConfigMgr>> = TierConfigMgr::new();
|
pub static ref GLOBAL_TierConfigMgr: Arc<RwLock<TierConfigMgr>> = TierConfigMgr::new();
|
||||||
pub static ref GLOBAL_LifecycleSys: Arc<LifecycleSys> = LifecycleSys::new();
|
pub static ref GLOBAL_LifecycleSys: Arc<LifecycleSys> = LifecycleSys::new();
|
||||||
pub static ref GLOBAL_EventNotifier: Arc<RwLock<EventNotifier>> = EventNotifier::new();
|
pub static ref GLOBAL_EventNotifier: Arc<RwLock<EventNotifier>> = EventNotifier::new();
|
||||||
//pub static ref GLOBAL_RemoteTargetTransport
|
|
||||||
static ref globalDeploymentIDPtr: OnceLock<Uuid> = OnceLock::new();
|
|
||||||
pub static ref GLOBAL_BOOT_TIME: OnceCell<SystemTime> = OnceCell::new();
|
pub static ref GLOBAL_BOOT_TIME: OnceCell<SystemTime> = OnceCell::new();
|
||||||
pub static ref GLOBAL_LocalNodeName: String = "127.0.0.1:9000".to_string();
|
pub static ref GLOBAL_LocalNodeName: String = "127.0.0.1:9000".to_string();
|
||||||
pub static ref GLOBAL_LocalNodeNameHex: String = rustfs_utils::crypto::hex(GLOBAL_LocalNodeName.as_bytes());
|
pub static ref GLOBAL_LocalNodeNameHex: String = rustfs_utils::crypto::hex(GLOBAL_LocalNodeName.as_bytes());
|
||||||
@@ -60,12 +58,22 @@ lazy_static! {
|
|||||||
pub static ref GLOBAL_REGION: OnceLock<String> = OnceLock::new();
|
pub static ref GLOBAL_REGION: OnceLock<String> = OnceLock::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global cancellation token for background services (data scanner and auto heal)
|
/// Global cancellation token for background services (data scanner and auto heal)
|
||||||
static GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN: OnceLock<CancellationToken> = OnceLock::new();
|
static GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN: OnceLock<CancellationToken> = OnceLock::new();
|
||||||
|
|
||||||
|
/// Global active credentials
|
||||||
static GLOBAL_ACTIVE_CRED: OnceLock<Credentials> = OnceLock::new();
|
static GLOBAL_ACTIVE_CRED: OnceLock<Credentials> = OnceLock::new();
|
||||||
|
|
||||||
pub fn init_global_action_cred(ak: Option<String>, sk: Option<String>) {
|
/// Initialize the global action credentials
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `ak` - Optional access key
|
||||||
|
/// * `sk` - Optional secret key
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
|
///
|
||||||
|
pub fn init_global_action_credentials(ak: Option<String>, sk: Option<String>) {
|
||||||
let ak = {
|
let ak = {
|
||||||
if let Some(k) = ak {
|
if let Some(k) = ak {
|
||||||
k
|
k
|
||||||
@@ -91,11 +99,16 @@ pub fn init_global_action_cred(ak: Option<String>, sk: Option<String>) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the global action credentials
|
||||||
pub fn get_global_action_cred() -> Option<Credentials> {
|
pub fn get_global_action_cred() -> Option<Credentials> {
|
||||||
GLOBAL_ACTIVE_CRED.get().cloned()
|
GLOBAL_ACTIVE_CRED.get().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the global rustfs port
|
/// Get the global rustfs port
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `u16` - The global rustfs port
|
||||||
|
///
|
||||||
pub fn global_rustfs_port() -> u16 {
|
pub fn global_rustfs_port() -> u16 {
|
||||||
if let Some(p) = GLOBAL_RUSTFS_PORT.get() {
|
if let Some(p) = GLOBAL_RUSTFS_PORT.get() {
|
||||||
*p
|
*p
|
||||||
@@ -105,36 +118,44 @@ pub fn global_rustfs_port() -> u16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the global rustfs port
|
/// Set the global rustfs port
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `value` - The port value to set globally
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
pub fn set_global_rustfs_port(value: u16) {
|
pub fn set_global_rustfs_port(value: u16) {
|
||||||
GLOBAL_RUSTFS_PORT.set(value).expect("set_global_rustfs_port fail");
|
GLOBAL_RUSTFS_PORT.set(value).expect("set_global_rustfs_port fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the global rustfs external port
|
/// Set the global deployment id
|
||||||
pub fn global_rustfs_external_port() -> u16 {
|
///
|
||||||
if let Some(p) = GLOBAL_RUSTFS_EXTERNAL_PORT.get() {
|
/// # Arguments
|
||||||
*p
|
/// * `id` - The Uuid to set as the global deployment id
|
||||||
} else {
|
///
|
||||||
rustfs_config::DEFAULT_PORT
|
/// # Returns
|
||||||
}
|
/// * None
|
||||||
}
|
///
|
||||||
|
|
||||||
/// Set the global rustfs external port
|
|
||||||
pub fn set_global_rustfs_external_port(value: u16) {
|
|
||||||
GLOBAL_RUSTFS_EXTERNAL_PORT
|
|
||||||
.set(value)
|
|
||||||
.expect("set_global_rustfs_external_port fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the global rustfs port
|
|
||||||
pub fn set_global_deployment_id(id: Uuid) {
|
pub fn set_global_deployment_id(id: Uuid) {
|
||||||
globalDeploymentIDPtr.set(id).unwrap();
|
globalDeploymentIDPtr.set(id).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the global deployment id
|
/// Get the global deployment id
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Option<String>` - The global deployment id as a string, if set
|
||||||
|
///
|
||||||
pub fn get_global_deployment_id() -> Option<String> {
|
pub fn get_global_deployment_id() -> Option<String> {
|
||||||
globalDeploymentIDPtr.get().map(|v| v.to_string())
|
globalDeploymentIDPtr.get().map(|v| v.to_string())
|
||||||
}
|
}
|
||||||
/// Get the global deployment id
|
/// Set the global endpoints
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `eps` - A vector of PoolEndpoints to set globally
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
|
///
|
||||||
pub fn set_global_endpoints(eps: Vec<PoolEndpoints>) {
|
pub fn set_global_endpoints(eps: Vec<PoolEndpoints>) {
|
||||||
GLOBAL_Endpoints
|
GLOBAL_Endpoints
|
||||||
.set(EndpointServerPools::from(eps))
|
.set(EndpointServerPools::from(eps))
|
||||||
@@ -142,6 +163,10 @@ pub fn set_global_endpoints(eps: Vec<PoolEndpoints>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the global endpoints
|
/// Get the global endpoints
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `EndpointServerPools` - The global endpoints
|
||||||
|
///
|
||||||
pub fn get_global_endpoints() -> EndpointServerPools {
|
pub fn get_global_endpoints() -> EndpointServerPools {
|
||||||
if let Some(eps) = GLOBAL_Endpoints.get() {
|
if let Some(eps) = GLOBAL_Endpoints.get() {
|
||||||
eps.clone()
|
eps.clone()
|
||||||
@@ -150,29 +175,63 @@ pub fn get_global_endpoints() -> EndpointServerPools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new object layer instance
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Option<Arc<ECStore>>` - The global object layer instance, if set
|
||||||
|
///
|
||||||
pub fn new_object_layer_fn() -> Option<Arc<ECStore>> {
|
pub fn new_object_layer_fn() -> Option<Arc<ECStore>> {
|
||||||
GLOBAL_OBJECT_API.get().cloned()
|
GLOBAL_OBJECT_API.get().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the global object layer
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `o` - The ECStore instance to set globally
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
pub async fn set_object_layer(o: Arc<ECStore>) {
|
pub async fn set_object_layer(o: Arc<ECStore>) {
|
||||||
GLOBAL_OBJECT_API.set(o).expect("set_object_layer fail ")
|
GLOBAL_OBJECT_API.set(o).expect("set_object_layer fail ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the setup type is distributed erasure coding
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `bool` - True if the setup type is distributed erasure coding, false otherwise
|
||||||
|
///
|
||||||
pub async fn is_dist_erasure() -> bool {
|
pub async fn is_dist_erasure() -> bool {
|
||||||
let lock = GLOBAL_IsDistErasure.read().await;
|
let lock = GLOBAL_IsDistErasure.read().await;
|
||||||
*lock
|
*lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the setup type is erasure coding with single data center
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `bool` - True if the setup type is erasure coding with single data center, false otherwise
|
||||||
|
///
|
||||||
pub async fn is_erasure_sd() -> bool {
|
pub async fn is_erasure_sd() -> bool {
|
||||||
let lock = GLOBAL_IsErasureSD.read().await;
|
let lock = GLOBAL_IsErasureSD.read().await;
|
||||||
*lock
|
*lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the setup type is erasure coding
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `bool` - True if the setup type is erasure coding, false otherwise
|
||||||
|
///
|
||||||
pub async fn is_erasure() -> bool {
|
pub async fn is_erasure() -> bool {
|
||||||
let lock = GLOBAL_IsErasure.read().await;
|
let lock = GLOBAL_IsErasure.read().await;
|
||||||
*lock
|
*lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update the global erasure type based on the setup type
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `setup_type` - The SetupType to update the global erasure type
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
pub async fn update_erasure_type(setup_type: SetupType) {
|
pub async fn update_erasure_type(setup_type: SetupType) {
|
||||||
let mut is_erasure = GLOBAL_IsErasure.write().await;
|
let mut is_erasure = GLOBAL_IsErasure.write().await;
|
||||||
*is_erasure = setup_type == SetupType::Erasure;
|
*is_erasure = setup_type == SetupType::Erasure;
|
||||||
@@ -198,25 +257,53 @@ pub async fn update_erasure_type(setup_type: SetupType) {
|
|||||||
|
|
||||||
type TypeLocalDiskSetDrives = Vec<Vec<Vec<Option<DiskStore>>>>;
|
type TypeLocalDiskSetDrives = Vec<Vec<Vec<Option<DiskStore>>>>;
|
||||||
|
|
||||||
|
/// Set the global region
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `region` - The region string to set globally
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
pub fn set_global_region(region: String) {
|
pub fn set_global_region(region: String) {
|
||||||
GLOBAL_REGION.set(region).unwrap();
|
GLOBAL_REGION.set(region).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the global region
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Option<String>` - The global region string, if set
|
||||||
|
///
|
||||||
pub fn get_global_region() -> Option<String> {
|
pub fn get_global_region() -> Option<String> {
|
||||||
GLOBAL_REGION.get().cloned()
|
GLOBAL_REGION.get().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the global background services cancellation token
|
/// Initialize the global background services cancellation token
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `cancel_token` - The CancellationToken instance to set globally
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Ok(())` if successful
|
||||||
|
/// * `Err(CancellationToken)` if setting fails
|
||||||
|
///
|
||||||
pub fn init_background_services_cancel_token(cancel_token: CancellationToken) -> Result<(), CancellationToken> {
|
pub fn init_background_services_cancel_token(cancel_token: CancellationToken) -> Result<(), CancellationToken> {
|
||||||
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.set(cancel_token)
|
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.set(cancel_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the global background services cancellation token
|
/// Get the global background services cancellation token
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `Option<&'static CancellationToken>` - The global cancellation token, if set
|
||||||
|
///
|
||||||
pub fn get_background_services_cancel_token() -> Option<&'static CancellationToken> {
|
pub fn get_background_services_cancel_token() -> Option<&'static CancellationToken> {
|
||||||
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get()
|
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create and initialize the global background services cancellation token
|
/// Create and initialize the global background services cancellation token
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * `CancellationToken` - The newly created global cancellation token
|
||||||
|
///
|
||||||
pub fn create_background_services_cancel_token() -> CancellationToken {
|
pub fn create_background_services_cancel_token() -> CancellationToken {
|
||||||
let cancel_token = CancellationToken::new();
|
let cancel_token = CancellationToken::new();
|
||||||
init_background_services_cancel_token(cancel_token.clone()).expect("Background services cancel token already initialized");
|
init_background_services_cancel_token(cancel_token.clone()).expect("Background services cancel token already initialized");
|
||||||
@@ -224,6 +311,9 @@ pub fn create_background_services_cancel_token() -> CancellationToken {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Shutdown all background services gracefully
|
/// Shutdown all background services gracefully
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// * None
|
||||||
pub fn shutdown_background_services() {
|
pub fn shutdown_background_services() {
|
||||||
if let Some(cancel_token) = GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get() {
|
if let Some(cancel_token) = GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get() {
|
||||||
cancel_token.cancel();
|
cancel_token.cancel();
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
use crate::AppConfig;
|
use crate::AppConfig;
|
||||||
use crate::telemetry::{OtelGuard, init_telemetry};
|
use crate::telemetry::{OtelGuard, init_telemetry};
|
||||||
|
use opentelemetry::metrics::Meter;
|
||||||
|
use rustfs_config::APP_NAME;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use tokio::sync::{OnceCell, SetError};
|
use tokio::sync::{OnceCell, SetError};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
@@ -21,6 +23,23 @@ use tracing::{error, info};
|
|||||||
/// Global guard for OpenTelemetry tracing
|
/// Global guard for OpenTelemetry tracing
|
||||||
static GLOBAL_GUARD: OnceCell<Arc<Mutex<OtelGuard>>> = OnceCell::const_new();
|
static GLOBAL_GUARD: OnceCell<Arc<Mutex<OtelGuard>>> = OnceCell::const_new();
|
||||||
|
|
||||||
|
/// Flag indicating if observability is enabled
|
||||||
|
pub(crate) static IS_OBSERVABILITY_ENABLED: OnceCell<bool> = OnceCell::const_new();
|
||||||
|
|
||||||
|
/// Name of the observability meter
|
||||||
|
pub(crate) static OBSERVABILITY_METER_NAME: OnceCell<String> = OnceCell::const_new();
|
||||||
|
|
||||||
|
/// Check whether Observability is enabled
|
||||||
|
pub fn is_observability_enabled() -> bool {
|
||||||
|
IS_OBSERVABILITY_ENABLED.get().copied().unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the global meter for observability
|
||||||
|
pub fn global_meter() -> Meter {
|
||||||
|
let meter_name = OBSERVABILITY_METER_NAME.get().map(|s| s.as_str()).unwrap_or(APP_NAME);
|
||||||
|
opentelemetry::global::meter(meter_name)
|
||||||
|
}
|
||||||
|
|
||||||
/// Error type for global guard operations
|
/// Error type for global guard operations
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum GlobalError {
|
pub enum GlobalError {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use crate::config::OtelConfig;
|
use crate::config::OtelConfig;
|
||||||
|
use crate::global::{IS_OBSERVABILITY_ENABLED, OBSERVABILITY_METER_NAME};
|
||||||
use flexi_logger::{
|
use flexi_logger::{
|
||||||
Age, Cleanup, Criterion, DeferredNow, FileSpec, LogSpecification, Naming, Record, WriteMode,
|
Age, Cleanup, Criterion, DeferredNow, FileSpec, LogSpecification, Naming, Record, WriteMode,
|
||||||
WriteMode::{AsyncWith, BufferAndFlush},
|
WriteMode::{AsyncWith, BufferAndFlush},
|
||||||
@@ -302,6 +303,8 @@ pub(crate) fn init_telemetry(config: &OtelConfig) -> OtelGuard {
|
|||||||
logger_level,
|
logger_level,
|
||||||
env::var("RUST_LOG").unwrap_or_else(|_| "Not set".to_string())
|
env::var("RUST_LOG").unwrap_or_else(|_| "Not set".to_string())
|
||||||
);
|
);
|
||||||
|
IS_OBSERVABILITY_ENABLED.set(true).ok();
|
||||||
|
OBSERVABILITY_METER_NAME.set(service_name.to_string()).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -148,17 +148,17 @@ pub fn is_local_host(host: Host<&str>, port: u16, local_port: u16) -> std::io::R
|
|||||||
pub async fn get_host_ip(host: Host<&str>) -> std::io::Result<HashSet<IpAddr>> {
|
pub async fn get_host_ip(host: Host<&str>) -> std::io::Result<HashSet<IpAddr>> {
|
||||||
match host {
|
match host {
|
||||||
Host::Domain(domain) => {
|
Host::Domain(domain) => {
|
||||||
// match crate::dns_resolver::resolve_domain(domain).await {
|
match crate::dns_resolver::resolve_domain(domain).await {
|
||||||
// Ok(ips) => {
|
Ok(ips) => {
|
||||||
// info!("Resolved domain {domain} using custom DNS resolver: {ips:?}");
|
info!("Resolved domain {domain} using custom DNS resolver: {ips:?}");
|
||||||
// return Ok(ips.into_iter().collect());
|
return Ok(ips.into_iter().collect());
|
||||||
// }
|
}
|
||||||
// Err(err) => {
|
Err(err) => {
|
||||||
// error!(
|
error!(
|
||||||
// "Failed to resolve domain {domain} using custom DNS resolver, falling back to system resolver,err: {err}"
|
"Failed to resolve domain {domain} using custom DNS resolver, falling back to system resolver,err: {err}"
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// Check cache first
|
// Check cache first
|
||||||
if CUSTOM_DNS_RESOLVER.read().unwrap().is_none() {
|
if CUSTOM_DNS_RESOLVER.read().unwrap().is_none() {
|
||||||
if let Ok(mut cache) = DNS_CACHE.lock() {
|
if let Ok(mut cache) = DNS_CACHE.lock() {
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ use tower_http::timeout::TimeoutLayer;
|
|||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
use tracing::{debug, error, info, instrument, warn};
|
use tracing::{debug, error, info, instrument, warn};
|
||||||
|
|
||||||
// shadow!(build);
|
|
||||||
pub(crate) const CONSOLE_PREFIX: &str = "/rustfs/console";
|
pub(crate) const CONSOLE_PREFIX: &str = "/rustfs/console";
|
||||||
const RUSTFS_ADMIN_PREFIX: &str = "/rustfs/admin/v3";
|
const RUSTFS_ADMIN_PREFIX: &str = "/rustfs/admin/v3";
|
||||||
|
|
||||||
@@ -49,6 +48,17 @@ const RUSTFS_ADMIN_PREFIX: &str = "/rustfs/admin/v3";
|
|||||||
struct StaticFiles;
|
struct StaticFiles;
|
||||||
|
|
||||||
/// Static file handler
|
/// Static file handler
|
||||||
|
///
|
||||||
|
/// Serves static files embedded in the binary using rust-embed.
|
||||||
|
/// If the requested file is not found, it serves index.html as a fallback.
|
||||||
|
/// If index.html is also not found, it returns a 404 Not Found response.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// - `uri`: The request URI.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// - An `impl IntoResponse` containing the static file content or a 404 response.
|
||||||
|
///
|
||||||
pub(crate) async fn static_handler(uri: Uri) -> impl IntoResponse {
|
pub(crate) async fn static_handler(uri: Uri) -> impl IntoResponse {
|
||||||
let mut path = uri.path().trim_start_matches('/');
|
let mut path = uri.path().trim_start_matches('/');
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
@@ -71,7 +81,7 @@ pub(crate) async fn static_handler(uri: Uri) -> impl IntoResponse {
|
|||||||
} else {
|
} else {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::NOT_FOUND)
|
.status(StatusCode::NOT_FOUND)
|
||||||
.body(Body::from("404 Not Found"))
|
.body(Body::from(" 404 Not Found \n RustFS "))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,8 +224,6 @@ fn _is_private_ip(ip: IpAddr) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::const_is_empty)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[instrument(fields(host))]
|
#[instrument(fields(host))]
|
||||||
pub async fn config_handler(uri: Uri, Host(host): Host, headers: HeaderMap) -> impl IntoResponse {
|
pub async fn config_handler(uri: Uri, Host(host): Host, headers: HeaderMap) -> impl IntoResponse {
|
||||||
// Get the scheme from the headers or use the URI scheme
|
// Get the scheme from the headers or use the URI scheme
|
||||||
@@ -390,8 +398,8 @@ fn setup_console_middleware_stack(
|
|||||||
auth_timeout: u64,
|
auth_timeout: u64,
|
||||||
) -> Router {
|
) -> Router {
|
||||||
let mut app = Router::new()
|
let mut app = Router::new()
|
||||||
.route(&format!("{CONSOLE_PREFIX}/license"), get(crate::admin::console::license_handler))
|
.route(&format!("{CONSOLE_PREFIX}/license"), get(license_handler))
|
||||||
.route(&format!("{CONSOLE_PREFIX}/config.json"), get(crate::admin::console::config_handler))
|
.route(&format!("{CONSOLE_PREFIX}/config.json"), get(config_handler))
|
||||||
.route(&format!("{CONSOLE_PREFIX}/health"), get(health_check))
|
.route(&format!("{CONSOLE_PREFIX}/health"), get(health_check))
|
||||||
.nest(CONSOLE_PREFIX, Router::new().fallback_service(get(static_handler)))
|
.nest(CONSOLE_PREFIX, Router::new().fallback_service(get(static_handler)))
|
||||||
.fallback_service(get(static_handler));
|
.fallback_service(get(static_handler));
|
||||||
@@ -405,7 +413,7 @@ fn setup_console_middleware_stack(
|
|||||||
// Add timeout layer - convert auth_timeout from seconds to Duration
|
// Add timeout layer - convert auth_timeout from seconds to Duration
|
||||||
.layer(TimeoutLayer::new(Duration::from_secs(auth_timeout)))
|
.layer(TimeoutLayer::new(Duration::from_secs(auth_timeout)))
|
||||||
// Add request body limit (10MB for console uploads)
|
// Add request body limit (10MB for console uploads)
|
||||||
.layer(RequestBodyLimitLayer::new(10 * 1024 * 1024));
|
.layer(RequestBodyLimitLayer::new(5 * 1024 * 1024 * 1024));
|
||||||
|
|
||||||
// Add rate limiting if enabled
|
// Add rate limiting if enabled
|
||||||
if rate_limit_enable {
|
if rate_limit_enable {
|
||||||
|
|||||||
@@ -41,23 +41,6 @@ mod tests {
|
|||||||
// Should create a layer without error (uses default)
|
// Should create a layer without error (uses default)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_external_address_configuration() {
|
|
||||||
// Test external address configuration
|
|
||||||
let args = vec![
|
|
||||||
"rustfs",
|
|
||||||
"/tmp/test",
|
|
||||||
"--console-address",
|
|
||||||
":9001",
|
|
||||||
"--external-address",
|
|
||||||
":9020",
|
|
||||||
];
|
|
||||||
let opt = Opt::parse_from(args);
|
|
||||||
|
|
||||||
assert_eq!(opt.console_address, ":9001");
|
|
||||||
assert_eq!(opt.external_address, ":9020".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_console_tls_configuration() {
|
async fn test_console_tls_configuration() {
|
||||||
// Test TLS configuration options (now uses shared tls_path)
|
// Test TLS configuration options (now uses shared tls_path)
|
||||||
@@ -103,14 +86,11 @@ mod tests {
|
|||||||
"true",
|
"true",
|
||||||
"--console-address",
|
"--console-address",
|
||||||
":9001",
|
":9001",
|
||||||
"--external-address",
|
|
||||||
":9020",
|
|
||||||
];
|
];
|
||||||
let opt = Opt::parse_from(args);
|
let opt = Opt::parse_from(args);
|
||||||
|
|
||||||
// Verify all console-related configuration is parsed correctly
|
// Verify all console-related configuration is parsed correctly
|
||||||
assert!(opt.console_enable);
|
assert!(opt.console_enable);
|
||||||
assert_eq!(opt.console_address, ":9001");
|
assert_eq!(opt.console_address, ":9001");
|
||||||
assert_eq!(opt.external_address, ":9020".to_string());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ mod tests {
|
|||||||
|
|
||||||
assert!(opt.console_enable);
|
assert!(opt.console_enable);
|
||||||
assert_eq!(opt.console_address, ":9001");
|
assert_eq!(opt.console_address, ":9001");
|
||||||
assert_eq!(opt.external_address, ":9000"); // Now defaults to DEFAULT_ADDRESS
|
|
||||||
assert_eq!(opt.address, ":9000");
|
assert_eq!(opt.address, ":9000");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,15 +48,6 @@ mod tests {
|
|||||||
assert_eq!(opt.address, ":8000");
|
assert_eq!(opt.address, ":8000");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_external_address_configuration() {
|
|
||||||
// Test external address configuration for Docker
|
|
||||||
let args = vec!["rustfs", "/test/volume", "--external-address", ":9020"];
|
|
||||||
let opt = Opt::parse_from(args);
|
|
||||||
|
|
||||||
assert_eq!(opt.external_address, ":9020".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_console_and_endpoint_ports_different() {
|
fn test_console_and_endpoint_ports_different() {
|
||||||
// Ensure console and endpoint use different default ports
|
// Ensure console and endpoint use different default ports
|
||||||
|
|||||||
@@ -75,12 +75,6 @@ pub struct Opt {
|
|||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_CONSOLE_ADDRESS.to_string(), env = "RUSTFS_CONSOLE_ADDRESS")]
|
#[arg(long, default_value_t = rustfs_config::DEFAULT_CONSOLE_ADDRESS.to_string(), env = "RUSTFS_CONSOLE_ADDRESS")]
|
||||||
pub console_address: String,
|
pub console_address: String,
|
||||||
|
|
||||||
/// External address for console to access endpoint (used in Docker deployments)
|
|
||||||
/// This should match the mapped host port when using Docker port mapping
|
|
||||||
/// Example: ":9020" when mapping host port 9020 to container port 9000
|
|
||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_ADDRESS.to_string(), env = "RUSTFS_EXTERNAL_ADDRESS")]
|
|
||||||
pub external_address: String,
|
|
||||||
|
|
||||||
/// Observability endpoint for trace, metrics and logs,only support grpc mode.
|
/// Observability endpoint for trace, metrics and logs,only support grpc mode.
|
||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_OBS_ENDPOINT.to_string(), env = "RUSTFS_OBS_ENDPOINT")]
|
#[arg(long, default_value_t = rustfs_config::DEFAULT_OBS_ENDPOINT.to_string(), env = "RUSTFS_OBS_ENDPOINT")]
|
||||||
pub obs_endpoint: String,
|
pub obs_endpoint: String,
|
||||||
@@ -89,18 +83,6 @@ pub struct Opt {
|
|||||||
#[arg(long, env = "RUSTFS_TLS_PATH")]
|
#[arg(long, env = "RUSTFS_TLS_PATH")]
|
||||||
pub tls_path: Option<String>,
|
pub tls_path: Option<String>,
|
||||||
|
|
||||||
/// Enable rate limiting for console
|
|
||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_CONSOLE_RATE_LIMIT_ENABLE, env = "RUSTFS_CONSOLE_RATE_LIMIT_ENABLE")]
|
|
||||||
pub console_rate_limit_enable: bool,
|
|
||||||
|
|
||||||
/// Console rate limit: requests per minute
|
|
||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_CONSOLE_RATE_LIMIT_RPM, env = "RUSTFS_CONSOLE_RATE_LIMIT_RPM")]
|
|
||||||
pub console_rate_limit_rpm: u32,
|
|
||||||
|
|
||||||
/// Console authentication timeout in seconds
|
|
||||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_CONSOLE_AUTH_TIMEOUT, env = "RUSTFS_CONSOLE_AUTH_TIMEOUT")]
|
|
||||||
pub console_auth_timeout: u64,
|
|
||||||
|
|
||||||
#[arg(long, env = "RUSTFS_LICENSE")]
|
#[arg(long, env = "RUSTFS_LICENSE")]
|
||||||
pub license: Option<String>,
|
pub license: Option<String>,
|
||||||
|
|
||||||
|
|||||||
+23
-11
@@ -132,26 +132,38 @@ async fn async_main() -> Result<()> {
|
|||||||
info!("{}", LOGO);
|
info!("{}", LOGO);
|
||||||
|
|
||||||
// Store in global storage
|
// Store in global storage
|
||||||
set_global_guard(guard).map_err(Error::other)?;
|
match set_global_guard(guard).map_err(Error::other) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to set global observability guard: {}", e);
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize performance profiling if enabled
|
// Initialize performance profiling if enabled
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
profiling::start_profiling_if_enabled();
|
profiling::start_profiling_if_enabled();
|
||||||
|
|
||||||
// Run parameters
|
// Run parameters
|
||||||
run(opt).await
|
match run(opt).await {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Server encountered an error and is shutting down: {}", e);
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(opt))]
|
#[instrument(skip(opt))]
|
||||||
async fn run(opt: config::Opt) -> Result<()> {
|
async fn run(opt: config::Opt) -> Result<()> {
|
||||||
debug!("opt: {:?}", &opt);
|
debug!("opt: {:?}", &opt);
|
||||||
|
|
||||||
// // Initialize global DNS resolver early for enhanced DNS resolution (concurrent)
|
// Initialize global DNS resolver early for enhanced DNS resolution (concurrent)
|
||||||
// let dns_init = tokio::spawn(async {
|
let dns_init = tokio::spawn(async {
|
||||||
// if let Err(e) = rustfs_utils::dns_resolver::init_global_dns_resolver().await {
|
if let Err(e) = rustfs_utils::dns_resolver::init_global_dns_resolver().await {
|
||||||
// warn!("Failed to initialize global DNS resolver: {}. Using standard DNS resolution.", e);
|
warn!("Failed to initialize global DNS resolver: {}. Using standard DNS resolution.", e);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
if let Some(region) = &opt.region {
|
if let Some(region) = &opt.region {
|
||||||
rustfs_ecstore::global::set_global_region(region.clone());
|
rustfs_ecstore::global::set_global_region(region.clone());
|
||||||
@@ -172,14 +184,14 @@ async fn run(opt: config::Opt) -> Result<()> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Set up AK and SK
|
// Set up AK and SK
|
||||||
rustfs_ecstore::global::init_global_action_cred(Some(opt.access_key.clone()), Some(opt.secret_key.clone()));
|
rustfs_ecstore::global::init_global_action_credentials(Some(opt.access_key.clone()), Some(opt.secret_key.clone()));
|
||||||
|
|
||||||
set_global_rustfs_port(server_port);
|
set_global_rustfs_port(server_port);
|
||||||
|
|
||||||
set_global_addr(&opt.address).await;
|
set_global_addr(&opt.address).await;
|
||||||
|
|
||||||
// // Wait for DNS initialization to complete before network-heavy operations
|
// Wait for DNS initialization to complete before network-heavy operations
|
||||||
// dns_init.await.map_err(Error::other)?;
|
dns_init.await.map_err(Error::other)?;
|
||||||
|
|
||||||
// For RPC
|
// For RPC
|
||||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
||||||
|
|||||||
@@ -151,18 +151,16 @@ pub async fn start_http_server(
|
|||||||
local_addr.ip()
|
local_addr.ip()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Detailed endpoint information (showing all API endpoints)
|
|
||||||
let api_endpoints = format!("http://{local_ip}:{server_port}");
|
|
||||||
let localhost_endpoint = format!("http://127.0.0.1:{server_port}");
|
|
||||||
|
|
||||||
let tls_acceptor = setup_tls_acceptor(opt.tls_path.as_deref().unwrap_or_default()).await?;
|
let tls_acceptor = setup_tls_acceptor(opt.tls_path.as_deref().unwrap_or_default()).await?;
|
||||||
let tls_enabled = tls_acceptor.is_some();
|
let tls_enabled = tls_acceptor.is_some();
|
||||||
|
let protocol = if tls_enabled { "https" } else { "http" };
|
||||||
|
// Detailed endpoint information (showing all API endpoints)
|
||||||
|
let api_endpoints = format!("{protocol}://{local_ip}:{server_port}");
|
||||||
|
let localhost_endpoint = format!("{protocol}://127.0.0.1:{server_port}");
|
||||||
|
|
||||||
if opt.console_enable {
|
if opt.console_enable {
|
||||||
admin::console::init_console_cfg(local_ip, server_port);
|
admin::console::init_console_cfg(local_ip, server_port);
|
||||||
|
|
||||||
let protocol = if tls_enabled { "https" } else { "http" };
|
|
||||||
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}:{server_port}/rustfs/console/index.html"
|
||||||
@@ -184,8 +182,8 @@ pub async fn start_http_server(
|
|||||||
DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY
|
DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
info!("For more information, visit https://rustfs.com/docs/");
|
info!(target: "rustfs::main::startup","For more information, visit https://rustfs.com/docs/");
|
||||||
info!("To enable the console, restart the server with --console-enable and a valid --console-address.");
|
info!(target: "rustfs::main::startup", "To enable the console, restart the server with --console-enable and a valid --console-address.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup S3 service
|
// Setup S3 service
|
||||||
@@ -223,7 +221,6 @@ pub async fn start_http_server(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Server will be created per connection - this ensures isolation
|
// Server will be created per connection - this ensures isolation
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
// Record the PID-related metrics of the current process
|
// Record the PID-related metrics of the current process
|
||||||
let meter = opentelemetry::global::meter("system");
|
let meter = opentelemetry::global::meter("system");
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ export RUSTFS_VOLUMES="./target/volume/test{1...4}"
|
|||||||
export RUSTFS_ADDRESS=":9000"
|
export RUSTFS_ADDRESS=":9000"
|
||||||
export RUSTFS_CONSOLE_ENABLE=true
|
export RUSTFS_CONSOLE_ENABLE=true
|
||||||
export RUSTFS_CONSOLE_ADDRESS=":9001"
|
export RUSTFS_CONSOLE_ADDRESS=":9001"
|
||||||
export RUSTFS_EXTERNAL_ADDRESS=":9000"
|
|
||||||
# export RUSTFS_SERVER_DOMAINS="localhost:9000"
|
# export RUSTFS_SERVER_DOMAINS="localhost:9000"
|
||||||
# HTTPS certificate directory
|
# HTTPS certificate directory
|
||||||
# export RUSTFS_TLS_PATH="./deploy/certs"
|
# export RUSTFS_TLS_PATH="./deploy/certs"
|
||||||
|
|||||||
Reference in New Issue
Block a user