mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-24 08:36:10 -04:00
ffi: Make tracing more flexible
… at the expense of some performance.
This commit is contained in:
committed by
Benjamin Bouvier
parent
6e62569b8a
commit
f7d52dfdc1
@@ -15,10 +15,10 @@ use tracing_core::{identify_callsite, metadata::Kind as MetadataKind};
|
||||
/// not be changed afterwards, i.e. the level and target passed for second and
|
||||
/// following `log_event`s with the same callsite will be ignored.
|
||||
///
|
||||
/// This function leaks a little bit of memory for each unique callsite it is
|
||||
/// called with. Please make sure that the number of different
|
||||
/// `(file, line, column)` tuples that this can be called with is fixed in the
|
||||
/// final executable.
|
||||
/// This function leaks a little bit of memory for each unique (file + line +
|
||||
/// column + level + target) it is called with. Please make sure that the number
|
||||
/// of different combinations of those parameters this can be called with is
|
||||
/// constant in the final executable.
|
||||
#[uniffi::export]
|
||||
fn log_event(
|
||||
file: String,
|
||||
@@ -28,12 +28,11 @@ fn log_event(
|
||||
target: String,
|
||||
message: String,
|
||||
) {
|
||||
static CALLSITES: Mutex<BTreeMap<Location, &'static DefaultCallsite>> =
|
||||
static CALLSITES: Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
let loc = Location::new(file, line, column);
|
||||
let callsite = get_or_init_metadata(&CALLSITES, loc, level, target, |loc| {
|
||||
(format!("event {}:{}", loc.file, loc.line), &["message"], MetadataKind::EVENT)
|
||||
});
|
||||
|
||||
let id = MetadataId::new(file, line, column, level, target, None);
|
||||
let callsite = get_or_init_metadata(&CALLSITES, id, &["message"], MetadataKind::EVENT);
|
||||
let metadata = callsite.metadata();
|
||||
|
||||
if span_or_event_enabled(callsite) {
|
||||
@@ -54,24 +53,27 @@ fn log_event(
|
||||
type FieldNames = &'static [&'static str];
|
||||
|
||||
fn get_or_init_metadata(
|
||||
mutex: &Mutex<BTreeMap<Location, &'static DefaultCallsite>>,
|
||||
loc: Location,
|
||||
level: LogLevel,
|
||||
target: String,
|
||||
get_details: impl FnOnce(&Location) -> (String, FieldNames, MetadataKind),
|
||||
mutex: &Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>>,
|
||||
id: MetadataId,
|
||||
field_names: FieldNames,
|
||||
meta_kind: MetadataKind,
|
||||
) -> &'static DefaultCallsite {
|
||||
mutex.lock().unwrap().entry(loc).or_insert_with_key(|loc| {
|
||||
let (name, field_names, span_kind) = get_details(loc);
|
||||
mutex.lock().unwrap().entry(id).or_insert_with_key(|id| {
|
||||
let callsite = Box::leak(Box::new(LateInitCallsite(OnceCell::new())));
|
||||
let metadata = Box::leak(Box::new(tracing::Metadata::new(
|
||||
Box::leak(name.into_boxed_str()),
|
||||
Box::leak(target.into_boxed_str()),
|
||||
level.to_tracing_level(),
|
||||
Some(Box::leak(Box::from(loc.file.as_str()))),
|
||||
Some(loc.line),
|
||||
Box::leak(
|
||||
id.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("event {}:{}", id.file, id.line))
|
||||
.into_boxed_str(),
|
||||
),
|
||||
Box::leak(id.target.as_str().into()),
|
||||
id.level.to_tracing_level(),
|
||||
Some(Box::leak(Box::from(id.file.as_str()))),
|
||||
Some(id.line),
|
||||
None, // module path
|
||||
FieldSet::new(field_names, identify_callsite!(callsite)),
|
||||
span_kind,
|
||||
meta_kind,
|
||||
)));
|
||||
callsite.0.try_insert(DefaultCallsite::new(metadata)).expect("callsite was not set before")
|
||||
})
|
||||
@@ -109,10 +111,10 @@ impl Span {
|
||||
/// target passed for second and following creation of a span with the same
|
||||
/// callsite will be ignored.
|
||||
///
|
||||
/// This function leaks a little bit of memory for each unique callsite it
|
||||
/// is called with. Please make sure that the number of different
|
||||
/// `(file, line, column)` tuples that this can be called with is fixed in
|
||||
/// the final executable.
|
||||
/// This function leaks a little bit of memory for each unique (file + line
|
||||
/// + column + level + target + name) it is called with. Please make sure
|
||||
/// that the number of different combinations of those parameters this can
|
||||
/// be called with is constant in the final executable.
|
||||
///
|
||||
/// For a span to have an effect, you must `.enter()` it at the start of a
|
||||
/// logical unit of work and `.exit()` it at the end of the same (including
|
||||
@@ -133,12 +135,11 @@ impl Span {
|
||||
target: String,
|
||||
name: String,
|
||||
) -> Arc<Self> {
|
||||
static CALLSITES: Mutex<BTreeMap<Location, &'static DefaultCallsite>> =
|
||||
static CALLSITES: Mutex<BTreeMap<MetadataId, &'static DefaultCallsite>> =
|
||||
Mutex::new(BTreeMap::new());
|
||||
let loc = Location::new(file, line, column);
|
||||
let callsite = get_or_init_metadata(&CALLSITES, loc, level, target, |_loc| {
|
||||
(name, &[], MetadataKind::SPAN)
|
||||
});
|
||||
|
||||
let loc = MetadataId::new(file, line, column, level, target, Some(name));
|
||||
let callsite = get_or_init_metadata(&CALLSITES, loc, &[], MetadataKind::SPAN);
|
||||
let metadata = callsite.metadata();
|
||||
|
||||
let span = if span_or_event_enabled(callsite) {
|
||||
@@ -170,7 +171,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uniffi::Enum)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, uniffi::Enum)]
|
||||
pub enum LogLevel {
|
||||
Error,
|
||||
Warn,
|
||||
@@ -192,15 +193,25 @@ impl LogLevel {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct Location {
|
||||
struct MetadataId {
|
||||
file: String,
|
||||
line: u32,
|
||||
column: u32,
|
||||
level: LogLevel,
|
||||
target: String,
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
impl Location {
|
||||
fn new(file: String, line: u32, column: u32) -> Self {
|
||||
Self { file, line, column }
|
||||
impl MetadataId {
|
||||
fn new(
|
||||
file: String,
|
||||
line: u32,
|
||||
column: u32,
|
||||
level: LogLevel,
|
||||
target: String,
|
||||
name: Option<String>,
|
||||
) -> Self {
|
||||
Self { file, line, column, level, target, name }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user