mirror of
https://github.com/sadoyan/aralez.git
synced 2026-10-23 06:01:35 +08:00
Added log file rotation and compression. Updated to Rust 1.97.0
This commit is contained in:
Generated
+284
-539
File diff suppressed because it is too large
Load Diff
+7
-5
@@ -23,20 +23,20 @@ pingora-http = "0.8.1"
|
|||||||
pingora-limits = "0.8.1"
|
pingora-limits = "0.8.1"
|
||||||
dashmap = "7.0.0-rc2"
|
dashmap = "7.0.0-rc2"
|
||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
log = "0.4.30"
|
log = "0.4.33"
|
||||||
notify = "9.0.0-rc.4"
|
notify = "9.0.0-rc.4"
|
||||||
axum = { version = "0.8.9" }
|
axum = { version = "0.8.9" }
|
||||||
reqwest = { version = "0.13.4", features = ["json", "stream", "blocking"] }
|
reqwest = { version = "0.13.4", features = ["json", "stream", "blocking"] }
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
noyalib = { version = "0.0.8", features = ["compat-serde-yaml"] }
|
noyalib = { version = "0.0.15", features = ["compat-serde-yaml"] }
|
||||||
rand = "0.10.1"
|
rand = "0.10.2"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
jsonwebtoken = { version = "10.4.0", default-features = false, features = ["use_pem", "rust_crypto"] }
|
jsonwebtoken = { version = "10.4.0", default-features = false, features = ["use_pem", "rust_crypto"] }
|
||||||
tonic = "0.14.6"
|
tonic = "0.14.6"
|
||||||
sha2 = { version = "0.11.0-rc.5", default-features = false }
|
sha2 = { version = "0.11.0-rc.5", default-features = false }
|
||||||
base16ct = { version = "1.0.0", features = ["alloc"] }
|
base16ct = { version = "1.0.0", features = ["alloc"] }
|
||||||
urlencoding = "2.1.3"
|
urlencoding = "2.1.3"
|
||||||
arc-swap = "1.9.1"
|
arc-swap = "1.9.2"
|
||||||
prometheus = "0.14.0"
|
prometheus = "0.14.0"
|
||||||
x509-parser = "0.18.1"
|
x509-parser = "0.18.1"
|
||||||
rustls-pemfile = "2.2.0"
|
rustls-pemfile = "2.2.0"
|
||||||
@@ -48,7 +48,9 @@ moka = { version = "0.12.15", features = ["sync"] }
|
|||||||
ahash = "0.8.12"
|
ahash = "0.8.12"
|
||||||
instant-acme = "0.8.5"
|
instant-acme = "0.8.5"
|
||||||
rcgen = "0.14.8"
|
rcgen = "0.14.8"
|
||||||
log4rs = "1.4.0"
|
#log4rs = "1.4.0"
|
||||||
|
#log4rs = { version = "1.4.0", features = ["rolling_file_appender", "compound_policy", "size_trigger", "fixed_window_roller"] }
|
||||||
|
log4rs = { version = "1.4.0", features = ["rolling_file_appender", "compound_policy", "size_trigger", "fixed_window_roller", "gzip"] }
|
||||||
mimalloc = { version = "0.1.52", default-features = false }
|
mimalloc = { version = "0.1.52", default-features = false }
|
||||||
signal-hook = "0.4.4"
|
signal-hook = "0.4.4"
|
||||||
sd-notify = "0.5.0"
|
sd-notify = "0.5.0"
|
||||||
|
|||||||
@@ -60,28 +60,28 @@ Built on Rust, on top of **Cloudflare’s Pingora engine**, **Aralez** delivers
|
|||||||
|
|
||||||
### `main.yaml`
|
### `main.yaml`
|
||||||
|
|
||||||
| Key | Example Value | Description |
|
| Key | Example Value | Description |
|
||||||
|----------------------------------|----------------------------|-------------------------------------------------------------------------------------------------|
|
|----------------------------------|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| **threads** | 12 | Number of running daemon threads. Optional, defaults to 1 |
|
| **threads** | 12 | Number of running daemon threads. Optional, defaults to 1 |
|
||||||
| **runuser** | aralez | Optional. Username for running aralez after dropping root privileges (requires launch as root) |
|
| **runuser** | aralez | Optional. Username for running aralez after dropping root privileges (requires launch as root) |
|
||||||
| **rungroup** | aralez | Optional. Group for running aralez after dropping root privileges (requires launch as root) |
|
| **rungroup** | aralez | Optional. Group for running aralez after dropping root privileges (requires launch as root) |
|
||||||
| **daemon** | false | Run in background (boolean) |
|
| **daemon** | false | Run in background (boolean) |
|
||||||
| **upstream_keepalive_pool_size** | 500 | Pool size for upstream keepalive connections |
|
| **upstream_keepalive_pool_size** | 500 | Pool size for upstream keepalive connections |
|
||||||
| **pid_file** | /tmp/aralez.pid | Path to PID file |
|
| **pid_file** | /tmp/aralez.pid | Path to PID file |
|
||||||
| **config_address** | 0.0.0.0:3000 | HTTP API address for pushing upstreams.yaml from remote location |
|
| **config_address** | 0.0.0.0:3000 | HTTP API address for pushing upstreams.yaml from remote location |
|
||||||
| **proxy_tls_grade** | high, medium, unsafe | Grade of TLS ciphers. `high` matches Qualys SSL Labs A+ (defaults to `medium`) |
|
| **proxy_tls_grade** | high, medium, unsafe | Grade of TLS ciphers. `high` matches Qualys SSL Labs A+ (defaults to `medium`) |
|
||||||
| **proxy_address_http** | 0.0.0.0:6193 | Aralez HTTP bind address |
|
| **proxy_address_http** | 0.0.0.0:6193 | Aralez HTTP bind address |
|
||||||
| **proxy_address_tls** | 0.0.0.0:6194 | Aralez HTTPS bind address (Optional) |
|
| **proxy_address_tls** | 0.0.0.0:6194 | Aralez HTTPS bind address (Optional) |
|
||||||
| **proxy_configs** | /etc/aralez/ | Direcotry containing configuration files, must be writeable by user `aralez` |
|
| **proxy_configs** | /etc/aralez/ | Direcotry containing configuration files, must be writeable by user `aralez` |
|
||||||
| **upstreams_conf** | /etc/aralez/upstreams.yaml | Location of the upstreams file |
|
| **upstreams_conf** | /etc/aralez/upstreams.yaml | Location of the upstreams file |
|
||||||
| **access_log** | access | Configure access logging. Values: `access, error` |
|
| **access_log** | access | Configure access logging. Values: `access, error` |
|
||||||
| **log_level** | info | Log level: `info`, `warn`, `error`, `debug`, `trace`, `off` |
|
| **log_level** | info | Log level: `info`, `warn`, `error`, `debug`, `trace`, `off` |
|
||||||
| **log_file** | /full/path/to/aralez.log | Optional, the location of log file. If thi entry does not exist logs will be emitted to stdout. |
|
| **log_file** | /tmp/aralez.log, 20, 5, compress | Optional, the location of log file, file size in megabytes, number of log files to keep, compress files .valueas are separated by comma. Defaults to None, 100, 5, No |
|
||||||
| **hc_method** | HEAD | Healthcheck method: HEAD, GET, POST (UPPERCASE) |
|
| **hc_method** | HEAD | Healthcheck method: HEAD, GET, POST (UPPERCASE) |
|
||||||
| **hc_interval** | 2 | Interval for health checks in seconds |
|
| **hc_interval** | 2 | Interval for health checks in seconds |
|
||||||
| **file_server_folder** | /some/local/folder | Optional. Local folder to serve |
|
| **file_server_folder** | /some/local/folder | Optional. Local folder to serve |
|
||||||
| **file_server_address** | 127.0.0.1:3002 | Optional. Local address for file server |
|
| **file_server_address** | 127.0.0.1:3002 | Optional. Local address for file server |
|
||||||
| **config_api_enabled** | true | Enable/disable remote config push capability |
|
| **config_api_enabled** | true | Enable/disable remote config push capability |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-38
@@ -3,14 +3,9 @@ use crate::utils::lazylock::REVERSE_STORE;
|
|||||||
use crate::utils::state::{is_first_run, mark_not_first_run};
|
use crate::utils::state::{is_first_run, mark_not_first_run};
|
||||||
use crate::utils::structs::*;
|
use crate::utils::structs::*;
|
||||||
use crate::utils::tools::{clone_dashmap, clone_dashmap_into, print_upstreams};
|
use crate::utils::tools::{clone_dashmap, clone_dashmap_into, print_upstreams};
|
||||||
|
use crate::web::logging::log_builder;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use log::LevelFilter;
|
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use log4rs::{
|
|
||||||
append::{console::ConsoleAppender, file::FileAppender},
|
|
||||||
config::{Appender, Config as Log4rsConfig, Root},
|
|
||||||
encode::pattern::PatternEncoder,
|
|
||||||
};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
@@ -327,35 +322,3 @@ pub fn build_headers(path_config: &Option<Vec<String>>, _config: &Configuration,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_builder(conf: &AppConfig, location: &Option<String>) {
|
|
||||||
let log_level = match conf.log_level.as_str() {
|
|
||||||
"info" => LevelFilter::Info,
|
|
||||||
"error" => LevelFilter::Error,
|
|
||||||
"warn" => LevelFilter::Warn,
|
|
||||||
"debug" => LevelFilter::Debug,
|
|
||||||
"trace" => LevelFilter::Trace,
|
|
||||||
"off" => LevelFilter::Off,
|
|
||||||
_ => {
|
|
||||||
println!("Error reading log level, defaulting to: INFO");
|
|
||||||
LevelFilter::Info
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// let pattern = "{d(%Y-%m-%d %H:%M:%S)} {l} {t} - {m}{n}";
|
|
||||||
let pattern = "{d(%Y-%m-%d %H:%M:%S)} {l} {t} - {m}\n";
|
|
||||||
if let Some(location) = location {
|
|
||||||
let file = FileAppender::builder().encoder(Box::new(PatternEncoder::new(pattern))).build(location).unwrap();
|
|
||||||
let config = Log4rsConfig::builder()
|
|
||||||
.appender(Appender::builder().build("file", Box::new(file)))
|
|
||||||
.build(Root::builder().appender("file").build(log_level))
|
|
||||||
.unwrap();
|
|
||||||
log4rs::init_config(config).unwrap();
|
|
||||||
} else {
|
|
||||||
let stdout = ConsoleAppender::builder().encoder(Box::new(PatternEncoder::new(pattern))).build();
|
|
||||||
let config = Log4rsConfig::builder()
|
|
||||||
.appender(Appender::builder().build("stdout", Box::new(stdout)))
|
|
||||||
.build(Root::builder().appender("stdout").build(log_level))
|
|
||||||
.unwrap();
|
|
||||||
log4rs::init_config(config).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+67
-1
@@ -1,5 +1,15 @@
|
|||||||
use crate::utils::metrics::LOGGING_ERRORS;
|
use crate::utils::metrics::LOGGING_ERRORS;
|
||||||
use log::info;
|
use crate::utils::structs::AppConfig;
|
||||||
|
use log::{info, LevelFilter};
|
||||||
|
use log4rs::append::rolling_file::policy::compound::roll::fixed_window::FixedWindowRoller;
|
||||||
|
use log4rs::append::rolling_file::policy::compound::trigger::size::SizeTrigger;
|
||||||
|
use log4rs::append::rolling_file::policy::compound::CompoundPolicy;
|
||||||
|
use log4rs::append::rolling_file::RollingFileAppender;
|
||||||
|
use log4rs::{
|
||||||
|
append::console::ConsoleAppender,
|
||||||
|
config::{Appender, Config as Log4rsConfig, Root},
|
||||||
|
encode::pattern::PatternEncoder,
|
||||||
|
};
|
||||||
use pingora_http::Version;
|
use pingora_http::Version;
|
||||||
use pingora_proxy::Session;
|
use pingora_proxy::Session;
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
@@ -18,6 +28,62 @@ static LOG_SENDER: OnceLock<mpsc::Sender<LogMessage>> = OnceLock::new();
|
|||||||
static ACCESS_LOG: OnceLock<LogLevel> = OnceLock::new();
|
static ACCESS_LOG: OnceLock<LogLevel> = OnceLock::new();
|
||||||
const LOG_BUFFER: usize = 16384;
|
const LOG_BUFFER: usize = 16384;
|
||||||
|
|
||||||
|
pub fn log_builder(conf: &AppConfig, location: &Option<String>) {
|
||||||
|
let log_level = match conf.log_level.as_str() {
|
||||||
|
"info" => LevelFilter::Info,
|
||||||
|
"error" => LevelFilter::Error,
|
||||||
|
"warn" => LevelFilter::Warn,
|
||||||
|
"debug" => LevelFilter::Debug,
|
||||||
|
"trace" => LevelFilter::Trace,
|
||||||
|
"off" => LevelFilter::Off,
|
||||||
|
_ => {
|
||||||
|
println!("Error reading log level, defaulting to: INFO");
|
||||||
|
LevelFilter::Info
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let pattern = "{d(%Y-%m-%d %H:%M:%S)} {l} {t} - {m}\n";
|
||||||
|
|
||||||
|
if let Some(location) = location {
|
||||||
|
let parts: Vec<&str> = location.splitn(4, ',').map(|s| s.trim()).collect();
|
||||||
|
|
||||||
|
let path = parts.get(0).expect("Syntax error, could not get path for log files");
|
||||||
|
let compress = parts.get(3).unwrap_or(&"No");
|
||||||
|
let size_mb: u64 = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(100);
|
||||||
|
let keep: u32 = parts.get(2).and_then(|s| s.parse().ok()).unwrap_or(5);
|
||||||
|
|
||||||
|
let pattern_str = match compress {
|
||||||
|
&"compress" => format!("{}.{{}}.gz", path),
|
||||||
|
_ => format!("{}.{{}}", path),
|
||||||
|
};
|
||||||
|
|
||||||
|
let roller = FixedWindowRoller::builder().build(pattern_str.as_str(), keep).unwrap();
|
||||||
|
let trigger = SizeTrigger::new(size_mb * 1024 * 1024);
|
||||||
|
let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller));
|
||||||
|
|
||||||
|
let file = RollingFileAppender::builder()
|
||||||
|
.encoder(Box::new(PatternEncoder::new(pattern)))
|
||||||
|
.build(path, Box::new(policy))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config = Log4rsConfig::builder()
|
||||||
|
.appender(Appender::builder().build("file", Box::new(file)))
|
||||||
|
.build(Root::builder().appender("file").build(log_level))
|
||||||
|
.unwrap();
|
||||||
|
log4rs::init_config(config).unwrap();
|
||||||
|
info!("Logging to: {}, Max file size: {}mb, Files to keep: {}, compression: {} ", path, size_mb, keep, compress);
|
||||||
|
} else {
|
||||||
|
let stdout = ConsoleAppender::builder().encoder(Box::new(PatternEncoder::new(pattern))).build();
|
||||||
|
|
||||||
|
let config = Log4rsConfig::builder()
|
||||||
|
.appender(Appender::builder().build("stdout", Box::new(stdout)))
|
||||||
|
.build(Root::builder().appender("stdout").build(log_level))
|
||||||
|
.unwrap();
|
||||||
|
log4rs::init_config(config).unwrap();
|
||||||
|
info!("No files are configured, logging to stdout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init_access_log(level_str: &str) {
|
pub fn init_access_log(level_str: &str) {
|
||||||
let level = LogLevel::from_str(level_str);
|
let level = LogLevel::from_str(level_str);
|
||||||
let _ = ACCESS_LOG.set(level);
|
let _ = ACCESS_LOG.set(level);
|
||||||
|
|||||||
+12
-2
@@ -70,8 +70,18 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: mpsc::Sende
|
|||||||
let static_listen = port_is_available("File Server", &address).await;
|
let static_listen = port_is_available("File Server", &address).await;
|
||||||
let static_files = ServeDir::new(folder);
|
let static_files = ServeDir::new(folder);
|
||||||
let static_serve: Router = Router::new().fallback_service(static_files);
|
let static_serve: Router = Router::new().fallback_service(static_files);
|
||||||
// drop(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }));
|
info!("Starting file server on: {}", address);
|
||||||
static_handle = Some(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }))
|
|
||||||
|
static_handle = Some(tokio::spawn(async move {
|
||||||
|
match axum::serve(static_listen, static_serve).await {
|
||||||
|
Ok(o) => info!("File server exited normally: {:?}", o),
|
||||||
|
Err(e) => error!("File server exited: {}", e),
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
// let a = config.file_server_address.to_owned();
|
||||||
|
// let f = config.file_server_folder.to_owned();
|
||||||
|
// drop(tokio::spawn(async move { run_file_server(a, f).await }));
|
||||||
}
|
}
|
||||||
|
|
||||||
let listener = port_is_available("Config API", &config.address).await;
|
let listener = port_is_available("Config API", &config.address).await;
|
||||||
|
|||||||
Reference in New Issue
Block a user