diff --git a/Cargo.lock b/Cargo.lock index 22bad56..a662826 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,10 +159,31 @@ dependencies = [ ] [[package]] -name = "fastrand" -version = "1.8.0" +name = "errno" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -290,6 +311,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "http" version = "0.2.8" @@ -414,6 +441,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.7.1" @@ -456,6 +494,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" + [[package]] name = "lock_api" version = "0.4.9" @@ -542,7 +586,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -554,9 +598,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "openssl" -version = "0.10.45" +version = "0.10.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" +checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" dependencies = [ "bitflags", "cfg-if", @@ -586,11 +630,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.80" +version = "0.9.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -615,7 +658,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "windows-sys 0.45.0", ] @@ -708,12 +751,12 @@ dependencies = [ ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "redox_syscall" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "winapi", + "bitflags", ] [[package]] @@ -736,15 +779,14 @@ dependencies = [ "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls", "serde", "serde_json", "serde_urlencoded", "tokio", - "tokio-native-tls", "tower-service", "url", "wasm-bindgen", @@ -753,9 +795,50 @@ dependencies = [ "winreg", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustix" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "rustocat" -version = "0.1.2" +version = "0.1.9" dependencies = [ "async-trait", "chrono", @@ -796,6 +879,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.8.2" @@ -909,6 +1002,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "syn" version = "1.0.107" @@ -922,16 +1021,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] @@ -1002,9 +1100,9 @@ dependencies = [ [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -1089,6 +1187,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc7ed8ba44ca06be78ea1ad2c3682a43349126c8818054231ee6f4748012aed2" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.3.1" @@ -1204,6 +1308,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1241,13 +1355,13 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", ] [[package]] @@ -1256,7 +1370,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -1265,13 +1388,28 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -1280,42 +1418,84 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 8637a3a..594b424 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustocat" -version = "0.1.2" +version = "0.1.9" edition = "2021" description = "Socat in rust with many less features and a configuration file" license = "ISC" @@ -20,7 +20,7 @@ log = "0.4" fern = "0.6" chrono = "0.4" async-trait = "0.1" -reqwest = { version = "0.11", features = ["json"] } +reqwest = { version = "0.11", features = ["json", "rustls", "hyper-tls"], default-features = false } [profile.release] opt-level = 3 # Optimize for size. diff --git a/Dockerfile b/Dockerfile index e475364..b1ffafc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,9 @@ FROM rust:alpine as builder WORKDIR /app -RUN apk add --no-cache musl-dev +RUN apk add --no-cache musl-dev libssl3 openssl-dev -# This should fetch the index and cache it. This should reduce subsequent builds +# This should fetch the index and cache it. This should reduce the time required of subsequent builds RUN cargo search test COPY Cargo.toml Cargo.lock /app/ @@ -12,11 +12,15 @@ COPY Cargo.toml Cargo.lock /app/ COPY src /app/src + RUN cargo build --release FROM alpine +RUN apk add --no-cache libssl3 COPY --from=builder /app/target/release/rustocat /usr/bin/rustocat -ENTRYPOINT ["rustocat"] +ENTRYPOINT ["/bin/sh"] +CMD [ "-c", "/usr/bin/rustocat" ] + diff --git a/src/config.rs b/src/config.rs index 4a458a9..c15333f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use std::{fs::File, path::Path}; +use log::info; use serde::Deserialize; use tokio::signal::unix::Signal; @@ -15,6 +16,8 @@ pub struct Target { #[derive(Debug, Deserialize)] pub struct Config { pub consul: Option, + pub consul_http_addr: Option, + pub consul_http_token: Option, mappings: Vec, } @@ -76,11 +79,13 @@ impl FileConfigProvider { #[async_trait::async_trait] impl ConfigProvider for FileConfigProvider { async fn get_targets(&self) -> Result> { + info!("Getting targets from file"); let config = self.load_config()?; return Ok(config.mappings); } async fn wait_for_change(&mut self) -> Result<()> { + info!("Waiting for file config change (SIGHUP)"); self.sighup_stream.recv().await; return Ok(()); diff --git a/src/consul.rs b/src/consul.rs index 41011eb..505b8b5 100644 --- a/src/consul.rs +++ b/src/consul.rs @@ -2,10 +2,14 @@ use std::collections::HashMap; +use log::debug; +use log::info; +use log::trace; use log::warn; use reqwest::header::HeaderMap; use serde::{Deserialize, Serialize}; +use crate::config::Config; use crate::config::ConfigProvider; use crate::config::Target; @@ -17,9 +21,13 @@ pub struct ConsulConfigProvider { } impl ConsulConfigProvider { - pub fn new() -> Self { + pub fn new(config: Option<&Config>) -> Self { Self { - consul_config: ConsulConfig::from_env(), + consul_config: if let Some(config) = config { + ConsulConfig::from_config_or_env(config) + } else { + ConsulConfig::from_env() + }, interval: tokio::time::interval(tokio::time::Duration::from_secs(10)), } } @@ -28,16 +36,21 @@ impl ConsulConfigProvider { #[async_trait::async_trait] impl ConfigProvider for ConsulConfigProvider { async fn get_targets(&self) -> Result> { + info!("Getting targets from consul"); let mut targets: Vec = Vec::new(); + debug!("Calling consul_get_services"); let services = consul_get_services(&self.consul_config).await?; // Find consul services and tags // Format of tags: rustocat:udp:port // rustocat:tcp:port + + debug!("Iterating over services: {:?}", services); for (name, tags) in services { for tag in tags { if tag.starts_with("rustocat") { + trace!("Found rustocat tag: {}", tag); let parts = tag.split(":").collect::>(); if parts.len() != 3 { warn!("Invalid tag: {} on service {}", tag, name); @@ -45,17 +58,19 @@ impl ConfigProvider for ConsulConfigProvider { } let port = parts[2]; + trace!("Getting nodes for service: {}", name); let nodes = consul_get_service_nodes(&self.consul_config, &name).await?; let mut t = vec![]; for node in nodes { - t.push(format!("{}:{}", node.Service.Address, node.Service.Port)); + t.push(format!("{}:{}", node.ServiceAddress, node.ServicePort)); } let target = Target { udp: Some(parts[1] == "udp"), source: format!("0.0.0.0:{}", port), targets: t, }; + trace!("Adding target: {:?}", target); targets.push(target); } } @@ -65,6 +80,7 @@ impl ConfigProvider for ConsulConfigProvider { } async fn wait_for_change(&mut self) -> Result<()> { + info!("Waiting for consul config change"); self.interval.tick().await; Ok(()) @@ -74,7 +90,7 @@ impl ConfigProvider for ConsulConfigProvider { async fn consul_get_services(config: &ConsulConfig) -> Result>> { let mut headers = HeaderMap::new(); if let Some(token) = config.token.clone() { - headers.insert("X-Consul-Token", token.parse().unwrap()); + headers.insert("X-Consul-Token", token.parse()?); } return Ok(reqwest::Client::new() @@ -86,21 +102,23 @@ async fn consul_get_services(config: &ConsulConfig) -> Result Result> { +async fn consul_get_service_nodes(config: &ConsulConfig, service: &str) -> Result> { let mut headers = HeaderMap::new(); if let Some(token) = config.token.clone() { - headers.insert("X-Consul-Token", token.parse().unwrap()); + headers.insert("X-Consul-Token", token.parse()?); } + trace!( + "Calling consul_get_service_nodes: {}/v1/catalog/service/{service}", + config.baseurl + ); + return Ok(reqwest::Client::new() - .get(format!("{}/v1/catalog/services/{service}", config.baseurl)) + .get(format!("{}/v1/catalog/service/{service}", config.baseurl)) .headers(headers) .send() .await? - .json::>() + .json::>() .await?); } @@ -136,7 +154,8 @@ struct HealthCheck { struct Node { ID: String, Node: String, - Address: String, + ServiceAddress: String, + ServicePort: u16, Datacenter: Option, TaggedAddresses: Option>, Meta: Option>, @@ -166,4 +185,20 @@ impl ConsulConfig { token: option_env!("CONSUL_HTTP_TOKEN").map(|s| s.to_string()), } } + + fn from_config_or_env(config: &Config) -> Self { + let baseurl = match config.consul_http_addr { + Some(ref s) => s.clone(), + None => option_env!("CONSUL_HTTP_ADDR") + .expect("CONSUL_HTTP_ADDR not set") + .to_string(), + }; + + let token = match config.consul_http_token { + Some(ref s) => Some(s.clone()), + None => option_env!("CONSUL_HTTP_TOKEN").map(|s| s.to_string()), + }; + + Self { baseurl, token } + } } diff --git a/src/main.rs b/src/main.rs index 98db714..464a381 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod udp; #[cfg(feature = "consul")] mod consul; +use config::ConfigProvider; use log::{debug, error, info, warn}; use std::collections::{HashMap, HashSet}; use std::error::Error; @@ -39,15 +40,18 @@ async fn main() -> Result<()> { .chain(std::io::stdout()) .apply()?; - let mut listeners: HashMap = HashMap::new(); + let listeners: HashMap = HashMap::new(); let text_config_provider = config::FileConfigProvider::new(); - let mut target_provider: Box = { + let target_provider: Box = { #[cfg(feature = "consul")] { let cfg = text_config_provider.load_config()?; + info!("Loaded yaml config"); if cfg.consul.is_some() && cfg.consul.unwrap() { - let consul_config_provider = consul::ConsulConfigProvider::new(); + info!("Using consul config provider"); + let consul_config_provider = consul::ConsulConfigProvider::new(Some(&cfg)); + info!("Loaded consul config provider"); Box::new(consul_config_provider) } else { Box::new(text_config_provider) @@ -55,9 +59,28 @@ async fn main() -> Result<()> { } #[cfg(not(feature = "consul"))] - Box::new(text_config_provider) + { + let cfg = Box::new(text_config_provider); + info!("Loaded yaml config"); + cfg + } }; + match run_loop(target_provider, listeners).await { + Ok(_) => {} + Err(e) => { + error!("Error in run loop: {}", e); + info!("Exiting"); + } + } + + Ok(()) +} + +async fn run_loop( + mut target_provider: Box, + mut listeners: HashMap, +) -> Result<()> { loop { let mappings = target_provider.get_targets().await?; let mut required_listeners: HashSet = HashSet::new(); @@ -151,6 +174,6 @@ async fn main() -> Result<()> { } target_provider.wait_for_change().await?; - info!("Recevied SIGHUP, reloading config!"); + info!("Reloading config!"); } }