Files
nx9-chronoseal-rs/server/src/main.rs
T
2026-05-29 14:50:45 +05:30

151 lines
5.2 KiB
Rust

mod cleanup;
mod cli;
mod config;
mod crypto;
mod errors;
mod fingerprint;
mod middleware;
mod output;
mod ratelimit;
mod routes;
mod runtime;
mod session;
mod storage;
mod trust;
mod vm;
use clap::{CommandFactory, Parser};
use cli::{Cli, Command, ConfigCommand, GenerateCommand};
use config::Config;
use std::path::PathBuf;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
#[tokio::main]
async fn main() {
if let Err(err) = try_main().await {
eprintln!("chronoseal: {err}");
std::process::exit(1);
}
}
async fn try_main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
if let Some(config_path) = cli.globals.config.as_deref() {
std::env::set_var("CHRONOSEAL_CONFIG", config_path);
}
let log_filter = cli.globals.log.as_deref().unwrap_or("info");
let log_file = log_file_for_command(&cli);
let _log_guard = init_logging(log_filter, log_file)?;
match &cli.command {
None | Some(Command::Run(_)) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
if let Some(Command::Run(args)) = &cli.command {
config.apply_run_args(args);
config.validate()?;
}
runtime::run_daemon(config).await?;
}
Some(Command::Status(args)) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
config.apply_runtime_args(args);
config.validate()?;
output::print(cli.globals.output_format(), &runtime::probe_status(&config))?;
}
Some(Command::Health(args)) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
config.apply_runtime_args(args);
config.validate()?;
let report = runtime::probe_health(&config);
let healthy = report.status == "healthy";
output::print(cli.globals.output_format(), &report)?;
if !healthy {
std::process::exit(2);
}
}
Some(Command::Config(ConfigCommand::Check(args))) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
config.apply_runtime_args(args);
config.validate()?;
output::print(cli.globals.output_format(), &config)?;
}
Some(Command::Generate(GenerateCommand::Keypair)) => {
output::print(cli.globals.output_format(), &runtime::generate_keypair())?;
}
Some(Command::Version) => {
output::print(cli.globals.output_format(), &runtime::version())?;
}
Some(Command::DbType) => {
output::print(cli.globals.output_format(), &runtime::db_type_report())?;
}
Some(Command::Metrics(args)) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
config.apply_runtime_args(args);
config.validate()?;
print!("{}", runtime::fetch_metrics(&config)?);
}
Some(Command::Stats(args)) => {
let mut config = Config::load(cli.globals.config.as_deref())?;
config.apply_runtime_args(args);
config.validate()?;
output::print(cli.globals.output_format(), &runtime::fetch_stats(&config)?)?;
}
Some(Command::Completion { shell }) => {
let mut command = Cli::command();
let name = command.get_name().to_string();
clap_complete::generate(*shell, &mut command, name, &mut std::io::stdout());
}
}
Ok(())
}
fn log_file_for_command(cli: &Cli) -> Option<PathBuf> {
match &cli.command {
None => Config::load(cli.globals.config.as_deref())
.ok()
.and_then(|config| config.log_file),
Some(Command::Run(args)) => {
let mut config = Config::load(cli.globals.config.as_deref()).ok()?;
config.apply_run_args(args);
config.log_file
}
_ => None,
}
}
fn init_logging(
filter: &str,
log_file: Option<PathBuf>,
) -> Result<Option<tracing_appender::non_blocking::WorkerGuard>, Box<dyn std::error::Error>> {
let env_filter = EnvFilter::try_new(filter)?;
if let Some(path) = log_file {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let directory = path.parent().unwrap_or_else(|| std::path::Path::new("."));
let file_name = path
.file_name()
.and_then(|name| name.to_str())
.unwrap_or("chronoseal.jsonl");
let appender = tracing_appender::rolling::never(directory, file_name);
let (writer, guard) = tracing_appender::non_blocking(appender);
tracing_subscriber::registry()
.with(env_filter)
.with(tracing_subscriber::fmt::layer().with_target(false))
.with(
tracing_subscriber::fmt::layer()
.json()
.with_target(false)
.with_writer(writer),
)
.init();
Ok(Some(guard))
} else {
tracing_subscriber::fmt()
.with_env_filter(env_filter)
.with_target(false)
.init();
Ok(None)
}
}