#[cfg(feature = "tracing-integration")]
pub use tracing::{
Instrument, Level, Span, debug, debug_span, error, error_span, event, info, info_span, span,
trace, trace_span, warn, warn_span,
};
#[cfg(feature = "proc-macros")]
pub use asupersync_macros::instrument;
#[cfg(not(feature = "tracing-integration"))]
mod noop {
#[macro_export]
macro_rules! trace {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! debug {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! info {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! warn {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! error {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! event {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules! span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
#[macro_export]
macro_rules! trace_span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
#[macro_export]
macro_rules! debug_span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
#[macro_export]
macro_rules! info_span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
#[macro_export]
macro_rules! warn_span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
#[macro_export]
macro_rules! error_span {
($($arg:tt)*) => {
$crate::tracing_compat::NoopSpan
};
}
pub use crate::{
debug, debug_span, error, error_span, event, info, info_span, span, trace, trace_span,
warn, warn_span,
};
}
#[cfg(not(feature = "tracing-integration"))]
pub use noop::*;
#[cfg(not(feature = "tracing-integration"))]
#[derive(Debug, Clone, Copy)]
pub struct NoopSpan;
#[cfg(not(feature = "tracing-integration"))]
impl NoopSpan {
#[inline]
#[must_use]
pub fn enter(&self) -> NoopGuard {
NoopGuard
}
#[inline]
#[must_use]
pub fn entered(self) -> Self {
self
}
#[inline]
#[must_use]
pub fn or_current(self) -> Self {
self
}
#[inline]
pub fn follows_from(&self, _span: &Self) {}
#[inline]
#[must_use]
pub fn is_disabled(&self) -> bool {
true
}
#[inline]
pub fn record<V>(&self, _field: &str, _value: V) {}
#[inline]
#[must_use]
pub fn current() -> Self {
Self
}
#[inline]
#[must_use]
pub fn none() -> Self {
Self
}
}
#[cfg(not(feature = "tracing-integration"))]
#[derive(Debug)]
pub struct NoopGuard;
#[cfg(not(feature = "tracing-integration"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Level;
#[cfg(not(feature = "tracing-integration"))]
impl Level {
pub const TRACE: Self = Self;
pub const DEBUG: Self = Self;
pub const INFO: Self = Self;
pub const WARN: Self = Self;
pub const ERROR: Self = Self;
}
#[cfg(not(feature = "tracing-integration"))]
pub type Span = NoopSpan;
#[cfg(not(feature = "tracing-integration"))]
pub trait Instrument: Sized {
#[must_use]
fn instrument(self, _span: NoopSpan) -> Self {
self
}
#[must_use]
fn in_current_span(self) -> Self {
self
}
}
#[cfg(not(feature = "tracing-integration"))]
impl<T> Instrument for T {}
#[cfg(test)]
mod tests {
#![allow(
clippy::pedantic,
clippy::nursery,
clippy::expect_fun_call,
clippy::map_unwrap_or,
clippy::cast_possible_wrap,
clippy::future_not_send
)]
use super::*;
use crate::test_utils::init_test_logging;
#[cfg(feature = "proc-macros")]
use futures_lite::future::block_on;
fn init_test(test_name: &str) {
init_test_logging();
crate::test_phase!(test_name);
}
#[cfg(feature = "proc-macros")]
#[super::instrument]
fn instrumented_sync_add(task_id: u32, label: &str) -> usize {
usize::try_from(task_id).expect("task_id fits usize") + label.len()
}
#[cfg(feature = "proc-macros")]
struct InstrumentedWorker;
#[cfg(feature = "proc-macros")]
impl InstrumentedWorker {
#[super::instrument(level = "debug", skip(self))]
fn tick(&self, value: usize) -> usize {
value + 1
}
}
#[cfg(feature = "proc-macros")]
#[super::instrument(name = "instrumented_async_len", level = "trace", skip(secret))]
async fn instrumented_async_len(secret: String, visible: usize) -> usize {
visible + secret.len()
}
#[test]
fn test_noop_macros_compile() {
init_test("test_noop_macros_compile");
trace!("trace message");
debug!("debug message");
info!("info message");
warn!("warn message");
error!("error message");
trace!(field = "value", "trace with field");
debug!(count = 42, "debug with field");
info!(name = "test", "info with field");
crate::test_complete!("test_noop_macros_compile");
}
#[test]
fn test_noop_span_compile() {
init_test("test_noop_span_compile");
let span = span!(Level::INFO, "test_span");
let _guard = span.enter();
let span2 = info_span!("info_span");
let _entered = span2.entered();
let span3 = debug_span!("debug_span", task_id = 42);
span3.record("field", "value");
crate::test_complete!("test_noop_span_compile");
}
#[test]
fn test_noop_level_constants() {
init_test("test_noop_level_constants");
crate::test_complete!("test_noop_level_constants");
}
#[test]
fn test_noop_span_methods() {
init_test("test_noop_span_methods");
#[cfg(not(feature = "tracing-integration"))]
{
let span = NoopSpan;
let disabled = span.is_disabled();
crate::assert_with_log!(disabled, "noop span should be disabled", true, disabled);
let current = NoopSpan::current();
let none = NoopSpan::none();
let _ = current.or_current();
none.follows_from(&span);
}
crate::test_complete!("test_noop_span_methods");
}
#[test]
fn noop_guard_debug() {
#[cfg(not(feature = "tracing-integration"))]
{
let guard = NoopGuard;
let dbg = format!("{guard:?}");
assert!(dbg.contains("NoopGuard"), "{dbg}");
}
}
#[test]
fn noop_span_debug_clone_copy() {
#[cfg(not(feature = "tracing-integration"))]
{
let span = NoopSpan;
let dbg = format!("{span:?}");
assert!(dbg.contains("NoopSpan"), "{dbg}");
let copied = span;
let cloned = span;
assert!(copied.is_disabled());
assert!(cloned.is_disabled());
}
}
#[test]
fn level_equality_and_ordering() {
#[cfg(not(feature = "tracing-integration"))]
{
assert_eq!(Level::TRACE, Level::DEBUG);
assert_eq!(Level::INFO, Level::WARN);
assert_eq!(Level::WARN, Level::ERROR);
assert!(Level::TRACE <= Level::ERROR);
let dbg = format!("{:?}", Level::INFO);
assert!(dbg.contains("Level"), "{dbg}");
let l = Level::INFO;
let copied = l;
let cloned = l;
assert_eq!(copied, cloned);
}
}
#[test]
fn span_type_alias_works() {
#[cfg(not(feature = "tracing-integration"))]
{
let span: Span = NoopSpan::current();
let _guard = span.enter();
}
}
#[test]
fn all_span_macros_compile() {
#[cfg(not(feature = "tracing-integration"))]
{
let _ = trace_span!("t");
let _ = debug_span!("d");
let _ = info_span!("i");
let _ = warn_span!("w");
let _ = error_span!("e");
}
}
#[test]
fn instrument_trait_noop() {
#[cfg(not(feature = "tracing-integration"))]
{
let fut = async { 42 };
let instrumented = fut.instrument(NoopSpan);
drop(async { 1 }.in_current_span());
drop(instrumented);
}
}
#[cfg(feature = "proc-macros")]
#[test]
fn instrument_attribute_wraps_sync_functions() {
init_test("instrument_attribute_wraps_sync_functions");
let value = instrumented_sync_add(7, "abc");
crate::assert_with_log!(value == 10, "sync result", 10usize, value);
crate::test_complete!("instrument_attribute_wraps_sync_functions");
}
#[cfg(feature = "proc-macros")]
#[test]
fn instrument_attribute_wraps_methods() {
init_test("instrument_attribute_wraps_methods");
let worker = InstrumentedWorker;
let value = worker.tick(9);
crate::assert_with_log!(value == 10, "method result", 10usize, value);
crate::test_complete!("instrument_attribute_wraps_methods");
}
#[cfg(feature = "proc-macros")]
#[test]
fn instrument_attribute_wraps_async_functions() {
init_test("instrument_attribute_wraps_async_functions");
let value = block_on(instrumented_async_len("secret".to_string(), 4));
crate::assert_with_log!(value == 10, "async result", 10usize, value);
crate::test_complete!("instrument_attribute_wraps_async_functions");
}
}