1use std::env;
2use std::path::Path;
3use std::str::FromStr;
4
5use log::LevelFilter;
6use log4rs::append::console::ConsoleAppender;
7use log4rs::append::rolling_file::policy::compound::roll::fixed_window::FixedWindowRoller;
8use log4rs::append::rolling_file::policy::compound::trigger::size::SizeTrigger;
9use log4rs::append::rolling_file::policy::compound::CompoundPolicy;
10use log4rs::append::rolling_file::RollingFileAppender;
11use log4rs::config::{load_config_file, Appender, Logger, Root};
12use log4rs::encode::pattern::PatternEncoder;
13use log4rs::filter::threshold::ThresholdFilter;
14use log4rs::Config;
15
16pub fn config_default(base_directory: &Path) -> Config {
17 Config::builder()
18 .appender(appender_stderr("stderr"))
19 .appender(appender_tofile(
20 "tofile",
21 base_directory.join("stats_puffin_main_broker.log"),
22 ))
23 .build(
24 Root::builder()
25 .appender("stderr")
26 .appender("tofile")
27 .build(log_level()),
28 )
29 .unwrap()
30}
31
32pub fn load_fuzzing_client() -> Config {
33 load_config_file("client_log_config.yml", Default::default()).unwrap()
34}
35
36fn appender_stderr<S>(name: S) -> Appender
37where
38 S: AsRef<str>,
39{
40 Appender::builder().build(
41 name.as_ref(),
42 Box::new(
43 ConsoleAppender::builder()
44 .target(log4rs::append::console::Target::Stderr)
45 .encoder(Box::new(PatternEncoder::new(
46 "{h({d(%Y-%m-%dT%H:%M:%S%Z)}\t{m}{n})}",
47 )))
48 .build(),
49 ),
50 )
51}
52
53fn appender_tofile<S, P>(name: S, log_path: P) -> Appender
54where
55 S: AsRef<str>,
56 P: AsRef<Path>,
57{
58 let window_size = 20; let fixed_window_roller = FixedWindowRoller::builder()
60 .build("log{}", window_size)
61 .unwrap();
62 let size_limit = 100 * 1024 * 1024; let size_trigger = SizeTrigger::new(size_limit);
64 let compound_policy =
65 CompoundPolicy::new(Box::new(size_trigger), Box::new(fixed_window_roller));
66
67 Appender::builder().build(
68 name.as_ref(),
69 Box::new(
70 RollingFileAppender::builder()
71 .encoder(Box::new(PatternEncoder::new("{d}\t{l}\t{m}{n}")))
72 .build(log_path, Box::new(compound_policy))
73 .unwrap(),
74 ),
75 )
76}
77
78fn log_level() -> LevelFilter {
79 env::var("RUST_LOG")
88 .ok()
89 .and_then(|level| LevelFilter::from_str(&level).ok())
90 .unwrap_or(LevelFilter::Info)
91}
92
93pub fn set_experiment_fuzzing_client(base_directory: &Path, level_filter: LevelFilter) -> Config {
94 let encoder = Box::new(PatternEncoder::new("{d}\t{l}\t{m}{n}"));
96
97 let stdout = ConsoleAppender::builder().build();
99
100 let max_log_size = 10 * 1024 * 1024; let build_rolling_appender = |path: &str, pattern: &str, filter: Option<LevelFilter>| {
103 let trigger = Box::new(SizeTrigger::new(max_log_size));
104 let roller = Box::new(
105 FixedWindowRoller::builder()
106 .base(1)
107 .build(
108 &format!("{}{}", base_directory.to_str().unwrap(), pattern),
109 20,
110 )
111 .unwrap(),
112 );
113
114 let policy = Box::new(CompoundPolicy::new(trigger, roller));
115 let rfa = RollingFileAppender::builder()
116 .encoder(encoder.clone())
117 .build(base_directory.join(path), policy)
118 .unwrap();
119 if let Some(filter) = filter {
120 Appender::builder()
121 .filter(Box::new(ThresholdFilter::new(filter)))
122 .build(path, Box::new(rfa))
123 } else {
124 Appender::builder().build(path, Box::new(rfa))
125 }
126 };
127
128 let fuzzer_log = build_rolling_appender("fuzzer.log", "fuzzer.{}.gz", None);
129 let harness_log = build_rolling_appender("harness.log", "harness.{}.gz", None);
130 let info_log = build_rolling_appender("info.log", "info.{}.gz", Some(LevelFilter::Info));
131 let warn_log = build_rolling_appender("warn.log", "warn.{}.gz", Some(LevelFilter::Warn));
132 let error_log = build_rolling_appender("error.log", "error.{}.gz", Some(LevelFilter::Error));
133
134 let config = Config::builder()
135 .appender(Appender::builder().build("stdout", Box::new(stdout)))
137 .appender(fuzzer_log)
138 .appender(harness_log)
139 .appender(info_log)
140 .appender(warn_log)
141 .appender(error_log);
142
143 let mut root_appenders = vec!["info.log", "warn.log", "error.log"];
144 let config = if level_filter >= LevelFilter::Debug {
147 root_appenders.push("debug.log");
148 let debug_log =
149 build_rolling_appender("debug.log", "debug.{}.gz", Some(LevelFilter::Debug));
150 config.appender(debug_log).logger(
151 Logger::builder()
152 .appenders(vec!["debug.log"])
153 .additive(true)
154 .build("debug", LevelFilter::Debug),
155 )
156 } else {
157 config
158 };
159
160 let config = if level_filter >= LevelFilter::Trace {
161 root_appenders.push("trace.log");
162 let trace_log =
163 build_rolling_appender("trace.log", "trace.{}.gz", Some(LevelFilter::Trace));
164 config.appender(trace_log).logger(
165 Logger::builder()
166 .appenders(vec!["trace.log"])
167 .additive(true)
168 .build("trace", LevelFilter::Trace),
169 )
170 } else {
171 config
172 };
173
174 config
176 .logger(Logger::builder()
177 .appenders(vec!["harness.log"])
178 .additive(true)
179 .build("puffin::harness", level_filter)) .logger(Logger::builder()
181 .appenders(vec!["fuzzer.log"])
182 .additive(true)
183 .build("puffin::fuzzer", level_filter))
184 .build(
186 Root::builder()
187 .appenders(root_appenders)
188 .build(log_level()),
189 )
190 .unwrap()
191}