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