Move logging configuration from arti_config::options to arti::logging

Code motion and import fixups.
This commit is contained in:
Ian Jackson 2022-03-21 10:45:58 +00:00
parent b51fccb70e
commit 32d3076a82
7 changed files with 135 additions and 132 deletions

1
Cargo.lock generated
View File

@ -82,6 +82,7 @@ dependencies = [
"cfg-if 1.0.0",
"clap",
"config",
"derive_builder",
"futures",
"libc",
"notify",

View File

@ -52,8 +52,7 @@ mod options;
pub use cmdline::CmdLine;
pub use options::{
ApplicationConfig, ApplicationConfigBuilder, LogRotation, LogfileConfig, LogfileConfigBuilder,
LoggingConfig, LoggingConfigBuilder, ProxyConfig, ProxyConfigBuilder, ARTI_DEFAULTS,
ApplicationConfig, ApplicationConfigBuilder, ProxyConfig, ProxyConfigBuilder, ARTI_DEFAULTS,
};
use tor_config::CfgPath;

View File

@ -2,7 +2,7 @@
use derive_builder::Builder;
use serde::Deserialize;
use tor_config::{CfgPath, ConfigBuildError};
use tor_config::ConfigBuildError;
/// Default options to use for our configuration.
//
@ -34,130 +34,6 @@ impl ApplicationConfig {
}
}
/// Structure to hold our logging configuration options
#[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)]
#[serde(deny_unknown_fields)]
#[non_exhaustive] // TODO(nickm) remove public elements when I revise this.
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Deserialize))]
pub struct LoggingConfig {
/// Filtering directives that determine tracing levels as described at
/// <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html#impl-FromStr>
///
/// You can override this setting with the -l, --log-level command line parameter.
///
/// Example: "info,tor_proto::channel=trace"
#[serde(default = "default_console_filter")]
#[builder(default = "default_console_filter()", setter(into, strip_option))]
console: Option<String>,
/// Filtering directives for the journald logger.
///
/// Only takes effect if Arti is built with the `journald` filter.
#[serde(default)]
#[builder(default, setter(into, strip_option))]
journald: Option<String>,
/// Configuration for one or more logfiles.
#[serde(default)]
#[builder(default)]
file: Vec<LogfileConfig>,
}
/// Return a default tracing filter value for `logging.console`.
#[allow(clippy::unnecessary_wraps)]
fn default_console_filter() -> Option<String> {
Some("debug".to_owned())
}
impl Default for LoggingConfig {
fn default() -> Self {
Self::builder().build().expect("Default builder failed")
}
}
impl LoggingConfig {
/// Return a new LoggingConfigBuilder
pub fn builder() -> LoggingConfigBuilder {
LoggingConfigBuilder::default()
}
/// Return the configured journald filter, if one is present
pub fn journald_filter(&self) -> Option<&str> {
match self.journald {
Some(ref s) if !s.is_empty() => Some(s.as_str()),
_ => None,
}
}
/// Return the configured stdout filter, if one is present
pub fn console_filter(&self) -> Option<&str> {
match self.console {
Some(ref s) if !s.is_empty() => Some(s.as_str()),
_ => None,
}
}
/// Return a list of the configured log files
pub fn logfiles(&self) -> &[LogfileConfig] {
&self.file
}
}
/// Configuration information for an (optionally rotating) logfile.
#[derive(Deserialize, Debug, Builder, Clone, Eq, PartialEq)]
pub struct LogfileConfig {
/// How often to rotate the file?
#[serde(default)]
#[builder(default)]
rotate: LogRotation,
/// Where to write the files?
path: CfgPath,
/// Filter to apply before writing
filter: String,
}
/// How often to rotate a log file
#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
#[serde(rename_all = "lowercase")]
pub enum LogRotation {
/// Rotate logs daily
Daily,
/// Rotate logs hourly
Hourly,
/// Never rotate the log
Never,
}
impl Default for LogRotation {
fn default() -> Self {
Self::Never
}
}
impl LogfileConfig {
/// Return a new [`LogfileConfigBuilder`]
pub fn builder() -> LogfileConfigBuilder {
LogfileConfigBuilder::default()
}
/// Return the configured rotation interval.
pub fn rotate(&self) -> LogRotation {
self.rotate
}
/// Return the configured path to the log file.
pub fn path(&self) -> &CfgPath {
&self.path
}
/// Return the configured filter.
pub fn filter(&self) -> &str {
&self.filter
}
}
/// Configuration for one or more proxy listeners.
#[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)]
#[serde(deny_unknown_fields)]

View File

@ -33,6 +33,7 @@ anyhow = "1.0.23"
async-ctrlc = { version = "1.2.0", optional = true }
config = { version = "0.12.0", default-features = false }
cfg-if = "1.0.0"
derive_builder = "0.11"
futures = "0.3.14"
tracing = "0.1.18"
notify = "4.0"

View File

@ -8,12 +8,11 @@ use serde::Deserialize;
use arti_client::config::{SystemConfig, SystemConfigBuilder, TorClientConfigBuilder};
use arti_client::TorClientConfig;
use arti_config::{
ApplicationConfig, ApplicationConfigBuilder, LoggingConfig, LoggingConfigBuilder, ProxyConfig,
ProxyConfigBuilder,
};
use arti_config::{ApplicationConfig, ApplicationConfigBuilder, ProxyConfig, ProxyConfigBuilder};
use tor_config::ConfigBuildError;
use crate::{LoggingConfig, LoggingConfigBuilder};
/// Structure to hold Arti's configuration options, whether from a
/// configuration file or the command line.
//

View File

@ -123,6 +123,7 @@ pub mod socks;
pub mod watch_cfg;
pub use cfg::{ArtiConfig, ArtiConfigBuilder};
pub use logging::{LoggingConfig, LoggingConfigBuilder};
use arti_client::{TorClient, TorClientConfig};
use arti_config::default_config_file;

View File

@ -1,15 +1,141 @@
//! Configure tracing subscribers for Arti
use anyhow::{anyhow, Context, Result};
use arti_config::{LogRotation, LogfileConfig, LoggingConfig};
use derive_builder::Builder;
use serde::Deserialize;
use std::path::Path;
use std::str::FromStr;
use tor_config::{CfgPath, ConfigBuildError};
use tracing::Subscriber;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{filter::Targets, fmt, registry, Layer};
/// Structure to hold our logging configuration options
#[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)]
#[serde(deny_unknown_fields)]
#[non_exhaustive] // TODO(nickm) remove public elements when I revise this.
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Deserialize))]
pub struct LoggingConfig {
/// Filtering directives that determine tracing levels as described at
/// <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/targets/struct.Targets.html#impl-FromStr>
///
/// You can override this setting with the -l, --log-level command line parameter.
///
/// Example: "info,tor_proto::channel=trace"
#[serde(default = "default_console_filter")]
#[builder(default = "default_console_filter()", setter(into, strip_option))]
console: Option<String>,
/// Filtering directives for the journald logger.
///
/// Only takes effect if Arti is built with the `journald` filter.
#[serde(default)]
#[builder(default, setter(into, strip_option))]
journald: Option<String>,
/// Configuration for one or more logfiles.
#[serde(default)]
#[builder(default)]
file: Vec<LogfileConfig>,
}
/// Return a default tracing filter value for `logging.console`.
#[allow(clippy::unnecessary_wraps)]
fn default_console_filter() -> Option<String> {
Some("debug".to_owned())
}
impl Default for LoggingConfig {
fn default() -> Self {
Self::builder().build().expect("Default builder failed")
}
}
impl LoggingConfig {
/// Return a new LoggingConfigBuilder
pub fn builder() -> LoggingConfigBuilder {
LoggingConfigBuilder::default()
}
/// Return the configured journald filter, if one is present
pub fn journald_filter(&self) -> Option<&str> {
match self.journald {
Some(ref s) if !s.is_empty() => Some(s.as_str()),
_ => None,
}
}
/// Return the configured stdout filter, if one is present
pub fn console_filter(&self) -> Option<&str> {
match self.console {
Some(ref s) if !s.is_empty() => Some(s.as_str()),
_ => None,
}
}
/// Return a list of the configured log files
pub fn logfiles(&self) -> &[LogfileConfig] {
&self.file
}
}
/// Configuration information for an (optionally rotating) logfile.
#[derive(Deserialize, Debug, Builder, Clone, Eq, PartialEq)]
pub struct LogfileConfig {
/// How often to rotate the file?
#[serde(default)]
#[builder(default)]
rotate: LogRotation,
/// Where to write the files?
path: CfgPath,
/// Filter to apply before writing
filter: String,
}
/// How often to rotate a log file
#[derive(Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
#[serde(rename_all = "lowercase")]
pub enum LogRotation {
/// Rotate logs daily
Daily,
/// Rotate logs hourly
Hourly,
/// Never rotate the log
Never,
}
impl Default for LogRotation {
fn default() -> Self {
Self::Never
}
}
impl LogfileConfig {
/// Return a new [`LogfileConfigBuilder`]
pub fn builder() -> LogfileConfigBuilder {
LogfileConfigBuilder::default()
}
/// Return the configured rotation interval.
pub fn rotate(&self) -> LogRotation {
self.rotate
}
/// Return the configured path to the log file.
pub fn path(&self) -> &CfgPath {
&self.path
}
/// Return the configured filter.
pub fn filter(&self) -> &str {
&self.filter
}
}
/// As [`Targets::from_str`], but wrapped in an [`anyhow::Result`].
//
// (Note that we have to use `Targets`, not `EnvFilter`: see comment in