continuwuity/src/core/log/capture/layer.rs
strawberry 77e0b76408
apply new rustfmt.toml changes, fix some clippy lints
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-12-15 01:00:41 -05:00

97 lines
2.2 KiB
Rust

use std::{fmt, sync::Arc};
use arrayvec::ArrayVec;
use tracing::field::{Field, Visit};
use tracing_core::{Event, Subscriber};
use tracing_subscriber::{layer::Context, registry::LookupSpan};
use super::{Capture, Data, State};
pub struct Layer {
state: Arc<State>,
}
struct Visitor {
values: Values,
}
type Values = ArrayVec<Value, 32>;
pub type Value = (&'static str, String);
type ScopeNames = ArrayVec<&'static str, 32>;
impl Layer {
#[inline]
pub fn new(state: &Arc<State>) -> Self { Self { state: state.clone() } }
}
impl fmt::Debug for Layer {
#[inline]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.debug_struct("capture::Layer").finish()
}
}
impl<S> tracing_subscriber::Layer<S> for Layer
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
self.state
.active
.read()
.expect("shared lock")
.iter()
.filter(|capture| filter(self, capture, event, &ctx))
.for_each(|capture| handle(self, capture, event, &ctx));
}
}
fn handle<S>(layer: &Layer, capture: &Capture, event: &Event<'_>, ctx: &Context<'_, S>)
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
let names = ScopeNames::new();
let mut visitor = Visitor { values: Values::new() };
event.record(&mut visitor);
let mut closure = capture.closure.lock().expect("exclusive lock");
closure(Data {
layer,
event,
current: &ctx.current_span(),
values: &visitor.values,
scope: &names,
});
}
fn filter<S>(layer: &Layer, capture: &Capture, event: &Event<'_>, ctx: &Context<'_, S>) -> bool
where
S: Subscriber + for<'a> LookupSpan<'a>,
{
let values = Values::new();
let mut names = ScopeNames::new();
if let Some(scope) = ctx.event_scope(event) {
for span in scope {
names.push(span.name());
}
}
capture.filter.as_ref().is_none_or(|filter| {
filter(Data {
layer,
event,
current: &ctx.current_span(),
values: &values,
scope: &names,
})
})
}
impl Visit for Visitor {
fn record_debug(&mut self, f: &Field, v: &dyn fmt::Debug) {
self.values.push((f.name(), format!("{v:?}")));
}
fn record_str(&mut self, f: &Field, v: &str) { self.values.push((f.name(), v.to_owned())); }
}