Env config
All checks were successful
CI / Check typos (push) Successful in 8s
CI / Check links (push) Successful in 6s
CI / Clippy (push) Successful in 51s
CI / Build and test (push) Successful in 1m7s
CI / Build container (push) Successful in 45s
CI / Deploy on waypoint (push) Successful in 42s
All checks were successful
CI / Check typos (push) Successful in 8s
CI / Check links (push) Successful in 6s
CI / Clippy (push) Successful in 51s
CI / Build and test (push) Successful in 1m7s
CI / Build container (push) Successful in 45s
CI / Deploy on waypoint (push) Successful in 42s
This commit is contained in:
@@ -17,3 +17,4 @@ tokio = { workspace = true }
|
||||
axum = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
||||
106
crates/bin/webpage/src/config.rs
Normal file
106
crates/bin/webpage/src/config.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use serde::Deserialize;
|
||||
use std::num::NonZeroUsize;
|
||||
use toolbox::{
|
||||
env::load_env,
|
||||
logging::{LogFilterPreset, LoggingFormat, LoggingInitializer, LoggingTarget, LokiConfig},
|
||||
};
|
||||
use tracing::info;
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct WebpageConfig {
|
||||
#[serde(default)]
|
||||
pub loglevel: LogFilterPreset,
|
||||
|
||||
#[serde(default)]
|
||||
pub logformat: LoggingFormat,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub loki: Option<LokiConfig>,
|
||||
|
||||
// How many threads tokio should use
|
||||
pub runtime_threads: Option<NonZeroUsize>,
|
||||
pub blocking_threads: Option<NonZeroUsize>,
|
||||
}
|
||||
|
||||
impl WebpageConfig {
|
||||
pub fn load() -> Self {
|
||||
let config_res = match load_env::<WebpageConfig>() {
|
||||
Ok(x) => x,
|
||||
|
||||
#[expect(clippy::print_stdout)]
|
||||
Err(err) => {
|
||||
println!("Error while loading .env: {err}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let config = config_res.get_config().clone();
|
||||
|
||||
info!(message = "Config loaded");
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn init_logging_noloki(&self) {
|
||||
let res = LoggingInitializer {
|
||||
app_name: "betalupi-webpage",
|
||||
loki: None,
|
||||
preset: self.loglevel,
|
||||
target: LoggingTarget::Stderr {
|
||||
format: self.logformat,
|
||||
},
|
||||
}
|
||||
.initialize();
|
||||
|
||||
if let Err(e) = res {
|
||||
#[expect(clippy::print_stderr)]
|
||||
for e in e.chain() {
|
||||
eprintln!("{e}");
|
||||
}
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// Must be run inside a tokio context,
|
||||
/// use `init_logging_noloki` if you don't have async.
|
||||
pub async fn init_logging(&self) {
|
||||
let res = LoggingInitializer {
|
||||
app_name: "betalupi-webpage",
|
||||
loki: self.loki.clone(),
|
||||
preset: self.loglevel,
|
||||
target: LoggingTarget::Stderr {
|
||||
format: self.logformat,
|
||||
},
|
||||
}
|
||||
.initialize();
|
||||
|
||||
if let Err(e) = res {
|
||||
#[expect(clippy::print_stderr)]
|
||||
for e in e.chain() {
|
||||
eprintln!("{e}");
|
||||
}
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_runtime(&self) -> tokio::runtime::Runtime {
|
||||
let mut rt = tokio::runtime::Builder::new_multi_thread();
|
||||
rt.enable_all();
|
||||
if let Some(threads) = self.runtime_threads {
|
||||
rt.worker_threads(threads.into());
|
||||
}
|
||||
|
||||
if let Some(threads) = self.blocking_threads {
|
||||
rt.max_blocking_threads(threads.into());
|
||||
}
|
||||
|
||||
#[expect(clippy::unwrap_used)]
|
||||
let rt = rt.build().unwrap();
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
use clap::Parser;
|
||||
use toolbox::logging::{LogCliVQ, LoggingFormat, LoggingInitializer, LoggingTarget};
|
||||
use toolbox::logging::LogCliVQ;
|
||||
use tracing::error;
|
||||
|
||||
use crate::cmd::Command;
|
||||
use crate::{cmd::Command, config::WebpageConfig};
|
||||
|
||||
mod cmd;
|
||||
mod config;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about, long_about = None, styles=toolbox::cli::clap_styles())]
|
||||
@@ -20,36 +21,19 @@ struct Cli {
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CmdContext {}
|
||||
pub struct CmdContext {
|
||||
config: WebpageConfig,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
let ctx = CmdContext {
|
||||
config: WebpageConfig::load(),
|
||||
};
|
||||
|
||||
{
|
||||
let res = LoggingInitializer {
|
||||
app_name: "webpage",
|
||||
loki: None,
|
||||
preset: cli.vq.into_preset(),
|
||||
target: LoggingTarget::Stderr {
|
||||
format: LoggingFormat::Ansi,
|
||||
},
|
||||
}
|
||||
.initialize();
|
||||
|
||||
if let Err(e) = res {
|
||||
#[expect(clippy::print_stderr)]
|
||||
for e in e.chain() {
|
||||
eprintln!("{e}");
|
||||
}
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
let ctx = CmdContext {};
|
||||
let res = cli.command.run(ctx).await;
|
||||
let rt = ctx.config.make_runtime();
|
||||
rt.block_on(ctx.config.init_logging());
|
||||
let res = rt.block_on(cli.command.run(ctx));
|
||||
|
||||
if let Err(e) = res {
|
||||
for e in e.chain() {
|
||||
|
||||
Reference in New Issue
Block a user