1pub 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
23pub 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}