feat: control log ANSI output via boolean --log-with-ansi option (#543)

This PR adds support for controlling ANSI escape codes for colors and other text formatting when logging via a new boolean --log-with-ansi CLI option and its equivalent SERVER_LOG_WITH_ANSI env.

No ANSI by default:
Note that from now on, SWS will be no-ansi by default. If you want colored log output, then use --log-with-ansi.
For example:

```
static-web-server -p 8788 -d ./public/ -g trace -z --log-with-ansi
```
This commit is contained in:
Jose Quintana
2025-05-17 14:39:37 +02:00
committed by GitHub
parent cb1999550e
commit 0236980bc5
6 changed files with 39 additions and 11 deletions

View File

@@ -27,6 +27,9 @@ Defines a grace period in seconds after a `SIGTERM` signal is caught which will
### SERVER_LOG_LEVEL
Specify a logging level in lowercase. Possible values are `error`, `warn`, `info`, `debug` or `trace`. Default `error`.
### SERVER_LOG_WITH_ANSI
Enable or disable ANSI escape codes for colors and other text formatting of the log output.
### SERVER_LOG_REMOTE_ADDRESS
Log incoming request information along with its Remote Address (IP) if available using the `info` log level. Default `false`.

View File

@@ -15,6 +15,16 @@ static-web-server \
> Note: The log format is not well defined and is subject to change.
## Log output with ANSI
SWS does not output ANSI escape codes by default. However, If you want ANSI escape for colors and other text formatting when logging then use the boolean `--log-with-ansi` CLI option and its equivalent [SERVER_LOG_WITH_ANSI](./../configuration/environment-variables.md#server_log_with_ansi) env.
For example, if you want colored log output then use the `--log-with-ansi` option as follows:
```sh
static-web-server -p 8788 -d ./public/ -g trace -z --log-with-ansi
```
## Log Remote Addresses
SWS provides *Remote Address (IP)* logging for every request via an `INFO` log level.
@@ -76,6 +86,7 @@ Since the content of the `X-Forwarded-For` header can be changed by all proxies
To restrict the logging to only requests that originate from trusted proxy IPs, you can use the `--trusted-proxies` option, or the equivalent [SERVER_TRUSTED_PROXIES](../configuration/environment-variables.md#server_trusted_proxies) env. This should be a list of IPs, separated by commas. An empty list (the default) indicates that all IPs should be trusted.
Command used for the following examples:
```sh
static-web-server -a "::" --log-forwarded-for=true --trusted-proxies="::1" -p 8080 -d docker/public/ -g info
```

View File

@@ -12,25 +12,20 @@ use tracing_subscriber::{filter::Targets, fmt::format::FmtSpan, prelude::*};
use crate::{Context, Result};
/// Logging system initialization
pub fn init(log_level: &str) -> Result {
pub fn init(log_level: &str, log_with_ansi: bool) -> Result {
let log_level = log_level.to_lowercase();
configure(&log_level).with_context(|| "failed to initialize logging")?;
configure(&log_level, log_with_ansi).with_context(|| "failed to initialize logging")?;
Ok(())
}
/// Initialize logging builder with its levels.
fn configure(level: &str) -> Result {
fn configure(level: &str, enable_ansi: bool) -> Result {
let level = level
.parse::<Level>()
.with_context(|| "failed to parse log level")?;
#[cfg(not(windows))]
let enable_ansi = true;
#[cfg(windows)]
let enable_ansi = false;
let filtered_layer = tracing_subscriber::fmt::layer()
.with_writer(std::io::stderr)
.with_span_events(FmtSpan::CLOSE)

View File

@@ -123,6 +123,18 @@ pub struct General {
/// Specify a logging level in lower case. Values: error, warn, info, debug or trace
pub log_level: String,
#[arg(
long,
default_value = "false",
default_missing_value("true"),
num_args(0..=1),
require_equals(false),
action = clap::ArgAction::Set,
env = "SERVER_LOG_WITH_ANSI",
)]
/// Enable or disable ANSI escape codes for colors and other text formatting of the log output.
pub log_with_ansi: bool,
#[arg(
long,
short = 'c',

View File

@@ -205,8 +205,10 @@ pub struct General {
/// Root directory path.
pub root: Option<PathBuf>,
/// Logging.
/// Logging level.
pub log_level: Option<LogLevel>,
/// Enable/disable ANSI escape codes for log output.
pub log_with_ansi: Option<bool>,
/// Cache Control headers.
pub cache_control_headers: Option<bool>,

View File

@@ -127,6 +127,7 @@ impl Settings {
let mut port = opts.port;
let mut root = opts.root;
let mut log_level = opts.log_level;
let mut log_with_ansi = opts.log_with_ansi;
let mut config_file = opts.config_file.clone();
let mut cache_control_headers = opts.cache_control_headers;
@@ -242,6 +243,9 @@ impl Settings {
if let Some(ref v) = general.log_level {
log_level = v.name().to_lowercase();
}
if let Some(v) = general.log_with_ansi {
log_with_ansi = v;
}
if let Some(v) = general.cache_control_headers {
cache_control_headers = v
}
@@ -414,7 +418,7 @@ impl Settings {
// Logging system initialization in config file context
if log_init {
logger::init(log_level.as_str())?;
logger::init(log_level.as_str(), log_with_ansi)?;
}
tracing::debug!("config file read successfully");
@@ -596,7 +600,7 @@ impl Settings {
}
} else if log_init {
// Logging system initialization on demand
logger::init(log_level.as_str())?;
logger::init(log_level.as_str(), log_with_ansi)?;
}
Ok(Settings {
@@ -606,6 +610,7 @@ impl Settings {
port,
root,
log_level,
log_with_ansi,
config_file,
cache_control_headers,
#[cfg(any(