mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-06 15:04:11 -04:00
ffi: Add filtering of tracing events and spans
This commit is contained in:
committed by
Jonas Platte
parent
50f29e5a11
commit
29068265db
@@ -7,8 +7,6 @@ use once_cell::sync::OnceCell;
|
||||
use tracing::{callsite::DefaultCallsite, field::FieldSet, Callsite};
|
||||
use tracing_core::{identify_callsite, metadata::Kind as MetadataKind};
|
||||
|
||||
type StaticMetadata = &'static tracing::Metadata<'static>;
|
||||
|
||||
#[uniffi::export]
|
||||
fn log_event(
|
||||
file: String,
|
||||
@@ -18,23 +16,27 @@ fn log_event(
|
||||
target: String,
|
||||
message: String,
|
||||
) {
|
||||
static METADATA: Mutex<BTreeMap<Location, StaticMetadata>> = Mutex::new(BTreeMap::new());
|
||||
static CALLSITES: Mutex<BTreeMap<Location, &'static DefaultCallsite>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
let loc = Location::new(file, line, column);
|
||||
let metadata = get_or_init_metadata(&METADATA, loc, level, target, |loc| {
|
||||
let callsite = get_or_init_metadata(&CALLSITES, loc, level, target, |loc| {
|
||||
(format!("event {}:{}", loc.file, loc.line), &["message"], MetadataKind::EVENT)
|
||||
});
|
||||
let metadata = callsite.metadata();
|
||||
|
||||
let fields = metadata.fields();
|
||||
let message_field = fields.field("message").unwrap();
|
||||
#[allow(trivial_casts)] // The compiler is lying, it can't infer this cast
|
||||
let values = [(&message_field, Some(&message as &dyn tracing::Value))];
|
||||
if span_or_event_enabled(callsite) {
|
||||
let fields = metadata.fields();
|
||||
let message_field = fields.field("message").unwrap();
|
||||
#[allow(trivial_casts)] // The compiler is lying, it can't infer this cast
|
||||
let values = [(&message_field, Some(&message as &dyn tracing::Value))];
|
||||
|
||||
// This function is hidden from docs, but we have to use it
|
||||
// because there is no other way of obtaining a `ValueSet`.
|
||||
// It's not entirely clear why it is private. See this issue:
|
||||
// https://github.com/tokio-rs/tracing/issues/2363
|
||||
let values = fields.value_set(&values);
|
||||
tracing::Event::dispatch(metadata, &values);
|
||||
// This function is hidden from docs, but we have to use it
|
||||
// because there is no other way of obtaining a `ValueSet`.
|
||||
// It's not entirely clear why it is private. See this issue:
|
||||
// https://github.com/tokio-rs/tracing/issues/2363
|
||||
let values = fields.value_set(&values);
|
||||
tracing::Event::dispatch(metadata, &values);
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
@@ -46,25 +48,34 @@ fn make_span(
|
||||
target: String,
|
||||
name: String,
|
||||
) -> Arc<Span> {
|
||||
static METADATA: Mutex<BTreeMap<Location, StaticMetadata>> = Mutex::new(BTreeMap::new());
|
||||
static CALLSITES: Mutex<BTreeMap<Location, &'static DefaultCallsite>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
let loc = Location::new(file, line, column);
|
||||
let metadata =
|
||||
get_or_init_metadata(&METADATA, loc, level, target, |_loc| (name, &[], MetadataKind::SPAN));
|
||||
let callsite = get_or_init_metadata(&CALLSITES, loc, level, target, |_loc| {
|
||||
(name, &[], MetadataKind::SPAN)
|
||||
});
|
||||
let metadata = callsite.metadata();
|
||||
|
||||
// This function is hidden from docs, but we have to use it (see above).
|
||||
let values = metadata.fields().value_set(&[]);
|
||||
Arc::new(Span(tracing::Span::new(metadata, &values)))
|
||||
let span = if span_or_event_enabled(callsite) {
|
||||
// This function is hidden from docs, but we have to use it (see above).
|
||||
let values = metadata.fields().value_set(&[]);
|
||||
tracing::Span::new(metadata, &values)
|
||||
} else {
|
||||
tracing::Span::none()
|
||||
};
|
||||
|
||||
Arc::new(Span(span))
|
||||
}
|
||||
|
||||
type FieldNames = &'static [&'static str];
|
||||
|
||||
fn get_or_init_metadata(
|
||||
mutex: &Mutex<BTreeMap<Location, StaticMetadata>>,
|
||||
mutex: &Mutex<BTreeMap<Location, &'static DefaultCallsite>>,
|
||||
loc: Location,
|
||||
level: LogLevel,
|
||||
target: String,
|
||||
get_details: impl FnOnce(&Location) -> (String, FieldNames, MetadataKind),
|
||||
) -> StaticMetadata {
|
||||
) -> &'static DefaultCallsite {
|
||||
mutex.lock().unwrap().entry(loc).or_insert_with_key(|loc| {
|
||||
let (name, field_names, span_kind) = get_details(loc);
|
||||
let callsite = Box::leak(Box::new(LateInitCallsite(OnceCell::new())));
|
||||
@@ -78,11 +89,28 @@ fn get_or_init_metadata(
|
||||
FieldSet::new(field_names, identify_callsite!(callsite)),
|
||||
span_kind,
|
||||
)));
|
||||
callsite.0.set(DefaultCallsite::new(metadata)).expect("callsite was not set before");
|
||||
metadata
|
||||
callsite.0.try_insert(DefaultCallsite::new(metadata)).expect("callsite was not set before")
|
||||
})
|
||||
}
|
||||
|
||||
fn span_or_event_enabled(callsite: &'static DefaultCallsite) -> bool {
|
||||
use tracing::{
|
||||
dispatcher,
|
||||
level_filters::{LevelFilter, STATIC_MAX_LEVEL},
|
||||
};
|
||||
|
||||
let meta = callsite.metadata();
|
||||
let level = *meta.level();
|
||||
|
||||
if level > STATIC_MAX_LEVEL || level > LevelFilter::current() {
|
||||
false
|
||||
} else {
|
||||
let interest = callsite.interest();
|
||||
interest.is_always()
|
||||
|| !interest.is_never() && dispatcher::get_default(|default| default.enabled(meta))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Span(tracing::Span);
|
||||
|
||||
impl Span {
|
||||
|
||||
Reference in New Issue
Block a user