Skip to main content

miden_node_tracing/
lib.rs

1//! Miden node tracing conventions and OpenTelemetry integration.
2
3extern crate self as miden_node_tracing;
4
5mod attribute;
6pub mod grpc;
7mod instrument;
8mod logging;
9pub mod panic;
10mod span_ext;
11pub mod spawn;
12
13#[doc(hidden)]
14pub use attribute::field_name_allowed;
15pub use attribute::{RecordAttribute, record_attribute};
16#[cfg(feature = "testing")]
17pub use logging::setup_test_tracing;
18pub use logging::{
19    OpenTelemetry,
20    OtelGuard,
21    ResourceConfig,
22    TracingConfig,
23    setup_tracing,
24    setup_tracing_with_config,
25};
26pub use miden_node_tracing_macro::{
27    debug,
28    error,
29    info,
30    miden_instrument,
31    miden_span_record,
32    trace,
33    warn,
34};
35pub use span_ext::ErrorSpanExt;
36// Used directly by applications and by expansions of `tracing::instrument`.
37pub use tracing::{Instrument, Level, Span, Value, enabled, field, info_span};
38/// Upstream `tracing` exports required by generated macro code.
39#[doc(hidden)]
40pub use tracing::{event, if_log_enabled, level_enabled, span};
41
42/// Upstream attribute and event macros used by this crate's proc-macro expansions.
43#[doc(hidden)]
44pub mod __private {
45    pub use tracing::{debug, error, info, instrument, trace, warn};
46
47    pub use crate::instrument::AsDynError;
48}
49
50/// Extends errors with a stable string representation of their source chain.
51pub trait ErrorReport: std::error::Error {
52    /// Returns a string representation of the error and its source chain.
53    fn as_report(&self) -> String {
54        use std::fmt::Write;
55        let mut report = self.to_string();
56
57        std::iter::successors(self.source(), |child| child.source())
58            .for_each(|source| write!(report, "\ncaused by: {source}").unwrap());
59
60        report
61    }
62
63    /// Creates a new root in the error chain and returns the complete error report.
64    fn as_report_context(&self, context: &'static str) -> String {
65        format!("{context}: \ncaused by: {}", self.as_report())
66    }
67}
68
69impl<T: std::error::Error + ?Sized> ErrorReport for T {}
70
71#[cfg(test)]
72mod tests {
73    use super::ErrorReport;
74
75    #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
76    enum TestSourceError {
77        #[error("source error")]
78        Source,
79    }
80
81    #[derive(thiserror::Error, Debug)]
82    enum TestError {
83        #[error("parent error")]
84        Parent(#[from] TestSourceError),
85    }
86
87    #[test]
88    fn as_report() {
89        let error = TestError::Parent(TestSourceError::Source);
90        assert_eq!("parent error\ncaused by: source error", error.as_report());
91    }
92
93    #[test]
94    fn as_report_context() {
95        let error = TestError::Parent(TestSourceError::Source);
96        assert_eq!(
97            "final error: \ncaused by: parent error\ncaused by: source error",
98            error.as_report_context("final error")
99        );
100    }
101}