unc_o11y/
lib.rs

1#![doc = include_str!("../README.md")]
2#![deny(clippy::arithmetic_side_effects)]
3
4pub use context::*;
5pub use env_filter::{BuildEnvFilterError, EnvFilterBuilder};
6pub use opentelemetry::OpenTelemetryLevel;
7pub use reload::{reload, reload_log_config};
8#[cfg(feature = "io_trace")]
9pub use subscriber::make_io_tracing_layer;
10pub use subscriber::{default_subscriber, default_subscriber_with_opentelemetry, Options};
11pub use tracing_opentelemetry::OpenTelemetrySpanExt;
12pub use {tracing, tracing_appender, tracing_subscriber};
13
14/// Custom tracing subscriber implementation that produces IO traces.
15pub mod context;
16pub mod env_filter;
17mod io_tracer;
18pub mod log_config;
19mod log_counter;
20pub mod macros;
21pub mod metrics;
22mod opentelemetry;
23mod reload;
24mod subscriber;
25pub mod testonly;
26
27/// Produce a tracing-event for target "io_tracer" that will be consumed by the
28/// IO-tracer, if the feature has been enabled.
29#[macro_export]
30#[cfg(feature = "io_trace")]
31macro_rules! io_trace {
32    (count: $name:expr) => { tracing::trace!( target: "io_tracer_count", counter = $name) };
33    ($($fields:tt)*) => { tracing::trace!( target: "io_tracer", $($fields)*) };
34}
35
36#[macro_export]
37#[cfg(not(feature = "io_trace"))]
38macro_rules! io_trace {
39    (count: $name:expr) => {};
40    ($($fields:tt)*) => {};
41}
42
43/// Prints backtrace to stderr.
44///
45/// This is intended as a printf-debugging aid.
46pub fn print_backtrace() {
47    let bt = std::backtrace::Backtrace::force_capture();
48    eprintln!("{bt:?}")
49}
50
51/// Asserts that the condition is true, logging an error otherwise.
52///
53/// This macro complements `assert!` and `debug_assert`. All three macros should
54/// only be used for conditions, whose violation signifise a programming error.
55/// All three macros are no-ops if the condition is true.
56///
57/// The behavior when the condition is false (i.e. when the assert fails) is
58/// different, and informs different usage patterns.
59///
60/// `assert!` panics. Use it for sanity-checking invariants, whose violation can
61/// compromise correctness of the protocol. For example, it's better to shut a
62/// node down via a panic than to admit potentially non-deterministic behavior.
63///
64/// `debug_assert!` panics if `cfg(debug_assertions)` is true, that is, only
65/// during development. In production, `debug_assert!` is compiled away (that
66/// is, the condition is not evaluated at all). Use `debug_assert!` if
67/// evaluating the condition is too slow. In other words, `debug_assert!` is a
68/// performance optimization.
69///
70/// Finally, `log_assert!` panics in debug mode, while in release mode it emits
71/// a `tracing::error!` log line. Use it for sanity-checking non-essential
72/// invariants, whose violation signals a bug in the code, where we'd rather
73/// avoid shutting the whole node down.
74///
75/// For example, `log_assert` is a great choice to use in some auxilary code
76/// paths -- would be a shame if a bug in, eg, metrics collection code brought
77/// the whole network down.
78///
79/// Another use case is adding new asserts to the old code -- if you are only
80/// 99% sure that the assert is correct, and there's evidance that the old code
81/// is working fine in practice, `log_assert!` is the right choice!
82///
83/// References:
84///   * <https://www.sqlite.org/assert.html>
85#[macro_export]
86macro_rules! log_assert {
87    ($cond:expr) => {
88        $crate::log_assert!($cond, "assertion failed: {}", stringify!($cond))
89    };
90
91    ($cond:expr, $fmt:literal $($arg:tt)*) => {
92        if cfg!(debug_assertions) {
93            assert!($cond, $fmt $($arg)*);
94        } else {
95            if !$cond {
96                $crate::tracing::error!($fmt $($arg)*);
97            }
98        }
99    };
100}
101
102/// The same as 'log_assert' but always fails.
103///
104/// `log_assert_fail!` panics in debug mode, while in release mode it emits
105/// a `tracing::error!` log line. Use it for sanity-checking non-essential
106/// invariants, whose violation signals a bug in the code, where we'd rather
107/// avoid shutting the whole node down.
108#[macro_export]
109macro_rules! log_assert_fail {
110    ($fmt:literal $($arg:tt)*) => {
111        $crate::log_assert!(false, $fmt $($arg)*);
112    };
113}