api and log refactor
This commit is contained in:
@@ -10,14 +10,10 @@ cfg_if! {
|
||||
use send_wrapper::*;
|
||||
|
||||
struct ApiLoggerInner {
|
||||
max_level: Option<VeilidLogLevel>,
|
||||
filter_ignore: Cow<'static, [Cow<'static, str>]>,
|
||||
update_callback: SendWrapper<UpdateCallback>,
|
||||
}
|
||||
} else {
|
||||
struct ApiLoggerInner {
|
||||
max_level: Option<VeilidLogLevel>,
|
||||
filter_ignore: Cow<'static, [Cow<'static, str>]>,
|
||||
update_callback: UpdateCallback,
|
||||
}
|
||||
}
|
||||
@@ -31,21 +27,14 @@ pub struct ApiTracingLayer {
|
||||
static API_LOGGER: OnceCell<ApiTracingLayer> = OnceCell::new();
|
||||
|
||||
impl ApiTracingLayer {
|
||||
fn new_inner(
|
||||
max_level: Option<VeilidLogLevel>,
|
||||
update_callback: UpdateCallback,
|
||||
) -> ApiLoggerInner {
|
||||
fn new_inner(update_callback: UpdateCallback) -> ApiLoggerInner {
|
||||
cfg_if! {
|
||||
if #[cfg(target_arch = "wasm32")] {
|
||||
ApiLoggerInner {
|
||||
max_level,
|
||||
filter_ignore: Default::default(),
|
||||
update_callback: SendWrapper::new(update_callback),
|
||||
}
|
||||
} else {
|
||||
ApiLoggerInner {
|
||||
max_level,
|
||||
filter_ignore: Default::default(),
|
||||
update_callback,
|
||||
}
|
||||
}
|
||||
@@ -53,11 +42,11 @@ impl ApiTracingLayer {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(update_callback))]
|
||||
pub async fn init(max_level: Option<VeilidLogLevel>, update_callback: UpdateCallback) {
|
||||
pub async fn init(update_callback: UpdateCallback) {
|
||||
let api_logger = API_LOGGER.get_or_init(|| ApiTracingLayer {
|
||||
inner: Arc::new(Mutex::new(None)),
|
||||
});
|
||||
let apilogger_inner = Some(Self::new_inner(max_level, update_callback));
|
||||
let apilogger_inner = Some(Self::new_inner(update_callback));
|
||||
*api_logger.inner.lock() = apilogger_inner;
|
||||
}
|
||||
|
||||
@@ -76,52 +65,9 @@ impl ApiTracingLayer {
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[instrument(level = "trace")]
|
||||
pub fn change_api_log_level(max_level: Option<VeilidLogLevel>) {
|
||||
if let Some(api_logger) = API_LOGGER.get() {
|
||||
if let Some(inner) = &mut *api_logger.inner.lock() {
|
||||
inner.max_level = max_level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_filter_ignore_str(filter_ignore: &'static str) {
|
||||
if let Some(api_logger) = API_LOGGER.get() {
|
||||
if let Some(inner) = &mut *api_logger.inner.lock() {
|
||||
let mut list = Vec::from(&*inner.filter_ignore);
|
||||
list.push(Cow::Borrowed(filter_ignore));
|
||||
inner.filter_ignore = Cow::Owned(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLayer {
|
||||
fn enabled(&self, metadata: &tracing::Metadata<'_>, _: layer::Context<'_, S>) -> bool {
|
||||
if let Some(inner) = &mut *self.inner.lock() {
|
||||
// Skip things that are out of our level
|
||||
if let Some(max_level) = inner.max_level {
|
||||
if VeilidLogLevel::from_tracing_level(*metadata.level()) > max_level {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// Skip filtered targets
|
||||
let skip = match (metadata.target(), &*inner.filter_ignore) {
|
||||
(path, ignore) if !ignore.is_empty() => {
|
||||
// Check that the module path does not match any ignore filters
|
||||
ignore.iter().any(|v| path.starts_with(&**v))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
!skip
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn on_new_span(
|
||||
&self,
|
||||
attrs: &tracing::span::Attributes<'_>,
|
||||
@@ -161,23 +107,16 @@ impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLa
|
||||
event.record(&mut recorder);
|
||||
let meta = event.metadata();
|
||||
let level = meta.level();
|
||||
if let Some(max_level) = inner.max_level {
|
||||
if VeilidLogLevel::from_tracing_level(*level) <= max_level {
|
||||
let log_level = VeilidLogLevel::from_tracing_level(*level);
|
||||
let log_level = VeilidLogLevel::from_tracing_level(*level);
|
||||
|
||||
let origin = meta
|
||||
.file()
|
||||
.and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln)))
|
||||
.unwrap_or_default();
|
||||
let origin = meta
|
||||
.file()
|
||||
.and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln)))
|
||||
.unwrap_or_default();
|
||||
|
||||
let message = format!("{} {}", origin, recorder);
|
||||
let message = format!("{} {}", origin, recorder);
|
||||
|
||||
(inner.update_callback)(VeilidUpdate::Log(VeilidStateLog {
|
||||
log_level,
|
||||
message,
|
||||
}))
|
||||
}
|
||||
}
|
||||
(inner.update_callback)(VeilidUpdate::Log(VeilidStateLog { log_level, message }))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,64 +171,3 @@ impl core::default::Default for StringRecorder {
|
||||
StringRecorder::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl log::Log for ApiTracingLayer {
|
||||
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
|
||||
if let Some(inner) = &mut *self.inner.lock() {
|
||||
if let Some(max_level) = inner.max_level {
|
||||
return VeilidLogLevel::from_log_level(metadata.level()) <= max_level;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn log(&self, record: &log::Record<'_>) {
|
||||
if let Some(inner) = &mut *self.inner.lock() {
|
||||
// Skip filtered targets
|
||||
let skip = match (record.target(), &*inner.filter_ignore) {
|
||||
(path, ignore) if !ignore.is_empty() => {
|
||||
// Check that the module path does not match any ignore filters
|
||||
ignore.iter().any(|v| path.starts_with(&**v))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if skip {
|
||||
return;
|
||||
}
|
||||
|
||||
let metadata = record.metadata();
|
||||
let level = metadata.level();
|
||||
let log_level = VeilidLogLevel::from_log_level(level);
|
||||
if let Some(max_level) = inner.max_level {
|
||||
if log_level <= max_level {
|
||||
let file = record.file().unwrap_or("<unknown>");
|
||||
let loc = if level >= log::Level::Debug {
|
||||
if let Some(line) = record.line() {
|
||||
format!("[{}:{}] ", file, line)
|
||||
} else {
|
||||
format!("[{}:<unknown>] ", file)
|
||||
}
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
let tgt = if record.target().is_empty() {
|
||||
"".to_owned()
|
||||
} else {
|
||||
format!("{}: ", record.target())
|
||||
};
|
||||
|
||||
let message = format!("{}{}{}", tgt, loc, record.args());
|
||||
|
||||
(inner.update_callback)(VeilidUpdate::Log(VeilidStateLog {
|
||||
log_level,
|
||||
message,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {
|
||||
// always flushes
|
||||
}
|
||||
}
|
||||
|
@@ -59,21 +59,11 @@ impl ServicesContext {
|
||||
|
||||
#[instrument(err, skip_all)]
|
||||
pub async fn startup(&mut self) -> Result<(), VeilidAPIError> {
|
||||
let api_log_level: VeilidConfigLogLevel = self.config.get().api_log_level;
|
||||
if api_log_level != VeilidConfigLogLevel::Off {
|
||||
ApiTracingLayer::init(
|
||||
api_log_level.to_veilid_log_level(),
|
||||
self.update_callback.clone(),
|
||||
)
|
||||
.await;
|
||||
for ig in crate::DEFAULT_LOG_IGNORE_LIST {
|
||||
ApiTracingLayer::add_filter_ignore_str(ig);
|
||||
}
|
||||
info!("Veilid API logging initialized");
|
||||
}
|
||||
|
||||
info!("Veilid API starting up");
|
||||
|
||||
info!("init api tracing");
|
||||
ApiTracingLayer::init(self.update_callback.clone()).await;
|
||||
|
||||
// Set up protected store
|
||||
trace!("init protected store");
|
||||
let protected_store = ProtectedStore::new(self.config.clone());
|
||||
|
@@ -30,6 +30,7 @@ mod routing_table;
|
||||
mod rpc_processor;
|
||||
mod veilid_api;
|
||||
mod veilid_config;
|
||||
mod veilid_layer_filter;
|
||||
mod veilid_rng;
|
||||
|
||||
#[macro_use]
|
||||
@@ -40,6 +41,7 @@ pub use self::attachment_manager::AttachmentState;
|
||||
pub use self::core_context::{api_startup, api_startup_json, UpdateCallback};
|
||||
pub use self::veilid_api::*;
|
||||
pub use self::veilid_config::*;
|
||||
pub use self::veilid_layer_filter::*;
|
||||
|
||||
pub mod veilid_capnp {
|
||||
include!(concat!(env!("OUT_DIR"), "/proto/veilid_capnp.rs"));
|
||||
|
@@ -169,7 +169,6 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
|
||||
match key.as_str() {
|
||||
"program_name" => Ok(Box::new(String::from("Veilid"))),
|
||||
"namespace" => Ok(Box::new(String::from(""))),
|
||||
"api_log_level" => Ok(Box::new(VeilidConfigLogLevel::Off)),
|
||||
"capabilities.protocol_udp" => Ok(Box::new(true)),
|
||||
"capabilities.protocol_connect_tcp" => Ok(Box::new(true)),
|
||||
"capabilities.protocol_accept_tcp" => Ok(Box::new(true)),
|
||||
|
@@ -1861,12 +1861,6 @@ impl VeilidAPI {
|
||||
.map_err(|e| VeilidAPIError::Internal { message: e })
|
||||
}
|
||||
|
||||
// Change api logging level if it is enabled
|
||||
#[instrument(skip(self))]
|
||||
pub async fn change_api_log_level(&self, log_level: VeilidConfigLogLevel) {
|
||||
ApiTracingLayer::change_api_log_level(log_level.to_veilid_log_level());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Direct Node Access (pretty much for testing only)
|
||||
|
||||
|
@@ -223,6 +223,16 @@ impl VeilidConfigLogLevel {
|
||||
Some(VeilidLogLevel::Trace) => Self::Trace,
|
||||
}
|
||||
}
|
||||
pub fn from_tracing_level_filter(level: level_filters::LevelFilter) -> Self {
|
||||
match level {
|
||||
level_filters::LevelFilter::OFF => Self::Off,
|
||||
level_filters::LevelFilter::ERROR => Self::Error,
|
||||
level_filters::LevelFilter::WARN => Self::Warn,
|
||||
level_filters::LevelFilter::INFO => Self::Info,
|
||||
level_filters::LevelFilter::DEBUG => Self::Debug,
|
||||
level_filters::LevelFilter::TRACE => Self::Trace,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Default for VeilidConfigLogLevel {
|
||||
fn default() -> Self {
|
||||
|
91
veilid-core/src/veilid_layer_filter.rs
Normal file
91
veilid-core/src/veilid_layer_filter.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use super::*;
|
||||
use crate::xx::*;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing::subscriber;
|
||||
use tracing_subscriber::layer;
|
||||
|
||||
struct VeilidLayerFilterInner {
|
||||
max_level: LevelFilter,
|
||||
ignore_list: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VeilidLayerFilter {
|
||||
inner: Arc<RwLock<VeilidLayerFilterInner>>,
|
||||
}
|
||||
|
||||
impl VeilidLayerFilter {
|
||||
pub fn new(
|
||||
max_level: VeilidConfigLogLevel,
|
||||
ignore_list: Option<Vec<String>>,
|
||||
) -> VeilidLayerFilter {
|
||||
Self {
|
||||
inner: Arc::new(RwLock::new(VeilidLayerFilterInner {
|
||||
max_level: max_level.to_tracing_level_filter(),
|
||||
ignore_list: ignore_list
|
||||
.unwrap_or_else(|| DEFAULT_LOG_IGNORE_LIST.map(|x| x.to_owned()).to_vec()),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max_level(&self) -> VeilidConfigLogLevel {
|
||||
let inner = self.inner.read();
|
||||
VeilidConfigLogLevel::from_tracing_level_filter(inner.max_level)
|
||||
}
|
||||
|
||||
pub fn ignore_list(&self) -> Vec<String> {
|
||||
let inner = self.inner.read();
|
||||
inner.ignore_list.clone()
|
||||
}
|
||||
|
||||
pub fn set_max_level(&self, level: VeilidConfigLogLevel) {
|
||||
{
|
||||
let mut inner = self.inner.write();
|
||||
inner.max_level = level.to_tracing_level_filter();
|
||||
}
|
||||
callsite::rebuild_interest_cache();
|
||||
}
|
||||
|
||||
pub fn set_ignore_list(&self, ignore_list: Option<Vec<String>>) {
|
||||
{
|
||||
let mut inner = self.inner.write();
|
||||
inner.ignore_list = ignore_list
|
||||
.unwrap_or_else(|| DEFAULT_LOG_IGNORE_LIST.map(|x| x.to_owned()).to_vec());
|
||||
}
|
||||
callsite::rebuild_interest_cache();
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: tracing::Subscriber> layer::Filter<S> for VeilidLayerFilter {
|
||||
fn enabled(&self, metadata: &tracing::Metadata<'_>, _: &layer::Context<'_, S>) -> bool {
|
||||
let inner = self.inner.read();
|
||||
if *metadata.level() > inner.max_level {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn callsite_enabled(
|
||||
&self,
|
||||
metadata: &'static tracing::Metadata<'static>,
|
||||
) -> subscriber::Interest {
|
||||
let inner = self.inner.read();
|
||||
let skip = inner
|
||||
.ignore_list
|
||||
.iter()
|
||||
.any(|v| metadata.target().starts_with(&**v));
|
||||
if skip {
|
||||
subscriber::Interest::never()
|
||||
} else if *metadata.level() > inner.max_level {
|
||||
subscriber::Interest::never()
|
||||
} else {
|
||||
subscriber::Interest::always()
|
||||
}
|
||||
}
|
||||
|
||||
fn max_level_hint(&self) -> Option<LevelFilter> {
|
||||
let inner = self.inner.read();
|
||||
Some(inner.max_level)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user