Skip to content

Commit

Permalink
Add rolling file logger, bump version number for release
Browse files Browse the repository at this point in the history
  • Loading branch information
Ash-L2L committed May 30, 2024
1 parent ba16ebd commit 0bb78e9
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 75 deletions.
42 changes: 38 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ authors = [
"Nikita Chashchinskii <[email protected]>"
]
edition = "2021"
version = "0.8.9"
version = "0.8.10"

[workspace.dependencies.bip300301]
git = "https://github.com/Ash-L2L/bip300301.git"
Expand Down
1 change: 1 addition & 0 deletions app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ tiny-bip39 = "1.0.0"
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
tokio-util = { version = "0.7.10", features = ["rt"] }
tracing = "0.1.40"
tracing-appender = "0.2.3"
tracing-subscriber = "0.3.18"

[[bin]]
Expand Down
214 changes: 151 additions & 63 deletions app/cli.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,145 @@
use clap::Parser;
use std::{net::SocketAddr, path::PathBuf};
use clap::{Arg, Parser};
use std::{
net::{IpAddr, Ipv4Addr, SocketAddr},
ops::Deref,
path::PathBuf,
sync::LazyLock,
};

const fn ipv4_socket_addr(ipv4_octets: [u8; 4], port: u16) -> SocketAddr {
let [a, b, c, d] = ipv4_octets;
let ipv4 = Ipv4Addr::new(a, b, c, d);
SocketAddr::new(IpAddr::V4(ipv4), port)
}

static DEFAULT_DATA_DIR: LazyLock<Option<PathBuf>> =
LazyLock::new(|| match dirs::data_dir() {
None => {
tracing::warn!("Failed to resolve default data dir");
None
}
Some(data_dir) => Some(data_dir.join("thunder")),
});

const DEFAULT_MAIN_ADDR: SocketAddr = ipv4_socket_addr([127, 0, 0, 1], 18443);

const DEFAULT_MAIN_USER: &str = "user";

const DEFAULT_MAIN_PASS: &str = "password";

const DEFAULT_NET_ADDR: SocketAddr = ipv4_socket_addr([0, 0, 0, 0], 4000);

const DEFAULT_RPC_ADDR: SocketAddr = ipv4_socket_addr([127, 0, 0, 1], 2020);

/// Implement arg manually so that there is only a default if we can resolve
/// the default data dir
#[derive(Clone, Debug)]
#[repr(transparent)]
struct DatadirArg(PathBuf);

impl clap::FromArgMatches for DatadirArg {
fn from_arg_matches(
matches: &clap::ArgMatches,
) -> Result<Self, clap::Error> {
let mut matches = matches.clone();
Self::from_arg_matches_mut(&mut matches)
}

fn from_arg_matches_mut(
matches: &mut clap::ArgMatches,
) -> Result<Self, clap::Error> {
let datadir = matches
.remove_one::<PathBuf>("DATADIR")
.expect("`datadir` is required");
Ok(Self(datadir))
}

fn update_from_arg_matches(
&mut self,
matches: &clap::ArgMatches,
) -> Result<(), clap::Error> {
let mut matches = matches.clone();
self.update_from_arg_matches_mut(&mut matches)
}

fn update_from_arg_matches_mut(
&mut self,
matches: &mut clap::ArgMatches,
) -> Result<(), clap::Error> {
if let Some(datadir) = matches.remove_one("DATADIR") {
self.0 = datadir;
}
Ok(())
}
}

impl clap::Args for DatadirArg {
fn augment_args(cmd: clap::Command) -> clap::Command {
cmd.arg({
let arg = Arg::new("DATADIR")
.value_parser(clap::builder::PathBufValueParser::new())
.long("datadir")
.short('d')
.help("Data directory for storing blockchain and wallet data");
match DEFAULT_DATA_DIR.deref() {
None => arg.required(true),
Some(datadir) => {
arg.required(false).default_value(datadir.as_os_str())
}
}
})
}

fn augment_args_for_update(cmd: clap::Command) -> clap::Command {
Self::augment_args(cmd)
}
}

#[derive(Clone, Debug, Parser)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
/// data directory for storing blockchain data and wallet, defaults to ~/.local/share
#[arg(short, long)]
pub datadir: Option<PathBuf>,
pub(super) struct Cli {
/// Data directory for storing blockchain and wallet data
#[command(flatten)]
datadir: DatadirArg,
/// If specified, the gui will not launch.
#[arg(long)]
pub headless: bool,
/// Log level, defaults to [`tracing::Level::Debug`]
headless: bool,
/// Directory in which to store log files.
/// Defaults to `<DATADIR>/logs/v<VERSION>`, where `<DATADIR>` is thunder's data
/// directory, and `<VERSION>` is the thunder app version.
/// By default, only logs at the WARN level and above are logged to file.
/// If set to the empty string, logging to file will be disabled.
#[arg(long)]
log_dir: Option<PathBuf>,
/// Log level
#[arg(default_value_t = tracing::Level::DEBUG, long)]
pub log_level: tracing::Level,
/// address to use for P2P networking, defaults to 0.0.0.0:4000
#[arg(short, long)]
pub net_addr: Option<String>,
/// address to connect to mainchain node RPC server, defaults to 127.0.0.1:18443
#[arg(short, long)]
pub main_addr: Option<String>,
log_level: tracing::Level,
/// Socket address to connect to mainchain node RPC server
#[arg(default_value_t = DEFAULT_MAIN_ADDR, long, short)]
main_addr: SocketAddr,
/// Path to a mnemonic seed phrase
#[arg(long)]
pub mnemonic_seed_phrase_path: Option<PathBuf>,
/// address for use by the RPC server exposing getblockcount and stop commands, defaults to
/// 127.0.0.1:2020
#[arg(short, long)]
pub rpc_addr: Option<String>,
/// mainchain node RPC user, defaults to "user"
#[arg(short, long)]
pub user_main: Option<String>,
/// mainchain node RPC password, defaults to "password"
#[arg(short, long)]
pub password_main: Option<String>,
mnemonic_seed_phrase_path: Option<PathBuf>,
/// Socket address to use for P2P networking
#[arg(default_value_t = DEFAULT_NET_ADDR, long, short)]
net_addr: SocketAddr,
/// Socket address to host the RPC server
#[arg(default_value_t = DEFAULT_RPC_ADDR, long, short)]
rpc_addr: SocketAddr,
/// Mainchain node RPC user
#[arg(default_value_t = DEFAULT_MAIN_USER.to_owned(), long, short)]
user_main: String,
/// Mainchain node RPC password
#[arg(default_value_t = DEFAULT_MAIN_PASS.to_owned(), long, short)]
password_main: String,
}

#[derive(Clone, Debug)]
pub struct Config {
pub datadir: PathBuf,
pub headless: bool,
/// If None, logging to file should be disabled.
pub log_dir: Option<PathBuf>,
pub log_level: tracing::Level,
pub main_addr: SocketAddr,
pub main_password: String,
Expand All @@ -49,47 +151,33 @@ pub struct Config {

impl Cli {
pub fn get_config(self) -> anyhow::Result<Config> {
let datadir = self
.datadir
.clone()
.unwrap_or_else(|| {
dirs::data_dir()
.expect("couldn't get default datadir, specify --datadir")
})
.join("thunder");
const DEFAULT_MAIN_ADDR: &str = "127.0.0.1:18443";
let main_addr: SocketAddr = self
.main_addr
.clone()
.unwrap_or(DEFAULT_MAIN_ADDR.to_string())
.parse()?;
let main_password = self
.password_main
.clone()
.unwrap_or_else(|| "password".into());
let main_user = self.user_main.clone().unwrap_or_else(|| "user".into());
const DEFAULT_NET_ADDR: &str = "0.0.0.0:4000";
let net_addr: SocketAddr = self
.net_addr
.clone()
.unwrap_or(DEFAULT_NET_ADDR.to_string())
.parse()?;
const DEFAULT_RPC_ADDR: &str = "127.0.0.1:2020";
let rpc_addr: SocketAddr = self
.rpc_addr
.clone()
.unwrap_or(DEFAULT_RPC_ADDR.to_string())
.parse()?;
let log_dir = match self.log_dir {
None => {
let version_dir_name =
format!("v{}", env!("CARGO_PKG_VERSION"));
let log_dir =
self.datadir.0.join("logs").join(version_dir_name);
Some(log_dir)
}
Some(log_dir) => {
if log_dir.as_os_str().is_empty() {
None
} else {
Some(log_dir)
}
}
};
Ok(Config {
datadir,
datadir: self.datadir.0,
headless: self.headless,
log_dir,
log_level: self.log_level,
main_addr,
main_password,
main_user,
main_addr: self.main_addr,
main_password: self.password_main,
main_user: self.user_main,
mnemonic_seed_phrase_path: self.mnemonic_seed_phrase_path,
net_addr,
rpc_addr,
net_addr: self.net_addr,
rpc_addr: self.rpc_addr,
})
}
}
Loading

0 comments on commit 0bb78e9

Please sign in to comment.