Skip to content

Commit

Permalink
Introduce daemonbase and use it for logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
partim committed Nov 20, 2023
1 parent c7fcb9d commit 7a1c5ab
Show file tree
Hide file tree
Showing 15 changed files with 333 additions and 789 deletions.
456 changes: 270 additions & 186 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ readme = "README.md"
[dependencies]
arc-swap = "1.0"
chrono = "0.4.31"
clap = { version = "3.0", features = [ "cargo" ] }
clap = { version = "4", features = [ "cargo", "derive" ] }
crossbeam-utils = "0.8.4"
daemonbase = { git = "https://github.com/NLnetLabs/daemonbase.git" }
fern = "0.6.0"
futures = "0.3"
hyper = { version = "0.14.8", features = [ "server", "stream" ] }
Expand Down
131 changes: 29 additions & 102 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
//! file referred to in command line options.
use std::{borrow, error, fmt, fs, io, ops};
use std::cell::RefCell;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::sync::Arc;
use clap::{Arg, ArgMatches, Command};
use clap::{Args as _, FromArgMatches};
use daemonbase::logging;
use daemonbase::config::ConfigPath;
use daemonbase::error::Failed;
use serde::Deserialize;
use toml::Spanned;
use crate::http;
use crate::log::{ExitError, Failed, LogConfig};
use crate::manager::{Manager, TargetSet, UnitSet};


Expand All @@ -39,19 +40,19 @@ pub struct Config {

/// The logging configuration.
#[serde(flatten)]
pub log: LogConfig,
pub log: logging::Config,

/// The HTTP server configuration.
#[serde(flatten)]
pub http: http::Server,
}

impl Config {
/// Initialises everything.
/// Adds the basic arguments to a Clap command.
///
/// This function should be called first thing.
pub fn init() -> Result<(), ExitError> {
LogConfig::init_logging()
/// Returns the command with the arguments added.
pub fn config_args(app: clap::Command) -> clap::Command {
Args::augment_args(app)
}

/// Creates a configuration from a bytes slice with TOML data.
Expand All @@ -66,20 +67,6 @@ impl Config {
res
}

/// Configures a clap app with the arguments to load the configuration.
pub fn config_args(app: Command) -> Command {
let app = app.arg(
Arg::new("config")
.short('c')
.long("config")
.required(true)
.takes_value(true)
.value_name("PATH")
.help("Read base configuration from this file")
);
LogConfig::config_args(app)
}

/// Loads the configuration based on command line options provided.
///
/// The `matches` must be the result of getting argument matches from a
Expand All @@ -91,30 +78,42 @@ impl Config {
/// paths. The manager is necessary to resolve links given in the
/// configuration.
pub fn from_arg_matches(
matches: &ArgMatches,
cur_dir: &Path,
matches: &clap::ArgMatches,
manager: &mut Manager,
) -> Result<Self, Failed> {
let conf_path = cur_dir.join(matches.value_of("config").unwrap());
let conf = match ConfigFile::load(&conf_path) {
let args = Args::from_arg_matches(
matches
).expect("bug in command line arguments parser");
let conf = match ConfigFile::load(&args.config) {
Ok(conf) => conf,
Err(err) => {
eprintln!(
"Failed to read config file '{}': {}",
conf_path.display(),
args.config.display(),
err
);
return Err(Failed)
}
};
let mut res = manager.load(conf)?;
res.log.update_with_arg_matches(matches, cur_dir)?;
res.log.switch_logging(false)?;
res.log.apply_args(&args.log);
Ok(res)
}
}


//------------ Args ----------------------------------------------------------

#[derive(clap::Parser)]
pub struct Args {
#[arg(short, long)]
pub config: ConfigPath,

#[command(flatten)]
pub log: logging::Args,
}


//------------ Source --------------------------------------------------------

/// Description of the source of configuration.
Expand Down Expand Up @@ -370,75 +369,3 @@ impl fmt::Display for ConfigError {

impl error::Error for ConfigError { }


//------------ ConfigPath ----------------------------------------------------

/// A path that encountered in a config file.
///
/// This is a basically a `PathBuf` that, when, deserialized resolves all
/// relative paths from a certain base path so that all relative paths
/// encountered in a config file are automatically resolved relative to the
/// location of the config file.
#[derive(
Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd
)]
#[serde(from = "String")]
pub struct ConfigPath(PathBuf);

impl ConfigPath {
thread_local!(
static BASE_PATH: RefCell<Option<PathBuf>> = RefCell::new(None)
);

fn set_base_path(path: PathBuf) {
Self::BASE_PATH.with(|base_path| {
base_path.replace(Some(path));
})
}

fn clear_base_path() {
Self::BASE_PATH.with(|base_path| {
base_path.replace(None);
})
}
}

impl From<PathBuf> for ConfigPath {
fn from(path: PathBuf) -> Self {
Self(path)
}
}

impl From<ConfigPath> for PathBuf {
fn from(path: ConfigPath) -> Self {
path.0
}
}

impl From<String> for ConfigPath {
fn from(path: String) -> Self {
Self::BASE_PATH.with(|base_path| {
ConfigPath(
match base_path.borrow().as_ref() {
Some(base_path) => base_path.join(path.as_str()),
None => path.into()
}
)
})
}
}

impl ops::Deref for ConfigPath {
type Target = Path;

fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}

impl AsRef<Path> for ConfigPath {
fn as_ref(&self) -> &Path {
self.0.as_ref()
}
}

6 changes: 3 additions & 3 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::pin::Pin;
use std::sync::{Arc, Mutex, Weak};
use std::task::{Context, Poll};
use arc_swap::ArcSwap;
use daemonbase::error::ExitError;
use futures::pin_mut;
use hyper::{Body, Method, Request, Response, StatusCode};
use hyper::server::accept::Accept;
Expand All @@ -24,7 +25,6 @@ use serde::Deserialize;
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio::net::{TcpListener, TcpStream};
use tokio::runtime::Runtime;
use crate::log::ExitError;
use crate::metrics;


Expand Down Expand Up @@ -64,15 +64,15 @@ impl Server {
Ok(listener) => listener,
Err(err) => {
error!("Fatal: error listening on {}: {}", addr, err);
return Err(ExitError);
return Err(ExitError::default());
}
};
if let Err(err) = listener.set_nonblocking(true) {
error!(
"Fatal: failed to set listener {} to non-blocking: {}.",
addr, err
);
return Err(ExitError);
return Err(ExitError::default());
}
debug!("HTTP server listening on {}", addr);
listeners.push(listener);
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub mod comms;
pub mod config;
pub mod formats;
pub mod http;
pub mod log;
//pub mod log;
pub mod manager;
pub mod metrics;
pub mod payload;
Expand Down
Loading

0 comments on commit 7a1c5ab

Please sign in to comment.