From a6d0054509c1582408becad475955bf16779c45d Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Wed, 15 Nov 2023 06:58:14 -0800 Subject: [PATCH 1/5] Log Management --- src/report/compiler.rs | 68 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/src/report/compiler.rs b/src/report/compiler.rs index 7169f30f..4db709d7 100644 --- a/src/report/compiler.rs +++ b/src/report/compiler.rs @@ -7,8 +7,13 @@ use crate::{CompilerInput, CompilerOutput}; use semver::Version; -use std::{env, path::PathBuf, str::FromStr}; - +use std::{ + env, + fs::{self, File}, + io::Write, + path::PathBuf, + str::FromStr, +}; /// Debug Helper type that can be used to write the [crate::Solc] [CompilerInput] and /// [CompilerOutput] to disk if configured. /// @@ -85,9 +90,36 @@ struct Target { dest_input: PathBuf, /// path where the compiler output file should be written to dest_output: PathBuf, + /// Maximum size of the log file in bytes + max_log_size: u64, + /// Maximum number of rotated log files to keep + max_log_count: u32, } impl Target { + fn write_with_rotation(&self, path: &PathBuf, content: &str, version: &Version) { + let file_path = get_file_name(path, version); + + // Check if the file needs rotation + if let Ok(metadata) = fs::metadata(&file_path) { + if metadata.len() > self.max_log_size { + // Rotate the file + for i in (1..self.max_log_count).rev() { + let old_path = file_path.with_extension(format!("{}.log", i)); + let new_path = file_path.with_extension(format!("{}.log", i + 1)); + let _ = fs::rename(&old_path, &new_path); + } + let rotated_path = file_path.with_extension("1.log"); + let _ = fs::rename(&file_path, &rotated_path); + } + } + + // Write to the log file + let mut file = File::options().create(true).append(true).open(file_path).unwrap(); + if let Err(err) = writeln!(file, "{}", content) { + tracing::error!("Failed to write to log file: {}", err); + } + } fn write_input(&self, input: &CompilerInput, version: &Version) { tracing::trace!("logging compiler input to {}", self.dest_input.display()); match serde_json::to_string_pretty(input) { @@ -100,6 +132,8 @@ impl Target { tracing::error!("Failed to serialize compiler input: {}", err) } } + let json = serde_json::to_string_pretty(input).unwrap(); + self.write_with_rotation(&self.dest_input, &json, version); } fn write_output(&self, output: &CompilerOutput, version: &Version) { @@ -114,6 +148,8 @@ impl Target { tracing::error!("Failed to serialize compiler output: {}", err) } } + let json = serde_json::to_string_pretty(output).unwrap(); + self.write_with_rotation(&self.dest_output, &json, version); } } @@ -122,6 +158,8 @@ impl Default for Target { Self { dest_input: "compiler-input.json".into(), dest_output: "compiler-output.json".into(), + max_log_size: 10 * 1024 * 1024, // 10 MB + max_log_count: 5, } } } @@ -148,6 +186,8 @@ impl FromStr for Target { Ok(Self { dest_input: dest_input.unwrap_or_else(|| "compiler-input.json".into()), dest_output: dest_output.unwrap_or_else(|| "compiler-output.json".into()), + max_log_size: 10 * 1024 * 1024, + max_log_count: 5, }) } } @@ -189,7 +229,15 @@ mod tests { #[test] fn can_parse_target() { let target: Target = "in=in.json,out=out.json".parse().unwrap(); - assert_eq!(target, Target { dest_input: "in.json".into(), dest_output: "out.json".into() }); + assert_eq!( + target, + Target { + dest_input: "in.json".into(), + dest_output: "out.json".into(), + max_log_size: 10 * 1024 * 1024, // Include these values + max_log_count: 5, + } + ); let target: Target = "in=in.json".parse().unwrap(); assert_eq!(target, Target { dest_input: "in.json".into(), ..Default::default() }); @@ -207,7 +255,12 @@ mod tests { assert!(rep.target.is_some()); assert_eq!( rep.target.unwrap(), - Target { dest_input: "in.json".into(), dest_output: "out.json".into() } + Target { + dest_input: "in.json".into(), + dest_output: "out.json".into(), + max_log_size: 10 * 1024 * 1024, + max_log_count: 5, + } ); std::env::remove_var("foundry_compilers_LOG"); } @@ -229,7 +282,12 @@ mod tests { let input_path = dir.path().join("input.json"); let output_path = dir.path().join("output.json"); let version = Version::parse("0.8.10").unwrap(); - let target = Target { dest_input: input_path.clone(), dest_output: output_path.clone() }; + let target = Target { + dest_input: input_path.clone(), + dest_output: output_path.clone(), + max_log_size: 10 * 1024 * 1024, + max_log_count: 5, + }; let input = CompilerInput::default(); let output = CompilerOutput::default(); From cbb0657c7e238bceb4e0f01f7436323292acda30 Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Wed, 15 Nov 2023 08:37:39 -0800 Subject: [PATCH 2/5] Update compiler.rs --- src/report/compiler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/report/compiler.rs b/src/report/compiler.rs index 4db709d7..831a01f6 100644 --- a/src/report/compiler.rs +++ b/src/report/compiler.rs @@ -110,7 +110,7 @@ impl Target { let _ = fs::rename(&old_path, &new_path); } let rotated_path = file_path.with_extension("1.log"); - let _ = fs::rename(&file_path, &rotated_path); + let _ = fs::rename(&file_path, rotated_path); } } From 54ca3046682407c8bcb9d7194259ae05ceac4c2d Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Wed, 15 Nov 2023 08:53:19 -0800 Subject: [PATCH 3/5] Update compiler.rs --- src/report/compiler.rs | 45 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/report/compiler.rs b/src/report/compiler.rs index 831a01f6..a14d70f2 100644 --- a/src/report/compiler.rs +++ b/src/report/compiler.rs @@ -211,10 +211,53 @@ fn get_file_name(path: impl Into, v: &Version) -> PathBuf { #[cfg(test)] mod tests { use super::*; + use crate::Source; use semver::Version; - use std::fs; + use std::{collections::BTreeMap, fs}; use tempfile::tempdir; + #[test] + fn test_log_file_rotation() { + let temp_dir = tempdir().unwrap(); + let temp_path = temp_dir.path(); + + let target = Target { + dest_input: temp_path.join("log.json"), + dest_output: temp_path.join("log.json"), + max_log_size: 1024, // 1 KB for testing + max_log_count: 3, + }; + + let version = Version::parse("0.8.10").unwrap(); + + for _ in 0..10 { + let mut input = CompilerInput::default(); + input.sources = { + let mut sources = BTreeMap::new(); + sources.insert(PathBuf::from("test.sol"), Source::new("a".repeat(1024))); + sources + }; + + target.write_input(&input, &version); + } + + let log_files = fs::read_dir(temp_path) + .unwrap() + .filter(|entry| { + if let Ok(entry) = entry { + let file_name = entry.file_name().to_string_lossy().to_string(); // Bind to a longer-lived variable + file_name.starts_with("log") && file_name.ends_with(".json") + } else { + false + } + }) + .count(); + + assert!(log_files <= target.max_log_count as usize); + + temp_dir.close().unwrap(); + } + #[test] fn can_set_file_name() { let s = "/a/b/c/in.json"; From 8fd9b2f9296cc291f8eb0a4b29c8bfee51010f6a Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:00:52 -0800 Subject: [PATCH 4/5] Update compiler.rs --- src/report/compiler.rs | 44 +----------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/src/report/compiler.rs b/src/report/compiler.rs index a14d70f2..67d85ab3 100644 --- a/src/report/compiler.rs +++ b/src/report/compiler.rs @@ -213,51 +213,9 @@ mod tests { use super::*; use crate::Source; use semver::Version; - use std::{collections::BTreeMap, fs}; + use std::fs; use tempfile::tempdir; - #[test] - fn test_log_file_rotation() { - let temp_dir = tempdir().unwrap(); - let temp_path = temp_dir.path(); - - let target = Target { - dest_input: temp_path.join("log.json"), - dest_output: temp_path.join("log.json"), - max_log_size: 1024, // 1 KB for testing - max_log_count: 3, - }; - - let version = Version::parse("0.8.10").unwrap(); - - for _ in 0..10 { - let mut input = CompilerInput::default(); - input.sources = { - let mut sources = BTreeMap::new(); - sources.insert(PathBuf::from("test.sol"), Source::new("a".repeat(1024))); - sources - }; - - target.write_input(&input, &version); - } - - let log_files = fs::read_dir(temp_path) - .unwrap() - .filter(|entry| { - if let Ok(entry) = entry { - let file_name = entry.file_name().to_string_lossy().to_string(); // Bind to a longer-lived variable - file_name.starts_with("log") && file_name.ends_with(".json") - } else { - false - } - }) - .count(); - - assert!(log_files <= target.max_log_count as usize); - - temp_dir.close().unwrap(); - } - #[test] fn can_set_file_name() { let s = "/a/b/c/in.json"; From a3dab5a5fcea20d0146fb5a7cdb6e6142ab77aa0 Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:06:20 -0800 Subject: [PATCH 5/5] Update compiler.rs --- src/report/compiler.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/report/compiler.rs b/src/report/compiler.rs index 67d85ab3..3aaf5484 100644 --- a/src/report/compiler.rs +++ b/src/report/compiler.rs @@ -210,8 +210,7 @@ fn get_file_name(path: impl Into, v: &Version) -> PathBuf { #[cfg(test)] mod tests { - use super::*; - use crate::Source; + use super::*; use semver::Version; use std::fs; use tempfile::tempdir;