9 Commits

Author SHA1 Message Date
Ara Sadoyan
bd315106b9 Merge pull request #41 from Taqman-probe/fix/TcpListener-bind
Fix TcpListener binding and port availability check
2026-06-07 11:57:06 +02:00
Ara Sadoyan
3ba2ed33ae cargo.toml 2026-06-07 11:38:50 +02:00
Taqman-probe
c09efab9fd prevent panic when parsing invalid address without port 2026-06-07 00:47:43 +09:00
Taqman-probe
735d605f6d prevent panic when parsing invalid address without port 2026-06-06 22:32:32 +09:00
Ara Sadoyan
6773d0f502 Cargo 2026-06-04 19:12:50 +02:00
Ara Sadoyan
a8cb727da5 Cargo Licence 2026-06-04 18:39:02 +02:00
Ara Sadoyan
f81194aee7 Cargo Licence 2026-06-04 18:38:47 +02:00
Ara Sadoyan
0f09a2e02b Roll back to MiMalloc 2026-06-04 18:14:22 +02:00
Ara Sadoyan
27aca0a3a5 Roll back to MiMalloc 2026-06-04 17:03:19 +02:00
9 changed files with 214 additions and 141 deletions

6
.gitignore vendored
View File

@@ -8,10 +8,14 @@
/docs/ /docs/
/docs /docs
/etc /etc
/etc/
etc
.etc/
assets/
assets
/target/ /target/
*.iml *.iml
.idea/ .idea/
.etc/
*.ipr *.ipr
*.iws *.iws
/out/ /out/

60
Cargo.lock generated
View File

@@ -127,7 +127,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]] [[package]]
name = "aralez" name = "aralez"
version = "0.9.2" version = "0.92.9"
dependencies = [ dependencies = [
"ahash", "ahash",
"arc-swap", "arc-swap",
@@ -141,6 +141,7 @@ dependencies = [
"jsonwebtoken", "jsonwebtoken",
"log", "log",
"log4rs", "log4rs",
"mimalloc",
"moka", "moka",
"notify", "notify",
"pingora", "pingora",
@@ -161,8 +162,6 @@ dependencies = [
"sha2 0.11.0", "sha2 0.11.0",
"signal-hook", "signal-hook",
"subtle", "subtle",
"tikv-jemalloc-ctl",
"tikv-jemallocator",
"tokio", "tokio",
"tonic", "tonic",
"tower-http", "tower-http",
@@ -1917,6 +1916,15 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libmimalloc-sys"
version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "libyml" name = "libyml"
version = "0.0.5" version = "0.0.5"
@@ -2043,6 +2051,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "mimalloc"
version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
dependencies = [
"libmimalloc-sys",
]
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.3.17" version = "0.3.17"
@@ -2428,12 +2445,6 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]] [[package]]
name = "pem" name = "pem"
version = "3.0.6" version = "3.0.6"
@@ -3880,37 +3891,6 @@ dependencies = [
"trackable", "trackable",
] ]
[[package]]
name = "tikv-jemalloc-ctl"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a184c43b8ab2f41df2733b55556e3f5f632f4aeaa205b1bb018f574b7f5f142"
dependencies = [
"libc",
"paste",
"tikv-jemalloc-sys",
]
[[package]]
name = "tikv-jemalloc-sys"
version = "0.7.1+5.3.1-0-g81034ce1f1373e37dc865038e1bc8eeecf559ce8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a2825c78386b4ae0314074867860ba9577875de945f05992c38815cbec327f0"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "tikv-jemallocator"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "249f09e49ab1609436f34c776e84231bead18d6a955f119f939bdc1d847561bd"
dependencies = [
"libc",
"tikv-jemalloc-sys",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.47" version = "0.3.47"

View File

@@ -1,7 +1,11 @@
[package] [package]
name = "aralez" name = "aralez"
version = "0.9.2" version = "0.92.9"
edition = "2021" edition = "2021"
license = "Apache-2.0"
description = "Reverse proxy built on top of Cloudflare's Pingora"
exclude = ["etc/*"]
repository = "https://github.com/sadoyan/aralez"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3
@@ -46,8 +50,6 @@ 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"
#mimalloc = { version = "0.1.52", default-features = false } mimalloc = { version = "0.1.52", default-features = false }
tikv-jemallocator = "0.7.0"
tikv-jemalloc-ctl = { version = "0.7.0", features = ["stats"] }
signal-hook = "0.4.4" signal-hook = "0.4.4"
sd-notify = "0.5.0" sd-notify = "0.5.0"

View File

@@ -9,13 +9,23 @@
Aralez is a high-performance Rust reverse proxy with zero-configuration automatic protocol handling, TLS, and upstream management, Aralez is a high-performance Rust reverse proxy with zero-configuration automatic protocol handling, TLS, and upstream management,
featuring Consul and Kubernetes integration for dynamic pod discovery and health-checked routing, acting as a lightweight ingress-style proxy. featuring Consul and Kubernetes integration for dynamic pod discovery and health-checked routing, acting as a lightweight ingress-style proxy.
--- ---
What Aralez means ? What Aralez means ?
**Aralez = Արալեզ** <ins>Named after the legendary Armenian guardian spirit, winged dog-like creature, that descend upon fallen heroes to lick their wounds and resurrect them</ins>. **Aralez = Արալեզ** <ins>Named after the legendary Armenian guardian spirit, winged dog-like creature, that descend upon fallen heroes to lick their wounds and resurrect them</ins>.
Built on Rust, on top of **Cloudflares Pingora engine**, **Aralez** delivers world-class performance, security and scalability — right out of the box. Built on Rust, on top of **Cloudflares Pingora engine**, **Aralez** delivers world-class performance, security and scalability — right out of the box.
[![Buy Me A Coffee](https://img.shields.io/badge/☕-Buy%20me%20a%20coffee-orange)](https://www.buymeacoffee.com/sadoyan) ---
## Links
- [**Documentation**](https://aralez.rs) : The manual you should read
- [**Downloads**](https://github.com/sadoyan/aralez/releases) : Binary downloads
- [**Issues**](https://github.com/sadoyan/aralez/issues) : Issues and requests
- [**Crates**](https://crates.io/crates/aralez) : The Rust crate registry
- [**DockerHUB**](https://hub.docker.com/r/sadoyan/aralez) : DockerHUB official repository
- [**GitHUB Packages**](https://github.com/sadoyan/aralez/pkgs/container/aralez) : GitHUB ghcr.io images
--- ---
@@ -107,6 +117,9 @@ For getting the best performance on newer hardware use `aralez-x86_64-*.gz`.
```shell ```shell
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez:compat
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 ghcr.io/sadoyan/aralez:latest
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 ghcr.io/sadoyan/aralez:compat
``` ```
**Dockerfile :** **Dockerfile :**
@@ -554,10 +567,3 @@ The results show requests per second performed by Load balancer. You can see 3 b
1. Requests via http1.1 to plain text endpoint. 1. Requests via http1.1 to plain text endpoint.
2. Requests to via http2 to SSL endpoint. 2. Requests to via http2 to SSL endpoint.
3. Mixed workload with plain http1.1 and htt2 SSL. 3. Mixed workload with plain http1.1 and htt2 SSL.
## Links
- [**Documentation**](https://aralez.rs) : The manual you should read
- [**Downloads**](https://github.com/sadoyan/aralez/releases) : Binary downloads
- [**Issues**](https://github.com/sadoyan/aralez/issues) : Issues and requests

View File

@@ -2,22 +2,22 @@
threads: 12 # Number of daemon threads default setting threads: 12 # Number of daemon threads default setting
#runuser: pastor # Username for running aralez after dropping root privileges, requires program to start as root #runuser: pastor # Username for running aralez after dropping root privileges, requires program to start as root
#rungroup: pastor # Group for running aralez after dropping root privileges, requires program to start as root #rungroup: pastor # Group for running aralez after dropping root privileges, requires program to start as root
daemon: false # Run in background #daemon: false # Run in background
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
error_log: /tmp/aralez_err.log # Path to error log #error_log: /tmp/aralez_err.log # Path to error log
upgrade_sock: /tmp/aralez.sock # Path to socket file upgrade_sock: /tmp/aralez.sock # Path to socket file
config_api_enabled: true # Boolean to enable/disable remote config push capability. config_api_enabled: true # Boolean to enable/disable remote config push capability.
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_address_http: 0.0.0.0:6193 # Proxy HTTP bind address proxy_address_http: 0.0.0.0:6193 # Proxy HTTP bind address
proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address
proxy_configs: /opt/Rust/Projects/asyncweb/etc # Mandatory if proxy_address_tls set, should contain a certificate and key files strictly in a format {NAME}.crt, {NAME}.key. proxy_configs: /opt/Rust/Projects/asyncweb/etc # Mandatory if proxy_address_tls set, should contain a certificate and key files strictly in a format {NAME}.crt, {NAME}.key.
proxy_tls_grade: high # Grade of TLS suite for proxy (high, medium, unsafe), matching grades of Qualys SSL Labs proxy_tls_grade: high # Grade of TLS suite for proxy (high, medium, unsafe), matching grades of Qualys SSL Labs
upstreams_conf: /opt/Rust/Projects/asyncweb/etc/upstreams.yaml # the location of upstreams file upstreams_conf: /opt/Rust/Projects/asyncweb/etc/upstreams.yaml # the location of upstreams file
#file_server_folder: /opt/storage # Optional, local folder to serve file_server_folder: /tmp/gazan # Optional, local folder to serve
#file_server_address: 127.0.0.1:3002 # Optional, Local address for file server. Can set as upstream for public access. file_server_address: 127.0.0.1:3002 # Optional, Local address for file server. Can set as upstream for public access.
log_level: info # info, warn, error, debug, trace, off log_level: info # info, warn, error, debug, trace, off
log_file: /tmp/aralez.log # Optional, the location of log file. If this entry does not exist logs will be emitted to stdout. #log_file: /tmp/aralez.log # Optional, the location of log file. If this entry does not exist logs will be emitted to stdout.
hc_method: HEAD # Healthcheck method (HEAD, GET, POST are supported) UPPERCASE hc_method: HEAD # Healthcheck method (HEAD, GET, POST are supported) UPPERCASE
hc_interval: 2 #Interval for health checks in seconds hc_interval: 2 #Interval for health checks in seconds
#master_key: 910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774 # Mater key for working with API server and JWT Secret #master_key: 910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774 # Mater key for working with API server and JWT Secret

View File

@@ -1,49 +1,47 @@
# The file under watch and hot reload, changes are applied immediately, no need to restart or reload. # The file under watch and hot reload, changes are applied immediately, no need to restart or reload.
provider: "file" # "file" "consul" "kubernetes" provider: "file" # "file" "consul" "kubernetes"
sticky_sessions: 8600 sticky_sessions: 172000
to_https: false to_https: false
rate_limit: 300 rate_limit: 500000
x4xx_limit: 200 x4xx_limit: 100000
server_headers: #server_headers:
- "X-Forwarded-Proto:https" # - "Y-Global-Something: Yes this is something"
- "X-Forwarded-Port:443" #client_headers:
client_headers: # - "Access-Control-Allow-Origin:*"
- "Access-Control-Allow-Origin:*" # - "Access-Control-Allow-Methods:POST, GET, OPTIONS"
- "Access-Control-Allow-Methods:POST, GET, OPTIONS" # - "Access-Control-Max-Age:86400"
- "Access-Control-Max-Age:86400" # - "Strict-Transport-Security:max-age=31536000; includeSubDomains; preload"
#authorization: #authorization:
# type: "jwt"
# creds: "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774"
# type: "basic" # type: "basic"
# creds: "username:Pa$$w0rd" # data: "root:toor"
# type: "jwt"
# data: "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774"
# type: "apikey" # type: "apikey"
# creds: "5ecbf799-1343-4e94-a9b5-e278af5cd313-56b45249-1839-4008-a450-a60dc76d2bae" # data: "5ecbf799-1343-4e94-a9b5-e278af5cd313-56b45249-1839-4008-a450-a60dc76d2bae"
consul: consul:
servers: servers:
- "http://192.168.1.199:8500" - "http://consul1:8500"
- "http://192.168.1.200:8500"
- "http://192.168.1.201:8500"
services: # hostname: The hostname to access the proxy server, upstream : The real service name in Consul database. services: # hostname: The hostname to access the proxy server, upstream : The real service name in Consul database.
- hostname: "webapi-service" - hostname: "nconsul"
upstream: "webapi-service-health" upstream: "nginx-consul-NginX-health"
path: "/one" path: "/one"
client_headers: client_headers:
- "X-Some-Thing:Yaaaaaaaaaaaaaaa" - "X-Some-Thing:Yaaaaaaaaaaaaaaa"
- "X-Proxy-From:Aralez" - "X-Proxy-From:Aralez"
rate_limit: 1 rate_limit: 1
to_https: false to_https: false
- hostname: "webapi-service" - hostname: "nconsul"
upstream: "webapi-service-health" upstream: "nginx-consul-NginX-health"
path: "/" path: "/"
token: "8e2db809-845b-45e1-8b47-2c8356a09da0-a4370955-18c2-4d6e-a8f8-ffcc0b47be81" # Consul server access token, If Consul auth is enabled token: "8e2db809-845b-45e1-8b47-2c8356a09da0-a4370955-18c2-4d6e-a8f8-ffcc0b47be81" # Consul server access token, If Consul auth is enabled
kubernetes: kubernetes:
servers: servers:
- "192.168.1.55:443" #For testing only, overrides with KUBERNETES_SERVICE_HOST : KUBERNETES_SERVICE_PORT_HTTPS env variables. - "172.16.0.11:5443" # Gets KUBERNETES_SERVICE_HOST : KUBERNETES_SERVICE_PORT_HTTPS env variables.
services: services:
- hostname: "webapi-service" - hostname: "api-service-v2"
upstream: "api-service-v2"
path: "/" path: "/"
upstream: "webapi-service" - hostname: "api-service-v2"
- hostname: "webapi-service"
upstream: "console-service" upstream: "console-service"
path: "/one" path: "/one"
client_headers: client_headers:
@@ -51,71 +49,146 @@ kubernetes:
- "X-Proxy-From:Aralez" - "X-Proxy-From:Aralez"
rate_limit: 100 rate_limit: 100
to_https: false to_https: false
- hostname: "webapi-service" - hostname: "api-service-v2"
upstream: "rambul-service" upstream: "feed-fanout-service"
path: "/two" path: "/two"
- hostname: "websocket-service" - hostname: "websocket-service"
upstream: "websocket-service" upstream: "websocket-service"
path: "/" path: "/"
tokenpath: "/path/to/kubetoken.txt" #If not set, will default to /var/run/secrets/kubernetes.io/serviceaccount/token tokenpath: "/opt/Rust/Projects/asyncweb/etc/kubetoken.txt" # Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token
upstreams: upstreams:
myip.mydomain.com: myip.netangels.net:
paths: paths:
"/": "/":
rate_limit: 200 # rate_limit: 50
x4xx_limit: 100 # x4xx_limit: 100
to_https: false # to_https: false
# authorization:
# type: "basic"
# data: "root:toor"
server_headers:
- "Y-Proxy-Server-Some:Yaaaaaaaaaaaaaaa"
- "Y-Proxy-Server-From:Aralez"
- "Y-Proxy-Server-Vers:Aralez v0.89"
client_headers: client_headers:
- "X-Proxy-From:Aralez" - "X-Proxy-From:Aralezzzzzzzzzzz"
- "X-Hopar-From:Hopaaaaaaaaaaaar"
- "X-Proxy-Some:X-Proxy-Somebody"
servers: servers:
- "127.0.0.1:8000" - "127.0.0.1:8000"
- "127.0.0.2:8000" - "127.0.0.2:8000"
- "127.0.0.3:8000" - "127.0.0.3:8000"
- "127.0.0.4:8000" - "127.0.0.4:8000"
- "127.0.0.5:8000" - "127.0.0.5:8000"
- "192.168.1.1:8000"
"/ping": "/ping":
authorization: # Will be ignored if global authentication is enabled.
type: "basic"
creds: "admin:admin"
to_https: false to_https: false
server_headers:
- "X-Forwarded-Proto:https"
- "X-Forwarded-Port:443"
client_headers: client_headers:
- "X-Some-Thing:Yaaaaaaaaaaaaaaa" - "X-Some-Thing:Yaaaaaaaaaaaaaaa"
- "X-Proxy-From:Aralez" - "X-Proxy-From:Aralez"
servers: servers:
- "127.0.0.1:8000" - "127.0.0.1:8000"
- "127.0.0.2:8000" - "127.0.0.2:8000"
"/draw": "/pong":
servers:
- "192.168.1.1:8000"
polo.mydomain.com:
paths:
"/":
to_https: false to_https: false
client_headers: client_headers:
- "X-Some-Thing:Yaaaaaaaaaaaaaaa" - "X-Some-Thing:Yaaaaaaaaaaaaaaa"
- "X-Proxy-From:Aralez"
servers: servers:
- "192.168.1.1:8000"
- "192.168.1.10:8000"
- "127.0.0.1:8000" - "127.0.0.1:8000"
- "127.0.0.2:8000" "/secret":
- "127.0.0.3:8000" authorization:
- "127.0.0.4:8000" type: "forward"
apt.mydomain.com: data: "http://192.168.1.1:8899/admin/login"
#data: "https://netangels.net/admin/login"
servers:
- "192.168.1.10:8000"
netangels.net:
paths: paths:
"/": "/":
redirect_to: "https://www.netangels.net:6194"
servers: servers:
- "192.168.1.10:443" - "192.168.1.1:80"
www.netangels.net:
paths:
"/":
to_https: true
servers:
- "192.168.1.1:80"
apt.netangels.net:
paths:
"/":
server_headers:
- "Y-Global-Something: Yes this is something"
client_headers:
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
rate_limit: 60
x4xx_limit: 30
#authorization:
# type: "jwt"
# data: "SOMETHING"
servers:
- "127.0.0.1:8000"
- "127.0.0.2:8000"
"/.well-known/acme-challenge": "/.well-known/acme-challenge":
healthcheck: false healthcheck: false
servers: servers:
- "127.0.0.1:8001" - "127.0.0.1:8001"
rdr.mydomain.com: "/400":
paths: rate_limit: 4
"/": x4xx_limit: 2
redirect_to: "https://som.other.domain:6194" servers:
- "192.168.1.1:8899"
"/500":
healthcheck: false healthcheck: false
servers: servers:
- "127.0.0.1:8080" - "192.168.1.1:8899"
# grafanalocal:
# paths:
# "/":
# healthcheck: false
# servers:
# - "95.211.203.222:443"
# "/.well-known/acme-challenge":
# healthcheck: false
# servers:
# - "127.0.0.1:8001"
localpost:
paths:
"/":
to_https: true
servers:
- "127.0.0.1:9000"
# 192.168.177.2:
# paths:
# "/":
# servers:
# - "127.0.0.1:8000"
ara.matyan.org:
paths:
"/":
servers:
- "127.0.0.1:8000"
"/.well-known/acme-challenge":
healthcheck: false
servers:
- "127.0.0.1:3000"
aro.matyan.org:
paths:
"/":
servers:
- "127.0.0.1:8000"
"/.well-known/acme-challenge":
healthcheck: false
servers:
- "127.0.0.1:3000"
DEFAUwLT:
paths:
"/":
healthcheck: false
servers:
- "127.0.0.1:3000"
"/.well-known/acme-challenge":
healthcheck: false
servers:
- "127.0.0.1:3000"

View File

@@ -1,14 +1,16 @@
use tikv_jemallocator::Jemalloc;
mod tls; mod tls;
mod utils; mod utils;
mod web; mod web;
#[global_allocator] #[global_allocator]
static ALLOC: Jemalloc = Jemalloc; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
// static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
// pub static A: CountingAllocator = CountingAllocator; // pub static A: CountingAllocator = CountingAllocator;
fn main() { fn main() {
if std::env::args().any(|a| a == "--version" || a == "-v") {
println!("aralez {}", env!("CARGO_PKG_VERSION"));
std::process::exit(0);
}
web::start::run(); web::start::run();
} }

View File

@@ -5,7 +5,6 @@ use prometheus::{register_histogram, register_int_counter, register_int_counter_
use std::sync::Arc; use std::sync::Arc;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::time::Duration; use std::time::Duration;
use tikv_jemalloc_ctl::{epoch, stats};
pub struct MetricTypes { pub struct MetricTypes {
pub method: Method, pub method: Method,
@@ -66,9 +65,17 @@ pub fn calc_metrics(metric_types: &MetricTypes) {
RESPONSE_LATENCY.observe(metric_types.latency.as_secs_f64()); RESPONSE_LATENCY.observe(metric_types.latency.as_secs_f64());
} }
pub fn get_memory_usage() -> usize { pub(crate) fn get_memory_usage() -> usize {
epoch::mib().unwrap().advance().unwrap(); // refresh stats std::fs::read_to_string("/proc/self/status")
stats::allocated::mib().unwrap().read().unwrap() // bytes allocated .ok()
.and_then(|s| {
s.lines()
.find(|l| l.starts_with("VmRSS:"))
.and_then(|l| l.split_whitespace().nth(1))
.and_then(|v| v.parse::<usize>().ok())
})
.unwrap_or(0)
* 1024
} }
pub fn get_open_files() -> usize { pub fn get_open_files() -> usize {

View File

@@ -18,6 +18,8 @@ use prometheus::{gather, Encoder, TextEncoder};
use serde::Serialize; use serde::Serialize;
use signal_hook::{consts::SIGQUIT, iterator::Signals}; use signal_hook::{consts::SIGQUIT, iterator::Signals};
use std::collections::HashMap; use std::collections::HashMap;
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::net::TcpListener; use tokio::net::TcpListener;
@@ -67,16 +69,14 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: Sender<Conf
let mut static_handle: Option<tokio::task::JoinHandle<()>> = None; let mut static_handle: Option<tokio::task::JoinHandle<()>> = None;
if let (Some(address), Some(folder)) = (&config.file_server_address, &config.file_server_folder) { if let (Some(address), Some(folder)) = (&config.file_server_address, &config.file_server_folder) {
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);
let static_listen = TcpListener::bind(address).await.unwrap();
// drop(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() })); // drop(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }));
static_handle = Some(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() })) static_handle = Some(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }))
} }
port_is_available("Config API", &config.address).await; let listener = port_is_available("Config API", &config.address).await;
let listener = TcpListener::bind(config.address.clone()).await.unwrap();
info!("Starting the API server on: {}", config.address); info!("Starting the API server on: {}", config.address);
let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() }); let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() });
@@ -227,20 +227,19 @@ async fn status(State(st): State<AppState>, Query(params): Query<HashMap<String,
.unwrap() .unwrap()
} }
pub async fn port_is_available(name: &str, address: &str) { pub async fn port_is_available(name: &str, address: &str) -> TcpListener {
let addr_port = address.split(":").collect::<Vec<&str>>(); let addr = SocketAddr::from_str(address)
.unwrap_or_else(|e| panic!("{}: Invalid address format: {:?}", name, e));
let t = Duration::from_secs(2); let t = Duration::from_secs(2);
let mut a = addr_port[0]; //if addr.ip() == IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
if address == "0.0.0.0" { // addr.set_ip(IpAddr::V4(Ipv4Addr::LOCALHOST));
a = "127.0.0.1"; //}
} let p = addr.port();
let p = addr_port[1].parse::<u16>().unwrap();
loop { loop {
match TcpListener::bind((a, p)).await { match TcpListener::bind(addr).await {
Ok(_) => { Ok(listener) => {
break; return listener;
} }
Err(_) => { Err(_) => {
warn!("{} port is not available: {} will try again in {:?}", name, p, t); warn!("{} port is not available: {} will try again in {:?}", name, p, t);