Add config options to coarsely disable log/tracing without initialization.
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -912,6 +912,26 @@ pub struct Config {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub log_to_stderr: bool,
|
pub log_to_stderr: bool,
|
||||||
|
|
||||||
|
/// Setting to false disables the logging/tracing system at a lower level.
|
||||||
|
/// In contrast to configuring an empty `log` string where the system is
|
||||||
|
/// still operating but muted, when this option is false the system was not
|
||||||
|
/// initialized and is not operating. Changing this option has no effect
|
||||||
|
/// after startup. This option is intended for developers and expert use
|
||||||
|
/// only: configuring an empty log string is preferred over using this.
|
||||||
|
///
|
||||||
|
/// default: true
|
||||||
|
#[serde(default = "true_fn")]
|
||||||
|
pub log_enable: bool,
|
||||||
|
|
||||||
|
/// Setting to false disables the logging/tracing system at a lower level
|
||||||
|
/// similar to `log_enable`. In this case the system is configured normally,
|
||||||
|
/// but not registered as the global handler in the final steps. This option
|
||||||
|
/// is for developers and expert use only.
|
||||||
|
///
|
||||||
|
/// default: true
|
||||||
|
#[serde(default = "true_fn")]
|
||||||
|
pub log_global_default: bool,
|
||||||
|
|
||||||
/// OpenID token expiration/TTL in seconds.
|
/// OpenID token expiration/TTL in seconds.
|
||||||
///
|
///
|
||||||
/// These are the OpenID tokens that are primarily used for Matrix account
|
/// These are the OpenID tokens that are primarily used for Matrix account
|
||||||
|
|||||||
@@ -8,23 +8,31 @@ pub mod fmt_span;
|
|||||||
mod reload;
|
mod reload;
|
||||||
mod suppress;
|
mod suppress;
|
||||||
|
|
||||||
pub use capture::Capture;
|
use std::sync::Arc;
|
||||||
pub use console::{ConsoleFormat, ConsoleWriter, is_systemd_mode};
|
|
||||||
pub use reload::{LogLevelReloadHandles, ReloadHandle};
|
pub use tracing::{Level, subscriber::Subscriber};
|
||||||
pub use suppress::Suppress;
|
|
||||||
pub use tracing::Level;
|
|
||||||
pub use tracing_core::{Event, Metadata};
|
pub use tracing_core::{Event, Metadata};
|
||||||
pub use tracing_subscriber::EnvFilter;
|
pub use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
capture::Capture,
|
||||||
|
console::{ConsoleFormat, ConsoleWriter, is_systemd_mode},
|
||||||
|
reload::{LogLevelReloadHandles, ReloadHandle},
|
||||||
|
suppress::Suppress,
|
||||||
|
};
|
||||||
|
|
||||||
/// Logging subsystem. This is a singleton member of super::Server which holds
|
/// Logging subsystem. This is a singleton member of super::Server which holds
|
||||||
/// all logging and tracing related state rather than shoving it all in
|
/// all logging and tracing related state rather than shoving it all in
|
||||||
/// super::Server directly.
|
/// super::Server directly.
|
||||||
pub struct Log {
|
pub struct Logging {
|
||||||
|
/// Subscriber assigned to globals and defaults; may also be NoSubscriber.
|
||||||
|
pub subscriber: Arc<dyn Subscriber + Send + Sync>,
|
||||||
|
|
||||||
/// General log level reload handles.
|
/// General log level reload handles.
|
||||||
pub reload: LogLevelReloadHandles,
|
pub reload: LogLevelReloadHandles,
|
||||||
|
|
||||||
/// Tracing capture state for ephemeral/oneshot uses.
|
/// Tracing capture state for ephemeral/oneshot uses.
|
||||||
pub capture: std::sync::Arc<capture::State>,
|
pub capture: Arc<capture::State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wraps for logging macros. Use these macros rather than extern tracing:: or
|
// Wraps for logging macros. Use these macros rather than extern tracing:: or
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
use ruma::OwnedServerName;
|
use ruma::OwnedServerName;
|
||||||
use tokio::{runtime, sync::broadcast};
|
use tokio::{runtime, sync::broadcast};
|
||||||
|
|
||||||
use crate::{Err, Result, config, config::Config, log::Log, metrics::Metrics};
|
use crate::{Err, Result, config, config::Config, log::Logging, metrics::Metrics};
|
||||||
|
|
||||||
/// Server runtime state; public portion
|
/// Server runtime state; public portion
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
@@ -41,7 +41,7 @@ pub struct Server {
|
|||||||
pub signal: broadcast::Sender<&'static str>,
|
pub signal: broadcast::Sender<&'static str>,
|
||||||
|
|
||||||
/// Logging subsystem state
|
/// Logging subsystem state
|
||||||
pub log: Log,
|
pub log: Logging,
|
||||||
|
|
||||||
/// Metrics subsystem state
|
/// Metrics subsystem state
|
||||||
pub metrics: Metrics,
|
pub metrics: Metrics,
|
||||||
@@ -49,7 +49,7 @@ pub struct Server {
|
|||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(config: Config, runtime: Option<runtime::Handle>, log: Log) -> Self {
|
pub fn new(config: Config, runtime: Option<runtime::Handle>, log: Logging) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: config.server_name.clone(),
|
name: config.server_name.clone(),
|
||||||
config: config::Manager::new(config),
|
config: config::Manager::new(config),
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use tracing::subscriber::NoSubscriber;
|
||||||
use tracing_subscriber::{EnvFilter, Layer, Registry, fmt, layer::SubscriberExt, reload};
|
use tracing_subscriber::{EnvFilter, Layer, Registry, fmt, layer::SubscriberExt, reload};
|
||||||
use tuwunel_core::{
|
use tuwunel_core::{
|
||||||
Result,
|
Result,
|
||||||
config::Config,
|
config::Config,
|
||||||
debug_warn, err,
|
debug_warn, err,
|
||||||
log::{ConsoleFormat, ConsoleWriter, LogLevelReloadHandles, capture, fmt_span},
|
log::{ConsoleFormat, ConsoleWriter, LogLevelReloadHandles, Logging, capture, fmt_span},
|
||||||
result::UnwrapOrErr,
|
result::UnwrapOrErr,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -14,13 +15,20 @@ pub(crate) type TracingFlameGuard =
|
|||||||
Option<tracing_flame::FlushGuard<std::io::BufWriter<std::fs::File>>>;
|
Option<tracing_flame::FlushGuard<std::io::BufWriter<std::fs::File>>>;
|
||||||
|
|
||||||
#[cfg(not(feature = "perf_measurements"))]
|
#[cfg(not(feature = "perf_measurements"))]
|
||||||
pub(crate) type TracingFlameGuard = ();
|
pub(crate) type TracingFlameGuard = Option<()>;
|
||||||
|
|
||||||
#[allow(clippy::redundant_clone)]
|
#[allow(clippy::redundant_clone)]
|
||||||
pub(crate) fn init(
|
pub(crate) fn init(config: &Config) -> Result<(TracingFlameGuard, Logging)> {
|
||||||
config: &Config,
|
|
||||||
) -> Result<(LogLevelReloadHandles, TracingFlameGuard, Arc<capture::State>)> {
|
|
||||||
let reload_handles = LogLevelReloadHandles::default();
|
let reload_handles = LogLevelReloadHandles::default();
|
||||||
|
let cap_state = Arc::new(capture::State::new());
|
||||||
|
|
||||||
|
if !config.log_enable {
|
||||||
|
return Ok((None, Logging {
|
||||||
|
reload: reload_handles,
|
||||||
|
capture: cap_state,
|
||||||
|
subscriber: Arc::new(NoSubscriber::new()),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
let console_span_events = fmt_span::from_str(&config.log_span_events).unwrap_or_err();
|
let console_span_events = fmt_span::from_str(&config.log_span_events).unwrap_or_err();
|
||||||
|
|
||||||
@@ -37,14 +45,11 @@ pub(crate) fn init(
|
|||||||
.event_format(ConsoleFormat::new(config))
|
.event_format(ConsoleFormat::new(config))
|
||||||
.with_writer(ConsoleWriter::new(config));
|
.with_writer(ConsoleWriter::new(config));
|
||||||
|
|
||||||
let (console_reload_filter, console_reload_handle) =
|
let (console_reload_filter, console_reload_handle) = reload::Layer::new(console_filter);
|
||||||
reload::Layer::new(console_filter.clone());
|
|
||||||
|
|
||||||
reload_handles.add("console", Box::new(console_reload_handle));
|
reload_handles.add("console", Box::new(console_reload_handle));
|
||||||
|
|
||||||
let cap_state = Arc::new(capture::State::new());
|
|
||||||
let cap_layer = capture::Layer::new(&cap_state);
|
let cap_layer = capture::Layer::new(&cap_state);
|
||||||
|
|
||||||
let subscriber = Registry::default()
|
let subscriber = Registry::default()
|
||||||
.with(console_layer.with_filter(console_reload_filter))
|
.with(console_layer.with_filter(console_reload_filter))
|
||||||
.with(cap_layer);
|
.with(cap_layer);
|
||||||
@@ -117,33 +122,43 @@ pub(crate) fn init(
|
|||||||
not(feature = "perf_measurements"),
|
not(feature = "perf_measurements"),
|
||||||
allow(clippy::let_unit_value)
|
allow(clippy::let_unit_value)
|
||||||
)]
|
)]
|
||||||
let flame_guard = ();
|
let flame_guard = None;
|
||||||
|
|
||||||
let ret = (reload_handles, flame_guard, cap_state);
|
let subscriber = Arc::new(subscriber);
|
||||||
|
|
||||||
// Enable the tokio console. This is slightly kludgy because we're judggling
|
// Enable the tokio console. This is slightly kludgy because we're judggling
|
||||||
// compile-time and runtime conditions to elide it, each of those changing the
|
// compile-time and runtime conditions to elide it, each of those changing the
|
||||||
// subscriber's type.
|
// subscriber's type.
|
||||||
let (console_enabled, console_disabled_reason) = tokio_console_enabled(config);
|
let (console_enabled, console_disabled_reason) = tokio_console_enabled(config);
|
||||||
#[cfg(all(feature = "tokio_console", tokio_unstable, tuwunel_disable))]
|
#[cfg(all(feature = "tokio_console", tokio_unstable, tuwunel_disable))]
|
||||||
if console_enabled {
|
if console_enabled && config.log_global_default {
|
||||||
let console_layer = console_subscriber::ConsoleLayer::builder()
|
let console_layer = console_subscriber::ConsoleLayer::builder()
|
||||||
.with_default_env()
|
.with_default_env()
|
||||||
.spawn();
|
.spawn();
|
||||||
|
|
||||||
set_global_default(subscriber.with(console_layer));
|
set_global_default(subscriber.clone().with(console_layer));
|
||||||
return Ok(ret);
|
return Ok((flame_guard, Log {
|
||||||
|
reload: reload_handles,
|
||||||
|
capture: cap_state,
|
||||||
|
subscriber,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
set_global_default(subscriber);
|
if config.log_global_default {
|
||||||
|
set_global_default(subscriber.clone());
|
||||||
|
}
|
||||||
|
|
||||||
// If there's a reason the tokio console was disabled when it might be desired
|
// If there's a reason the tokio console was disabled when it might be desired
|
||||||
// we output that here after initializing logging
|
// we output that here after initializing logging
|
||||||
if !console_enabled && !console_disabled_reason.is_empty() {
|
if !console_enabled && !console_disabled_reason.is_empty() && config.log_global_default {
|
||||||
debug_warn!("{console_disabled_reason}");
|
debug_warn!("{console_disabled_reason}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ret)
|
Ok((flame_guard, Logging {
|
||||||
|
reload: reload_handles,
|
||||||
|
capture: cap_state,
|
||||||
|
subscriber,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tokio_console_enabled(config: &Config) -> (bool, &'static str) {
|
fn tokio_console_enabled(config: &Config) -> (bool, &'static str) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use tuwunel_core::{
|
|||||||
Error, Result,
|
Error, Result,
|
||||||
config::Config,
|
config::Config,
|
||||||
implement, info,
|
implement, info,
|
||||||
log::Log,
|
|
||||||
utils::{stream, sys},
|
utils::{stream, sys},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ pub fn new(args: Option<&Args>, runtime: Option<&runtime::Handle>) -> Result<Arc
|
|||||||
.and_then(|raw| args::update(raw, args))
|
.and_then(|raw| args::update(raw, args))
|
||||||
.and_then(|raw| Config::new(&raw))?;
|
.and_then(|raw| Config::new(&raw))?;
|
||||||
|
|
||||||
let (tracing_reload_handle, tracing_flame_guard, capture) = crate::logging::init(&config)?;
|
let (tracing_flame_guard, logger) = crate::logging::init(&config)?;
|
||||||
|
|
||||||
config.check()?;
|
config.check()?;
|
||||||
|
|
||||||
@@ -67,8 +66,6 @@ pub fn new(args: Option<&Args>, runtime: Option<&runtime::Handle>) -> Result<Arc
|
|||||||
tuwunel_core::version(),
|
tuwunel_core::version(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let logger = Log { reload: tracing_reload_handle, capture };
|
|
||||||
|
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
server: Arc::new(tuwunel_core::Server::new(config, runtime.cloned(), logger)),
|
server: Arc::new(tuwunel_core::Server::new(config, runtime.cloned(), logger)),
|
||||||
|
|
||||||
|
|||||||
@@ -751,6 +751,22 @@
|
|||||||
#
|
#
|
||||||
#log_to_stderr = false
|
#log_to_stderr = false
|
||||||
|
|
||||||
|
# Setting to false disables the logging/tracing system at a lower level.
|
||||||
|
# In contrast to configuring an empty `log` string where the system is
|
||||||
|
# still operating but muted, when this option is false the system was not
|
||||||
|
# initialized and is not operating. Changing this option has no effect
|
||||||
|
# after startup. This option is intended for developers and expert use
|
||||||
|
# only: configuring an empty log string is preferred over using this.
|
||||||
|
#
|
||||||
|
#log_enable = true
|
||||||
|
|
||||||
|
# Setting to false disables the logging/tracing system at a lower level
|
||||||
|
# similar to `log_enable`. In this case the system is configured normally,
|
||||||
|
# but not registered as the global handler in the final steps. This option
|
||||||
|
# is for developers and expert use only.
|
||||||
|
#
|
||||||
|
#log_global_default = true
|
||||||
|
|
||||||
# OpenID token expiration/TTL in seconds.
|
# OpenID token expiration/TTL in seconds.
|
||||||
#
|
#
|
||||||
# These are the OpenID tokens that are primarily used for Matrix account
|
# These are the OpenID tokens that are primarily used for Matrix account
|
||||||
|
|||||||
Reference in New Issue
Block a user