change log dir option from toml to command line

This commit is contained in:
Jun Kurihara 2025-04-28 16:29:21 +09:00
commit f252959a2f
No known key found for this signature in database
GPG key ID: D992B3E3DE1DED23
8 changed files with 61 additions and 62 deletions

View file

@ -1,6 +1,11 @@
# CHANGELOG
## 0.9.8 or 0.10.0 (Unreleased)
## 0.10.0 (Unreleased)
### Important Changes
- [Breaking] We removed non-`watch` execute option and enabled the dynamic reloading of the config file by default.
- We newly added `log-dir` execute option to specify the directory for `access.log`,`error.log` and `rpxy.log`. This is optional, and if not specified, the logs are written to the standard output by default.
## 0.9.7

8
Cargo.lock generated
View file

@ -2084,7 +2084,7 @@ dependencies = [
[[package]]
name = "rpxy"
version = "0.9.7"
version = "0.10.0"
dependencies = [
"ahash",
"anyhow",
@ -2108,7 +2108,7 @@ dependencies = [
[[package]]
name = "rpxy-acme"
version = "0.9.7"
version = "0.10.0"
dependencies = [
"ahash",
"async-trait",
@ -2129,7 +2129,7 @@ dependencies = [
[[package]]
name = "rpxy-certs"
version = "0.9.7"
version = "0.10.0"
dependencies = [
"ahash",
"async-trait",
@ -2147,7 +2147,7 @@ dependencies = [
[[package]]
name = "rpxy-lib"
version = "0.9.7"
version = "0.10.0"
dependencies = [
"ahash",
"anyhow",

View file

@ -1,5 +1,5 @@
[workspace.package]
version = "0.9.7"
version = "0.10.0"
authors = ["Jun Kurihara"]
homepage = "https://github.com/junkurihara/rust-rpxy"
repository = "https://github.com/junkurihara/rust-rpxy"

View file

@ -80,7 +80,7 @@ You can run `rpxy` with a configuration file like
% ./target/release/rpxy --config config.toml
```
If you specify `-w` option along with the config file path, `rpxy` tracks the change of `config.toml` in the real-time manner and apply the change immediately without restarting the process.
`rpxy` tracks the change of `config.toml` in the real-time manner and apply the change immediately without restarting the process.
The full help messages are given follows.
@ -89,11 +89,16 @@ usage: rpxy [OPTIONS] --config <FILE>
Options:
-c, --config <FILE> Configuration file path like ./config.toml
-w, --watch Activate dynamic reloading of the config file via continuous monitoring
-h, --help Print help
-V, --version Print version
```
If you set `--log-dir=<log_dir>`, the log files are created in the specified directory. Otherwise, the log is printed to stdout.
- `${log_dir}/access.log` for access log
- `${log_dir}/error.log` for error log
- `${log_dir}/rpxy.log` for system log
That's all!
## Basic Configuration

View file

@ -1,18 +1,18 @@
use super::toml::ConfigToml;
use crate::error::{anyhow, ensure};
use ahash::HashMap;
use clap::{Arg, ArgAction};
use clap::Arg;
use hot_reload::{ReloaderReceiver, ReloaderService};
use rpxy_certs::{build_cert_reloader, CryptoFileSourceBuilder, CryptoReloader, ServerCryptoBase};
use rpxy_certs::{CryptoFileSourceBuilder, CryptoReloader, ServerCryptoBase, build_cert_reloader};
use rpxy_lib::{AppConfig, AppConfigList, ProxyConfig};
#[cfg(feature = "acme")]
use rpxy_acme::{AcmeManager, ACME_DIR_URL, ACME_REGISTRY_PATH};
use rpxy_acme::{ACME_DIR_URL, ACME_REGISTRY_PATH, AcmeManager};
/// Parsed options
pub struct Opts {
pub config_file_path: String,
pub watch: bool,
pub log_dir_path: Option<String>,
}
/// Parse arg values passed from cli
@ -28,19 +28,22 @@ pub fn parse_opts() -> Result<Opts, anyhow::Error> {
.help("Configuration file path like ./config.toml"),
)
.arg(
Arg::new("watch")
.long("watch")
.short('w')
.action(ArgAction::SetTrue)
.help("Activate dynamic reloading of the config file via continuous monitoring"),
Arg::new("log_dir")
.long("log-dir")
.short('l')
.value_name("LOG_DIR")
.help("Directory for log files. If not specified, logs are printed to stdout."),
);
let matches = options.get_matches();
///////////////////////////////////
let config_file_path = matches.get_one::<String>("config_file").unwrap().to_owned();
let watch = matches.get_one::<bool>("watch").unwrap().to_owned();
let log_dir_path = matches.get_one::<String>("log_dir").map(|v| v.to_owned());
Ok(Opts { config_file_path, watch })
Ok(Opts {
config_file_path,
log_dir_path,
})
}
pub fn build_settings(config: &ConfigToml) -> std::result::Result<(ProxyConfig, AppConfigList), anyhow::Error> {

View file

@ -4,7 +4,7 @@ use crate::{
log::warn,
};
use ahash::HashMap;
use rpxy_lib::{reexports::Uri, AppConfig, ProxyConfig, ReverseProxyConfig, TlsConfig, UpstreamUri};
use rpxy_lib::{AppConfig, ProxyConfig, ReverseProxyConfig, TlsConfig, UpstreamUri, reexports::Uri};
use serde::Deserialize;
use std::{fs, net::SocketAddr};
use tokio::time::Duration;

View file

@ -5,7 +5,12 @@ use tracing_subscriber::{fmt, prelude::*};
pub use tracing::{debug, error, info, warn};
/// Initialize the logger with the RUST_LOG environment variable.
pub fn init_logger() {
pub fn init_logger(log_dir_path: Option<&str>) {
if log_dir_path.is_some() {
// TODO:
println!("Activate logging to files")
}
let level_string = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
let level = tracing::Level::from_str(level_string.as_str()).unwrap_or(tracing::Level::INFO);

View file

@ -20,8 +20,6 @@ use std::sync::Arc;
use tokio_util::sync::CancellationToken;
fn main() {
init_logger();
let mut runtime_builder = tokio::runtime::Builder::new_multi_thread();
runtime_builder.enable_all();
runtime_builder.thread_name("rpxy");
@ -30,40 +28,34 @@ fn main() {
runtime.block_on(async {
// Initially load options
let Ok(parsed_opts) = parse_opts() else {
error!("Invalid toml file");
std::process::exit(1);
};
if !parsed_opts.watch {
if let Err(e) = rpxy_service_without_watcher(&parsed_opts.config_file_path, runtime.handle().clone()).await {
error!("rpxy service existed: {e}");
std::process::exit(1);
}
} else {
let (config_service, config_rx) = ReloaderService::<ConfigTomlReloader, ConfigToml, String>::new(
&parsed_opts.config_file_path,
CONFIG_WATCH_DELAY_SECS,
false,
)
.await
.unwrap();
init_logger(parsed_opts.log_dir_path.as_deref());
tokio::select! {
config_res = config_service.start() => {
if let Err(e) = config_res {
error!("config reloader service exited: {e}");
std::process::exit(1);
}
}
rpxy_res = rpxy_service_with_watcher(config_rx, runtime.handle().clone()) => {
if let Err(e) = rpxy_res {
error!("rpxy service existed: {e}");
std::process::exit(1);
}
let (config_service, config_rx) = ReloaderService::<ConfigTomlReloader, ConfigToml, String>::new(
&parsed_opts.config_file_path,
CONFIG_WATCH_DELAY_SECS,
false,
)
.await
.unwrap();
tokio::select! {
config_res = config_service.start() => {
if let Err(e) = config_res {
error!("config reloader service exited: {e}");
std::process::exit(1);
}
}
rpxy_res = rpxy_service(config_rx, runtime.handle().clone()) => {
if let Err(e) = rpxy_res {
error!("rpxy service existed: {e}");
std::process::exit(1);
}
}
std::process::exit(0);
}
std::process::exit(0);
});
}
@ -233,18 +225,7 @@ impl RpxyService {
}
}
async fn rpxy_service_without_watcher(
config_file_path: &str,
runtime_handle: tokio::runtime::Handle,
) -> Result<(), anyhow::Error> {
info!("Start rpxy service");
let config_toml = ConfigToml::new(config_file_path).map_err(|e| anyhow!("Invalid toml file: {e}"))?;
let service = RpxyService::new(&config_toml, runtime_handle).await?;
// Create cancel token that is never be called as dummy
service.start(tokio_util::sync::CancellationToken::new()).await
}
async fn rpxy_service_with_watcher(
async fn rpxy_service(
mut config_rx: ReloaderReceiver<ConfigToml, String>,
runtime_handle: tokio::runtime::Handle,
) -> Result<(), anyhow::Error> {