Skip to content

Commit 2d6d17b

Browse files
committed
refactor: move huge context data away from logs main msg
And instead add them to a property. This allow to keep the main log messages leans while still providing detailed errors info.
1 parent 37af52e commit 2d6d17b

File tree

4 files changed

+130
-31
lines changed

4 files changed

+130
-31
lines changed

mithril-signer/src/main.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,7 @@ async fn main() -> StdResult<()> {
211211
loop {
212212
interval.tick().await;
213213
if let Err(err) = cardano_transaction_preloader.preload().await {
214-
crit!(
215-
preload_logger,
216-
"🔥 Cardano transactions preloader failed: {err:?}"
217-
);
214+
crit!(preload_logger, "🔥 Cardano transactions preloader failed"; "error" => ?err);
218215
}
219216
info!(
220217
preload_logger,
@@ -267,7 +264,7 @@ async fn main() -> StdResult<()> {
267264

268265
let shutdown_reason = match join_set.join_next().await {
269266
Some(Err(e)) => {
270-
crit!(root_logger, "A critical error occurred: {e:?}");
267+
crit!(root_logger, "A critical error occurred"; "error" => ?e);
271268
None
272269
}
273270
Some(Ok(res)) => res?,

mithril-signer/src/runtime/error.rs

Lines changed: 125 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use slog::{crit, error, Logger};
12
use std::fmt::Display;
23

34
use mithril_common::entities::EpochError;
@@ -40,39 +41,37 @@ impl RuntimeError {
4041
}
4142
)
4243
}
44+
45+
/// Write the error to the given logger.
46+
pub fn write_to_log(&self, logger: &Logger) {
47+
match self {
48+
Self::KeepState { nested_error, .. } => match nested_error {
49+
None => error!(logger, "{self}"),
50+
Some(err) => error!(logger, "{self}"; "nested_error" => ?err),
51+
},
52+
Self::Critical { nested_error, .. } => match nested_error {
53+
None => crit!(logger, "{self}"),
54+
Some(err) => crit!(logger, "{self}"; "nested_error" => ?err),
55+
},
56+
}
57+
}
4358
}
4459

4560
impl std::error::Error for RuntimeError {}
4661

4762
impl Display for RuntimeError {
4863
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4964
match self {
50-
Self::KeepState {
51-
message,
52-
nested_error,
53-
} => {
54-
let nested = if let Some(error) = nested_error {
55-
format!("nested error = {error:?}")
56-
} else {
57-
String::new()
58-
};
65+
Self::KeepState { message, .. } => {
5966
write!(
6067
f,
61-
"An error occurred, runtime state kept. message = '{message}'. {nested}"
68+
"An error occurred, runtime state kept. message = '{message}'"
6269
)
6370
}
64-
Self::Critical {
65-
message,
66-
nested_error,
67-
} => {
68-
let nested = if let Some(error) = nested_error {
69-
format!("nested error = {error:?}")
70-
} else {
71-
String::new()
72-
};
71+
Self::Critical { message, .. } => {
7372
write!(
7473
f,
75-
"A critical error occurred, aborting runtime. message = '{message}'. {nested}"
74+
"A critical error occurred, aborting runtime. message = '{message}'"
7675
)
7776
}
7877
}
@@ -96,3 +95,109 @@ impl From<EpochError> for RuntimeError {
9695
}
9796
}
9897
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use anyhow::anyhow;
102+
use std::path::Path;
103+
104+
use mithril_common::test_utils::TempDir;
105+
106+
use crate::test_tools::TestLogger;
107+
108+
use super::*;
109+
110+
/// Separate function so the logger is dropped and flushed before the assertion.
111+
fn write_log(log_file: &Path, error: &RuntimeError) {
112+
let logger = TestLogger::file(log_file);
113+
error.write_to_log(&logger);
114+
}
115+
116+
fn nested_error_debug_string(error: &RuntimeError) -> String {
117+
let error = match error {
118+
RuntimeError::KeepState { nested_error, .. } => nested_error,
119+
RuntimeError::Critical { nested_error, .. } => nested_error,
120+
};
121+
match error {
122+
None => String::new(),
123+
Some(err) => {
124+
format!("{err:?}")
125+
}
126+
}
127+
}
128+
129+
#[test]
130+
fn log_critical_without_nested_error() {
131+
let log_file = TempDir::create("signer_runtime_error", "log_critical_without_nested_error")
132+
.join("file.log");
133+
134+
let error = RuntimeError::Critical {
135+
message: "Critical error".to_string(),
136+
nested_error: None,
137+
};
138+
write_log(&log_file, &error);
139+
140+
let log_content = std::fs::read_to_string(&log_file).unwrap();
141+
assert!(log_content.contains(&format!("{error}")));
142+
assert!(!log_content.contains("nested_error"));
143+
}
144+
145+
#[test]
146+
fn log_critical_with_nested_error() {
147+
let log_file = TempDir::create("signer_runtime_error", "log_critical_with_nested_error")
148+
.join("file.log");
149+
150+
let error = RuntimeError::Critical {
151+
message: "Critical error".to_string(),
152+
nested_error: Some(
153+
anyhow!("Another context error")
154+
.context("Context error")
155+
.context("Critical nested error"),
156+
),
157+
};
158+
write_log(&log_file, &error);
159+
160+
let log_content = std::fs::read_to_string(&log_file).unwrap();
161+
assert!(log_content.contains(&format!("{error}")));
162+
assert!(log_content.contains(&nested_error_debug_string(&error)));
163+
}
164+
165+
#[test]
166+
fn log_keep_state_without_nested_error() {
167+
let log_file = TempDir::create(
168+
"signer_runtime_error",
169+
"log_keep_state_without_nested_error",
170+
)
171+
.join("file.log");
172+
173+
let error = RuntimeError::KeepState {
174+
message: "KeepState error".to_string(),
175+
nested_error: None,
176+
};
177+
write_log(&log_file, &error);
178+
179+
let log_content = std::fs::read_to_string(&log_file).unwrap();
180+
assert!(log_content.contains(&format!("{error}")));
181+
assert!(!log_content.contains("nested_error"));
182+
}
183+
184+
#[test]
185+
fn log_keep_state_with_nested_error() {
186+
let log_file = TempDir::create("signer_runtime_error", "log_keep_state_with_nested_error")
187+
.join("file.log");
188+
189+
let error = RuntimeError::KeepState {
190+
message: "KeepState error".to_string(),
191+
nested_error: Some(
192+
anyhow!("Another context error")
193+
.context("Context error")
194+
.context("KeepState nested error"),
195+
),
196+
};
197+
write_log(&log_file, &error);
198+
199+
let log_content = std::fs::read_to_string(&log_file).unwrap();
200+
assert!(log_content.contains(&format!("{error}")));
201+
assert!(log_content.contains(&nested_error_debug_string(&error)));
202+
}
203+
}

mithril-signer/src/runtime/state_machine.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use slog::{crit, debug, error, info, Logger};
1+
use slog::{debug, info, Logger};
22
use std::{fmt::Display, ops::Deref, sync::Arc, time::Duration};
33
use tokio::{sync::Mutex, time::sleep};
44

@@ -113,12 +113,9 @@ impl StateMachine {
113113

114114
loop {
115115
if let Err(e) = self.cycle().await {
116+
e.write_to_log(&self.logger);
116117
if e.is_critical() {
117-
crit!(self.logger, "{e}");
118-
119118
return Err(e);
120-
} else {
121-
error!(self.logger, "{e}");
122119
}
123120
}
124121

mithril-signer/src/services/epoch_service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl EpochService for MithrilEpochService {
177177
epoch_settings: SignerEpochSettings,
178178
allowed_discriminants: BTreeSet<SignedEntityTypeDiscriminants>,
179179
) -> StdResult<()> {
180-
debug!(self.logger, "register_epoch_settings: {:?}", epoch_settings);
180+
debug!(self.logger, "register_epoch_settings"; "epoch_settings" => ?epoch_settings);
181181

182182
let epoch = epoch_settings.epoch;
183183
let protocol_initializer = self

0 commit comments

Comments
 (0)