refactor: improve server log information
Diff
Cargo.toml | 2 +-
src/helpers.rs | 6 +---
src/lib.rs | 1 +-
src/logger.rs | 38 +++++++++++++++++++---
src/server.rs | 95 +++++++++++++++++++++++++++---------------------------
src/settings/mod.rs | 15 +++------
6 files changed, 89 insertions(+), 68 deletions(-)
@@ -82,7 +82,7 @@ tokio-rustls = { version = "0.24", optional = true }
tokio-util = { version = "0.7", default-features = false, features = ["io"] }
toml = "0.7"
tracing = { version = "0.1", default-features = false, features = ["std"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["smallvec", "parking_lot", "fmt", "ansi", "tracing-log"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["smallvec", "registry", "parking_lot", "fmt", "ansi", "tracing-log"] }
[target.'cfg(all(target_env = "musl", target_pointer_width = "64"))'.dependencies.tikv-jemallocator]
version = "0.5"
@@ -63,12 +63,6 @@ pub fn stringify(dst: &mut String, path: &serde_ignored::Path<'_>) {
}
}
#[cfg(unix)]
pub fn adjust_canonicalization(p: &Path) -> String {
p.display().to_string()
}
#[cfg(windows)]
pub fn adjust_canonicalization(p: &Path) -> String {
@@ -130,6 +130,7 @@ pub mod handler;
#[cfg(feature = "http2")]
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
pub mod https_redirect;
#[macro_use]
pub mod logger;
pub mod redirects;
pub mod rewrites;
@@ -7,7 +7,7 @@
use tracing::Level;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::{filter::Targets, fmt::format::FmtSpan, prelude::*};
use crate::{Context, Result};
@@ -17,8 +17,6 @@ pub fn init(log_level: &str) -> Result {
configure(&log_level).with_context(|| "failed to initialize logging")?;
tracing::info!("logging level: {}", log_level);
Ok(())
}
@@ -31,14 +29,44 @@ fn configure(level: &str) -> Result {
#[cfg(windows)]
let enable_ansi = false;
match tracing_subscriber::fmt()
let filtered_layer = tracing_subscriber::fmt::layer()
.with_writer(std::io::stderr)
.with_max_level(level)
.with_span_events(FmtSpan::CLOSE)
.with_ansi(enable_ansi)
.with_filter(
Targets::default()
.with_default(level)
.with_target("static_web_server::info", Level::INFO)
.with_target("static_web_server::warn", Level::WARN),
);
match tracing_subscriber::registry()
.with(filtered_layer)
.try_init()
{
Err(err) => Err(anyhow!(err)),
_ => Ok(()),
}
}
#[macro_export]
macro_rules! server_info {
($($arg:tt)*) => {
tracing::info!(
target: "static_web_server::info",
$($arg)*
)
};
}
#[macro_export]
macro_rules! server_warn {
($($arg:tt)*) => {
tracing::warn!(
target: "static_web_server::warn",
$($arg)*
)
};
}
@@ -76,7 +76,7 @@ impl Server {
where
F: FnOnce(),
{
tracing::debug!(%self.worker_threads, "initializing tokio runtime with multi thread scheduler");
tracing::debug!(%self.worker_threads, "initializing tokio runtime with multi-thread scheduler");
tokio::runtime::Builder::new_multi_thread()
.worker_threads(self.worker_threads)
@@ -85,15 +85,13 @@ impl Server {
.enable_all()
.build()?
.block_on(async {
tracing::trace!("starting web server");
tracing::trace!("tokio runtime initialized");
if let Err(err) = self.start_server(cancel_recv, cancel_fn).await {
tracing::error!("server failed to start up: {:?}", err);
std::process::exit(1)
}
});
tracing::trace!("runtime initialized");
Ok(())
}
@@ -103,16 +101,19 @@ impl Server {
where
F: FnOnce(),
{
tracing::trace!("starting web server");
server_info!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
let general = self.opts.general;
let advanced_opts = self.opts.advanced;
server_info!("log level: {}", general.log_level);
if let Some(config_file) = general.config_file {
let config_file = helpers::adjust_canonicalization(&config_file);
tracing::info!("config file: {}", config_file);
server_info!("config file: {}", config_file.display());
}
@@ -123,7 +124,7 @@ impl Server {
tcp_listener = ListenFd::from_env()
.take_tcp_listener(fd)?
.with_context(|| "failed to convert inherited 'fd' into a 'tcp' listener")?;
tracing::info!(
server_info!(
"converted inherited file descriptor {} to a 'tcp' listener",
fd
);
@@ -137,10 +138,20 @@ impl Server {
tcp_listener = TcpListener::bind(addr)
.with_context(|| format!("failed to bind to {addr} address"))?;
addr_str = addr.to_string();
tracing::info!("server bound to tcp socket {}", addr_str);
server_info!("server bound to tcp socket {}", addr_str);
}
}
let threads = self.worker_threads;
server_info!("runtime worker threads: {}", threads);
server_info!(
"runtime max blocking threads: {}",
general.max_blocking_threads
);
let root_dir = helpers::get_valid_dirpath(&general.root)
.with_context(|| "root directory was not found or inaccessible")?;
@@ -162,26 +173,16 @@ impl Server {
page_fallback_opt = page_fallback_pbuf.to_str().unwrap()
}
tracing::info!(
server_info!(
"fallback page: enabled={}, value=\"{}\"",
page_fallback_enabled,
page_fallback_opt
);
}
let threads = self.worker_threads;
tracing::info!("runtime worker threads: {}", threads);
tracing::info!(
"runtime max blocking threads: {}",
general.max_blocking_threads
);
let security_headers = general.security_headers;
tracing::info!("security headers: enabled={}", security_headers);
server_info!("security headers: enabled={}", security_headers);
#[cfg(not(feature = "compression"))]
@@ -189,7 +190,7 @@ impl Server {
#[cfg(feature = "compression")]
let compression = general.compression;
#[cfg(feature = "compression")]
tracing::info!("auto compression: enabled={}", compression);
server_info!("auto compression: enabled={}", compression);
#[cfg(not(feature = "compression"))]
@@ -197,27 +198,27 @@ impl Server {
#[cfg(feature = "compression")]
let compression_static = general.compression_static;
#[cfg(feature = "compression")]
tracing::info!("compression static: enabled={}", compression_static);
server_info!("compression static: enabled={}", compression_static);
#[cfg(feature = "directory-listing")]
let dir_listing = general.directory_listing;
#[cfg(feature = "directory-listing")]
tracing::info!("directory listing: enabled={}", dir_listing);
server_info!("directory listing: enabled={}", dir_listing);
#[cfg(feature = "directory-listing")]
let dir_listing_order = general.directory_listing_order;
#[cfg(feature = "directory-listing")]
tracing::info!("directory listing order code: {}", dir_listing_order);
server_info!("directory listing order code: {}", dir_listing_order);
#[cfg(feature = "directory-listing")]
let dir_listing_format = general.directory_listing_format;
#[cfg(feature = "directory-listing")]
tracing::info!("directory listing format: {:?}", dir_listing_format);
server_info!("directory listing format: {:?}", dir_listing_format);
let cache_control_headers = general.cache_control_headers;
tracing::info!("cache control headers: enabled={}", cache_control_headers);
server_info!("cache control headers: enabled={}", cache_control_headers);
let cors = cors::new(
@@ -230,33 +231,33 @@ impl Server {
let basic_auth = general.basic_auth.trim().to_owned();
#[cfg(feature = "basic-auth")]
tracing::info!(
server_info!(
"basic authentication: enabled={}",
!general.basic_auth.is_empty()
);
let log_remote_address = general.log_remote_address;
tracing::info!("log remote address: enabled={}", log_remote_address);
server_info!("log remote address: enabled={}", log_remote_address);
let redirect_trailing_slash = general.redirect_trailing_slash;
tracing::info!(
server_info!(
"redirect trailing slash: enabled={}",
redirect_trailing_slash
);
let ignore_hidden_files = general.ignore_hidden_files;
tracing::info!("ignore hidden files: enabled={}", ignore_hidden_files);
server_info!("ignore hidden files: enabled={}", ignore_hidden_files);
let grace_period = general.grace_period;
tracing::info!("grace period before graceful shutdown: {}s", grace_period);
server_info!("grace period before graceful shutdown: {}s", grace_period);
let health = general.health;
tracing::info!("health endpoint: enabled={}", health);
server_info!("health endpoint: enabled={}", health);
let router_service = RouterService::new(RequestHandler {
@@ -293,11 +294,11 @@ impl Server {
#[cfg(windows)]
let ctrlc_task = tokio::spawn(async move {
if !general.windows_service {
tracing::info!("installing graceful shutdown ctrl+c signal handler");
server_info!("installing graceful shutdown ctrl+c signal handler");
tokio::signal::ctrl_c()
.await
.expect("failed to install ctrl+c signal handler");
tracing::info!("installing graceful shutdown ctrl+c signal handler");
server_info!("installing graceful shutdown ctrl+c signal handler");
let _ = sender.send(());
}
});
@@ -307,16 +308,16 @@ impl Server {
if general.http2 {
let https_redirect = general.https_redirect;
tracing::info!("http to https redirect: enabled={}", https_redirect);
tracing::info!(
server_info!("http to https redirect: enabled={}", https_redirect);
server_info!(
"http to https redirect host: {}",
general.https_redirect_host
);
tracing::info!(
server_info!(
"http to https redirect from port: {}",
general.https_redirect_from_port
);
tracing::info!(
server_info!(
"http to https redirect from hosts: {}",
general.https_redirect_from_hosts
);
@@ -381,7 +382,7 @@ impl Server {
}
});
tracing::info!(
server_info!(
parent: tracing::info_span!("Server::start_server", ?addr_str, ?threads),
"http2 server is listening on https://{}",
addr_str
@@ -396,7 +397,7 @@ impl Server {
let addr = SocketAddr::from((ip, general.https_redirect_from_port));
let tcp_listener = TcpListener::bind(addr)
.with_context(|| format!("failed to bind to {addr} address"))?;
tracing::info!(
server_info!(
parent: tracing::info_span!("Server::start_server", ?addr, ?threads),
"http1 redirect server is listening on http://{}",
addr
@@ -484,7 +485,7 @@ impl Server {
}
});
tracing::info!("press ctrl+c to shut down the servers");
server_info!("press ctrl+c to shut down the servers");
#[cfg(windows)]
tokio::try_join!(ctrlc_task, server_task, redirect_server_task)?;
@@ -494,7 +495,7 @@ impl Server {
#[cfg(unix)]
redirect_handle.close();
} else {
tracing::info!("press ctrl+c to shut down the server");
server_info!("press ctrl+c to shut down the server");
http2_server.await?;
}
@@ -504,7 +505,7 @@ impl Server {
#[cfg(windows)]
_cancel_fn();
tracing::warn!("termination signal caught, shutting down the server execution");
server_warn!("termination signal caught, shutting down the server execution");
return Ok(());
}
@@ -543,13 +544,13 @@ impl Server {
}
});
tracing::info!(
server_info!(
parent: tracing::info_span!("Server::start_server", ?addr_str, ?threads),
"http1 server is listening on http://{}",
addr_str
);
tracing::info!("press ctrl+c to shut down the server");
server_info!("press ctrl+c to shut down the server");
http1_server.await?;
@@ -559,7 +560,7 @@ impl Server {
#[cfg(unix)]
handle.close();
tracing::warn!("termination signal caught, shutting down the server execution");
server_warn!("termination signal caught, shutting down the server execution");
Ok(())
}
}
@@ -284,6 +284,7 @@ impl Settings {
logger::init(log_level.as_str())?;
tracing::debug!("toml configuration file read successfully");
if let Some(advanced) = settings.advanced {
@@ -374,14 +375,14 @@ impl Settings {
let pattern =
source.glob().regex().trim_start_matches("(?-u)").to_owned();
tracing::debug!(
"url rewrites glob pattern: {}",
"url redirects glob pattern: {}",
&redirects_entry.source
);
tracing::debug!("url rewrites regex equivalent: {}", pattern);
tracing::debug!("url redirects regex equivalent: {}", pattern);
let source = Regex::new(&pattern).with_context(|| {
format!(
"can not compile regex pattern equivalent for rewrite source: {}",
"can not compile regex pattern equivalent for redirect source: {}",
&pattern
)
})?;
@@ -479,17 +480,13 @@ fn get_file_settings(file_path_opt: Option<PathBuf>) -> Result<Option<(FileSetti
let file_path_resolved = file_path
.canonicalize()
.with_context(|| "error resolving toml config file path")?;
let settings = FileSettings::read(&file_path_resolved).with_context(|| {
"can not read toml config file because has invalid or unsupported format/options"
})?;
return Ok(Some((settings, file_path_resolved)));
}
tracing::warn!(
"config file `{}` is not a regular toml file, ignored!",
file_path.display()
);
} else {
tracing::warn!("config file was not determined, ignored!");
}
Ok(None)
}