tracing: Add support for span fields
This commit is contained in:
parent
31ba572811
commit
d1e0087bd5
|
@ -68,7 +68,10 @@ typedef struct TracingSpanGuard TracingSpanGuard;
|
||||||
/// Creates a span for a callsite.
|
/// Creates a span for a callsite.
|
||||||
///
|
///
|
||||||
/// The span must be freed when it goes out of scope.
|
/// The span must be freed when it goes out of scope.
|
||||||
TracingSpanHandle* tracing_span_create(const TracingCallsite* callsite);
|
TracingSpanHandle* tracing_span_create(
|
||||||
|
const TracingCallsite* callsite,
|
||||||
|
const char* const* field_values,
|
||||||
|
size_t fields_len);
|
||||||
|
|
||||||
/// Clones the given span.
|
/// Clones the given span.
|
||||||
///
|
///
|
||||||
|
@ -216,7 +219,7 @@ public:
|
||||||
Span() : inner(nullptr, tracing_span_free) {}
|
Span() : inner(nullptr, tracing_span_free) {}
|
||||||
|
|
||||||
/// Use the `TracingSpan` macro instead of calling this constructor directly.
|
/// Use the `TracingSpan` macro instead of calling this constructor directly.
|
||||||
Span(const TracingCallsite* callsite) : inner(tracing_span_create(callsite), tracing_span_free) {}
|
Span(const TracingCallsite* callsite, const char* const* field_values, size_t fields_len) : inner(tracing_span_create(callsite, field_values, fields_len), tracing_span_free) {}
|
||||||
|
|
||||||
Span(Span& span) : inner(std::move(span.inner)) {}
|
Span(Span& span) : inner(std::move(span.inner)) {}
|
||||||
Span(const Span& span) : inner(tracing_span_clone(span.inner.get()), tracing_span_free) {}
|
Span(const Span& span) : inner(tracing_span_clone(span.inner.get()), tracing_span_free) {}
|
||||||
|
@ -257,9 +260,31 @@ public:
|
||||||
/// strings.
|
/// strings.
|
||||||
#define TracingSpan(level, target, name) ([&] { \
|
#define TracingSpan(level, target, name) ([&] { \
|
||||||
static constexpr const char* const FIELDS[] = {}; \
|
static constexpr const char* const FIELDS[] = {}; \
|
||||||
|
const char* T_VALUES[] = {}; \
|
||||||
static TracingCallsite* CALLSITE = \
|
static TracingCallsite* CALLSITE = \
|
||||||
T_CALLSITE(name, target, level, FIELDS, true); \
|
T_CALLSITE(name, target, level, FIELDS, true); \
|
||||||
return tracing::Span(CALLSITE); \
|
return tracing::Span( \
|
||||||
|
CALLSITE, T_VALUES, T_ARRLEN(T_VALUES)); \
|
||||||
|
}())
|
||||||
|
|
||||||
|
/// Expands to a `tracing::Span` object which is used to record a span.
|
||||||
|
/// The `Span::Enter` method on that object records that the span has been
|
||||||
|
/// entered, and returns a RAII guard object, which will exit the span when
|
||||||
|
/// dropped.
|
||||||
|
///
|
||||||
|
/// Arguments: (level, target, name, key, value[, key2, value2, ...])
|
||||||
|
///
|
||||||
|
/// level, target, name, and all keys MUST be static constants, and MUST be
|
||||||
|
/// valid UTF-8 strings.
|
||||||
|
#define TracingSpanFields(level, target, name, ...) ([&] { \
|
||||||
|
static constexpr const char* const FIELDS[] = \
|
||||||
|
{T_FIELD_NAMES(__VA_ARGS__)}; \
|
||||||
|
const char* T_VALUES[] = \
|
||||||
|
{T_FIELD_VALUES(__VA_ARGS__)}; \
|
||||||
|
static TracingCallsite* CALLSITE = \
|
||||||
|
T_CALLSITE(name, target, level, FIELDS, true); \
|
||||||
|
return tracing::Span( \
|
||||||
|
CALLSITE, T_VALUES, T_ARRLEN(T_VALUES)); \
|
||||||
}())
|
}())
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,9 @@ pub extern "C" fn tracing_callsite(
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! repeat {
|
macro_rules! repeat {
|
||||||
|
(0, $val:expr) => {
|
||||||
|
[]
|
||||||
|
};
|
||||||
(1, $val:expr) => {
|
(1, $val:expr) => {
|
||||||
[$val]
|
[$val]
|
||||||
};
|
};
|
||||||
|
@ -435,14 +438,76 @@ macro_rules! repeat {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn tracing_span_create(callsite: *const FfiCallsite) -> *mut Span {
|
pub extern "C" fn tracing_span_create(
|
||||||
|
callsite: *const FfiCallsite,
|
||||||
|
field_values: *const *const c_char,
|
||||||
|
fields_len: usize,
|
||||||
|
) -> *mut Span {
|
||||||
let callsite = unsafe { &*callsite };
|
let callsite = unsafe { &*callsite };
|
||||||
|
let field_values = unsafe { slice::from_raw_parts(field_values, fields_len) };
|
||||||
|
|
||||||
let meta = callsite.metadata();
|
let meta = callsite.metadata();
|
||||||
assert!(meta.is_span());
|
assert!(meta.is_span());
|
||||||
|
|
||||||
let span = if level_enabled!(*meta.level()) && callsite.is_enabled() {
|
let span = if level_enabled!(*meta.level()) && callsite.is_enabled() {
|
||||||
Span::new(meta, &meta.fields().value_set(&[]))
|
let mut fi = meta.fields().iter();
|
||||||
|
let mut vi = field_values
|
||||||
|
.iter()
|
||||||
|
.map(|&p| unsafe { CStr::from_ptr(p) })
|
||||||
|
.map(|cs| cs.to_string_lossy());
|
||||||
|
|
||||||
|
macro_rules! new_span {
|
||||||
|
($n:tt) => {
|
||||||
|
Span::new(
|
||||||
|
meta,
|
||||||
|
&meta.fields().value_set(&repeat!(
|
||||||
|
$n,
|
||||||
|
(
|
||||||
|
&fi.next().unwrap(),
|
||||||
|
Some(&vi.next().unwrap().as_ref() as &dyn Value)
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/tokio-rs/tracing/issues/782 might help improve things here.
|
||||||
|
match field_values.len() {
|
||||||
|
0 => new_span!(0),
|
||||||
|
1 => new_span!(1),
|
||||||
|
2 => new_span!(2),
|
||||||
|
3 => new_span!(3),
|
||||||
|
4 => new_span!(4),
|
||||||
|
5 => new_span!(5),
|
||||||
|
6 => new_span!(6),
|
||||||
|
7 => new_span!(7),
|
||||||
|
8 => new_span!(8),
|
||||||
|
9 => new_span!(9),
|
||||||
|
10 => new_span!(10),
|
||||||
|
11 => new_span!(11),
|
||||||
|
12 => new_span!(12),
|
||||||
|
13 => new_span!(13),
|
||||||
|
14 => new_span!(14),
|
||||||
|
15 => new_span!(15),
|
||||||
|
16 => new_span!(16),
|
||||||
|
17 => new_span!(17),
|
||||||
|
18 => new_span!(18),
|
||||||
|
19 => new_span!(19),
|
||||||
|
20 => new_span!(20),
|
||||||
|
21 => new_span!(21),
|
||||||
|
22 => new_span!(22),
|
||||||
|
23 => new_span!(23),
|
||||||
|
24 => new_span!(24),
|
||||||
|
25 => new_span!(25),
|
||||||
|
26 => new_span!(26),
|
||||||
|
27 => new_span!(27),
|
||||||
|
28 => new_span!(28),
|
||||||
|
29 => new_span!(29),
|
||||||
|
30 => new_span!(30),
|
||||||
|
31 => new_span!(31),
|
||||||
|
32 => new_span!(32),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Span::none()
|
Span::none()
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue