openmina_core/
log.rs

1/// Must only be used in logging and even there it's not preferable.
2///
3/// This **MUST** only be used in places which doesn't have access to any
4/// of the following: `redux::Store`, global state where time is stored,
5/// `redux::ActionMeta::time()`.
6pub fn system_time() -> redux::Timestamp {
7    redux::Timestamp::global_now()
8}
9
10pub fn time_to_str(t: redux::Timestamp) -> String {
11    let t = u64::from(t);
12    t.to_string()
13}
14
15pub fn to_rfc_3339(t: redux::Timestamp) -> time::Result<String> {
16    let t: u64 = t.into();
17    let datetime = time::OffsetDateTime::from_unix_timestamp_nanos(t as i128)?;
18    let format = time::format_description::well_known::Rfc3339;
19
20    Ok(datetime.format(&format)?)
21}
22
23// pub fn create_span(peer_id: &str) -> tracing::Span {
24//     tracing::span!(tracing::Level::INFO, "span", node_id = peer_id)
25// }
26
27pub mod inner {
28    pub use tracing::*;
29}
30
31#[macro_export]
32macro_rules! log_entry {
33    ($level:ident, $time:expr; $($tts:tt)*) => {
34        $crate::log::inner::$level!(time = $crate::log::time_to_str($time), $($tts)*);
35    };
36    ($level:ident; $($tts:tt)*) => {
37        $crate::log::inner::$level!(time = $crate::log::time_to_str($crate::log::system_time()), $($tts)*);
38    };
39}
40
41#[macro_export]
42macro_rules! trace {
43    ($time:expr; $($tts:tt)*) => {
44        $crate::log_entry!(trace, $time; $($tts)*);
45    };
46    ($($tts:tt)*) => {
47        $crate::log_entry!(trace; $($tts)*);
48    };
49}
50
51#[macro_export]
52macro_rules! debug {
53    ($time:expr; $($tts:tt)*) => {
54        $crate::log_entry!(debug, $time; $($tts)*);
55    };
56    ($($tts:tt)*) => {
57        $crate::log_entry!(debug; $($tts)*);
58    };
59}
60
61#[macro_export]
62macro_rules! info {
63    ($time:expr; $($tts:tt)*) => {
64        $crate::log_entry!(info, $time; $($tts)*);
65    };
66    ($($tts:tt)*) => {
67        $crate::log_entry!(info; $($tts)*);
68    };
69}
70
71#[macro_export]
72macro_rules! warn {
73    ($time:expr; $($tts:tt)*) => {
74        $crate::log_entry!(warn, $time; $($tts)*);
75    };
76    ($($tts:tt)*) => {
77        $crate::log_entry!(warn; $($tts)*);
78    };
79}
80
81#[macro_export]
82macro_rules! error {
83    ($time:expr; $($tts:tt)*) => {
84        $crate::log_entry!(error, $time; $($tts)*);
85    };
86    ($($tts:tt)*) => {
87        $crate::log_entry!(error; $($tts)*);
88    };
89}
90
91pub const ACTION_TRACE_TARGET: &str = "openmina_core::log::action";
92
93#[macro_export]
94macro_rules! action_event {
95    ($level:expr, $context:expr, $($tts:tt)*) => {
96        if $context.log_node_id() {
97            $crate::log::inner::event!(target: { $crate::log::ACTION_TRACE_TARGET }, $level, time = $context.time(), node_id = $context.node_id(), $($tts)*)
98        } else {
99            $crate::log::inner::event!(target: { $crate::log::ACTION_TRACE_TARGET }, $level, time = $context.time(), $($tts)*)
100        }
101    };
102    ($level:expr, $context:expr) => {
103        if $context.log_node_id() {
104            $crate::log::inner::event!(target: { $crate::log::ACTION_TRACE_TARGET }, $level, time = $context.time(), node_id = $context.node_id())
105        } else {
106            $crate::log::inner::event!(target: { $crate::log::ACTION_TRACE_TARGET }, $level, time = $context.time())
107        }
108    };
109}
110
111#[macro_export]
112macro_rules! action_error {
113    ($context:expr, $($tts:tt)*) => {
114        $crate::action_event!($crate::log::inner::Level::ERROR, $context, $($tts)*)
115    };
116    ($context:expr) => {
117        $crate::action_event!($crate::log::inner::Level::ERROR, $context)
118    };
119}
120
121#[macro_export]
122macro_rules! action_warn {
123    ($context:expr, $($tts:tt)*) => {
124        $crate::action_event!($crate::log::inner::Level::WARN, $context, $($tts)*)
125    };
126    ($context:expr) => {
127        $crate::action_event!($crate::log::inner::Level::WARN, $context)
128    };
129}
130
131#[macro_export]
132macro_rules! action_info {
133    ($context:expr, $($tts:tt)*) => {
134        $crate::action_event!($crate::log::inner::Level::INFO, $context, $($tts)*)
135    };
136    ($context:expr) => {
137        $crate::action_event!($crate::log::inner::Level::INFO, $context)
138    };
139}
140
141#[macro_export]
142macro_rules! action_debug {
143    ($context:expr, $($tts:tt)*) => {
144        $crate::action_event!($crate::log::inner::Level::DEBUG, $context, $($tts)*)
145    };
146    ($context:expr) => {
147        $crate::action_event!($crate::log::inner::Level::DEBUG, $context)
148    };
149}
150
151#[macro_export]
152macro_rules! action_trace {
153    ($context:expr, $($tts:tt)*) => {
154        $crate::action_event!($crate::log::inner::Level::TRACE, $context, $($tts)*)
155    };
156    ($context:expr) => {
157        $crate::action_event!($crate::log::inner::Level::TRACE, $context)
158    };
159}
160
161pub trait EventContext {
162    fn timestamp(&self) -> redux::Timestamp;
163    fn time(&self) -> &'_ dyn Value;
164    fn node_id(&self) -> &'_ dyn Value;
165    fn log_node_id(&self) -> bool;
166}
167
168pub trait ActionEvent {
169    fn action_event<T>(&self, context: &T)
170    where
171        T: EventContext;
172}
173
174use tracing::Value;
175
176pub use crate::{debug, error, info, trace, warn};
177
178#[macro_export]
179macro_rules! bug_condition {
180    ($($arg:tt)*) => {{
181        if std::env::var("OPENMINA_PANIC_ON_BUG")
182        .map(|v| ["true", "1"].contains(&v.to_lowercase().as_str()))
183        .unwrap_or(false) {
184            panic!($($arg)*)
185        } else {
186            $crate::log::inner::error!("BUG CONDITION: {}", format!($($arg)*))
187        }
188    }};
189}