mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +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
|
||||
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
|
||||
/// This is the default log directory for rustfs.
|
||||
/// 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
|
||||
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
|
||||
pub const KI_B: usize = 1024;
|
||||
/// 1 MiB
|
||||
|
||||
+113
-23
@@ -38,7 +38,7 @@ pub const DISK_RESERVE_FRACTION: f64 = 0.15;
|
||||
|
||||
lazy_static! {
|
||||
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_LOCAL_DISK: Arc<RwLock<Vec<Option<DiskStore>>>> = Arc::new(RwLock::new(Vec::new()));
|
||||
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_LifecycleSys: Arc<LifecycleSys> = LifecycleSys::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_LocalNodeName: String = "127.0.0.1:9000".to_string();
|
||||
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();
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
/// Global active credentials
|
||||
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 = {
|
||||
if let Some(k) = ak {
|
||||
k
|
||||
@@ -91,11 +99,16 @@ pub fn init_global_action_cred(ak: Option<String>, sk: Option<String>) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Get the global action credentials
|
||||
pub fn get_global_action_cred() -> Option<Credentials> {
|
||||
GLOBAL_ACTIVE_CRED.get().cloned()
|
||||
}
|
||||
|
||||
/// Get the global rustfs port
|
||||
///
|
||||
/// # Returns
|
||||
/// * `u16` - The global rustfs port
|
||||
///
|
||||
pub fn global_rustfs_port() -> u16 {
|
||||
if let Some(p) = GLOBAL_RUSTFS_PORT.get() {
|
||||
*p
|
||||
@@ -105,36 +118,44 @@ pub fn global_rustfs_port() -> u16 {
|
||||
}
|
||||
|
||||
/// Set the global rustfs port
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `value` - The port value to set globally
|
||||
///
|
||||
/// # Returns
|
||||
/// * None
|
||||
pub fn set_global_rustfs_port(value: u16) {
|
||||
GLOBAL_RUSTFS_PORT.set(value).expect("set_global_rustfs_port fail");
|
||||
}
|
||||
|
||||
/// Get the global rustfs external port
|
||||
pub fn global_rustfs_external_port() -> u16 {
|
||||
if let Some(p) = GLOBAL_RUSTFS_EXTERNAL_PORT.get() {
|
||||
*p
|
||||
} else {
|
||||
rustfs_config::DEFAULT_PORT
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// Set the global deployment id
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - The Uuid to set as the global deployment id
|
||||
///
|
||||
/// # Returns
|
||||
/// * None
|
||||
///
|
||||
pub fn set_global_deployment_id(id: Uuid) {
|
||||
globalDeploymentIDPtr.set(id).unwrap();
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
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>) {
|
||||
GLOBAL_Endpoints
|
||||
.set(EndpointServerPools::from(eps))
|
||||
@@ -142,6 +163,10 @@ pub fn set_global_endpoints(eps: Vec<PoolEndpoints>) {
|
||||
}
|
||||
|
||||
/// Get the global endpoints
|
||||
///
|
||||
/// # Returns
|
||||
/// * `EndpointServerPools` - The global endpoints
|
||||
///
|
||||
pub fn get_global_endpoints() -> EndpointServerPools {
|
||||
if let Some(eps) = GLOBAL_Endpoints.get() {
|
||||
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>> {
|
||||
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>) {
|
||||
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 {
|
||||
let lock = GLOBAL_IsDistErasure.read().await;
|
||||
*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 {
|
||||
let lock = GLOBAL_IsErasureSD.read().await;
|
||||
*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 {
|
||||
let lock = GLOBAL_IsErasure.read().await;
|
||||
*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) {
|
||||
let mut is_erasure = GLOBAL_IsErasure.write().await;
|
||||
*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>>>>;
|
||||
|
||||
/// Set the global region
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `region` - The region string to set globally
|
||||
///
|
||||
/// # Returns
|
||||
/// * None
|
||||
pub fn set_global_region(region: String) {
|
||||
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> {
|
||||
GLOBAL_REGION.get().cloned()
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.set(cancel_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> {
|
||||
GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get()
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
let cancel_token = CancellationToken::new();
|
||||
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
|
||||
///
|
||||
/// # Returns
|
||||
/// * None
|
||||
pub fn shutdown_background_services() {
|
||||
if let Some(cancel_token) = GLOBAL_BACKGROUND_SERVICES_CANCEL_TOKEN.get() {
|
||||
cancel_token.cancel();
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::telemetry::{OtelGuard, init_telemetry};
|
||||
use opentelemetry::metrics::Meter;
|
||||
use rustfs_config::APP_NAME;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::sync::{OnceCell, SetError};
|
||||
use tracing::{error, info};
|
||||
@@ -21,6 +23,23 @@ use tracing::{error, info};
|
||||
/// Global guard for OpenTelemetry tracing
|
||||
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
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum GlobalError {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::config::OtelConfig;
|
||||
use crate::global::{IS_OBSERVABILITY_ENABLED, OBSERVABILITY_METER_NAME};
|
||||
use flexi_logger::{
|
||||
Age, Cleanup, Criterion, DeferredNow, FileSpec, LogSpecification, Naming, Record, WriteMode,
|
||||
WriteMode::{AsyncWith, BufferAndFlush},
|
||||
@@ -302,6 +303,8 @@ pub(crate) fn init_telemetry(config: &OtelConfig) -> OtelGuard {
|
||||
logger_level,
|
||||
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>> {
|
||||
match host {
|
||||
Host::Domain(domain) => {
|
||||
// match crate::dns_resolver::resolve_domain(domain).await {
|
||||
// Ok(ips) => {
|
||||
// info!("Resolved domain {domain} using custom DNS resolver: {ips:?}");
|
||||
// return Ok(ips.into_iter().collect());
|
||||
// }
|
||||
// Err(err) => {
|
||||
// error!(
|
||||
// "Failed to resolve domain {domain} using custom DNS resolver, falling back to system resolver,err: {err}"
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
match crate::dns_resolver::resolve_domain(domain).await {
|
||||
Ok(ips) => {
|
||||
info!("Resolved domain {domain} using custom DNS resolver: {ips:?}");
|
||||
return Ok(ips.into_iter().collect());
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Failed to resolve domain {domain} using custom DNS resolver, falling back to system resolver,err: {err}"
|
||||
);
|
||||
}
|
||||
}
|
||||
// Check cache first
|
||||
if CUSTOM_DNS_RESOLVER.read().unwrap().is_none() {
|
||||
if let Ok(mut cache) = DNS_CACHE.lock() {
|
||||
|
||||
@@ -40,7 +40,6 @@ use tower_http::timeout::TimeoutLayer;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
|
||||
// shadow!(build);
|
||||
pub(crate) const CONSOLE_PREFIX: &str = "/rustfs/console";
|
||||
const RUSTFS_ADMIN_PREFIX: &str = "/rustfs/admin/v3";
|
||||
|
||||
@@ -49,6 +48,17 @@ const RUSTFS_ADMIN_PREFIX: &str = "/rustfs/admin/v3";
|
||||
struct StaticFiles;
|
||||
|
||||
/// 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 {
|
||||
let mut path = uri.path().trim_start_matches('/');
|
||||
if path.is_empty() {
|
||||
@@ -71,7 +81,7 @@ pub(crate) async fn static_handler(uri: Uri) -> impl IntoResponse {
|
||||
} else {
|
||||
Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
.body(Body::from("404 Not Found"))
|
||||
.body(Body::from(" 404 Not Found \n RustFS "))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
@@ -214,8 +224,6 @@ fn _is_private_ip(ip: IpAddr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::const_is_empty)]
|
||||
#[allow(dead_code)]
|
||||
#[instrument(fields(host))]
|
||||
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
|
||||
@@ -390,8 +398,8 @@ fn setup_console_middleware_stack(
|
||||
auth_timeout: u64,
|
||||
) -> Router {
|
||||
let mut app = Router::new()
|
||||
.route(&format!("{CONSOLE_PREFIX}/license"), get(crate::admin::console::license_handler))
|
||||
.route(&format!("{CONSOLE_PREFIX}/config.json"), get(crate::admin::console::config_handler))
|
||||
.route(&format!("{CONSOLE_PREFIX}/license"), get(license_handler))
|
||||
.route(&format!("{CONSOLE_PREFIX}/config.json"), get(config_handler))
|
||||
.route(&format!("{CONSOLE_PREFIX}/health"), get(health_check))
|
||||
.nest(CONSOLE_PREFIX, Router::new().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
|
||||
.layer(TimeoutLayer::new(Duration::from_secs(auth_timeout)))
|
||||
// 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
|
||||
if rate_limit_enable {
|
||||
|
||||
@@ -41,23 +41,6 @@ mod tests {
|
||||
// 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]
|
||||
async fn test_console_tls_configuration() {
|
||||
// Test TLS configuration options (now uses shared tls_path)
|
||||
@@ -103,14 +86,11 @@ mod tests {
|
||||
"true",
|
||||
"--console-address",
|
||||
":9001",
|
||||
"--external-address",
|
||||
":9020",
|
||||
];
|
||||
let opt = Opt::parse_from(args);
|
||||
|
||||
// Verify all console-related configuration is parsed correctly
|
||||
assert!(opt.console_enable);
|
||||
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_eq!(opt.console_address, ":9001");
|
||||
assert_eq!(opt.external_address, ":9000"); // Now defaults to DEFAULT_ADDRESS
|
||||
assert_eq!(opt.address, ":9000");
|
||||
}
|
||||
|
||||
@@ -49,15 +48,6 @@ mod tests {
|
||||
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]
|
||||
fn test_console_and_endpoint_ports_different() {
|
||||
// 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")]
|
||||
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.
|
||||
#[arg(long, default_value_t = rustfs_config::DEFAULT_OBS_ENDPOINT.to_string(), env = "RUSTFS_OBS_ENDPOINT")]
|
||||
pub obs_endpoint: String,
|
||||
@@ -89,18 +83,6 @@ pub struct Opt {
|
||||
#[arg(long, env = "RUSTFS_TLS_PATH")]
|
||||
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")]
|
||||
pub license: Option<String>,
|
||||
|
||||
|
||||
+23
-11
@@ -132,26 +132,38 @@ async fn async_main() -> Result<()> {
|
||||
info!("{}", LOGO);
|
||||
|
||||
// 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
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
profiling::start_profiling_if_enabled();
|
||||
|
||||
// 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))]
|
||||
async fn run(opt: config::Opt) -> Result<()> {
|
||||
debug!("opt: {:?}", &opt);
|
||||
|
||||
// // Initialize global DNS resolver early for enhanced DNS resolution (concurrent)
|
||||
// let dns_init = tokio::spawn(async {
|
||||
// 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);
|
||||
// }
|
||||
// });
|
||||
// Initialize global DNS resolver early for enhanced DNS resolution (concurrent)
|
||||
let dns_init = tokio::spawn(async {
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(region) = &opt.region {
|
||||
rustfs_ecstore::global::set_global_region(region.clone());
|
||||
@@ -172,14 +184,14 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
);
|
||||
|
||||
// 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_addr(&opt.address).await;
|
||||
|
||||
// // Wait for DNS initialization to complete before network-heavy operations
|
||||
// dns_init.await.map_err(Error::other)?;
|
||||
// Wait for DNS initialization to complete before network-heavy operations
|
||||
dns_init.await.map_err(Error::other)?;
|
||||
|
||||
// For RPC
|
||||
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()
|
||||
}
|
||||
};
|
||||
|
||||
// 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_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 {
|
||||
admin::console::init_console_cfg(local_ip, server_port);
|
||||
|
||||
let protocol = if tls_enabled { "https" } else { "http" };
|
||||
info!(
|
||||
target: "rustfs::console::startup",
|
||||
"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
|
||||
);
|
||||
}
|
||||
info!("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","For more information, visit https://rustfs.com/docs/");
|
||||
info!(target: "rustfs::main::startup", "To enable the console, restart the server with --console-enable and a valid --console-address.");
|
||||
}
|
||||
|
||||
// Setup S3 service
|
||||
@@ -223,7 +221,6 @@ pub async fn start_http_server(
|
||||
};
|
||||
|
||||
// Server will be created per connection - this ensures isolation
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Record the PID-related metrics of the current process
|
||||
let meter = opentelemetry::global::meter("system");
|
||||
|
||||
@@ -46,7 +46,6 @@ export RUSTFS_VOLUMES="./target/volume/test{1...4}"
|
||||
export RUSTFS_ADDRESS=":9000"
|
||||
export RUSTFS_CONSOLE_ENABLE=true
|
||||
export RUSTFS_CONSOLE_ADDRESS=":9001"
|
||||
export RUSTFS_EXTERNAL_ADDRESS=":9000"
|
||||
# export RUSTFS_SERVER_DOMAINS="localhost:9000"
|
||||
# HTTPS certificate directory
|
||||
# export RUSTFS_TLS_PATH="./deploy/certs"
|
||||
|
||||
Reference in New Issue
Block a user