Print multiline logs in one write call

Fixes potential split of multiline logs in the multithreaded context
by writing them all at once.
This commit is contained in:
Kirill Chibisov 2020-12-10 09:00:54 +03:00 committed by GitHub
parent 5ececc3105
commit 8e6a608b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 12 deletions

View File

@ -228,8 +228,7 @@ fn load_imports(config: &Value, config_paths: &mut Vec<PathBuf>, recursion_limit
} }
if !path.exists() { if !path.exists() {
info!(target: LOG_TARGET_CONFIG, "Skipping importing config; not found:"); info!(target: LOG_TARGET_CONFIG, "Config import not found:\n {:?}", path.display());
info!(target: LOG_TARGET_CONFIG, " {:?}", path.display());
continue; continue;
} }

View File

@ -72,7 +72,7 @@ impl Logger {
#[cfg(windows)] #[cfg(windows)]
let env_var = format!("%{}%", ALACRITTY_LOG_ENV); let env_var = format!("%{}%", ALACRITTY_LOG_ENV);
let msg = format!( let message = format!(
"[{}] See log at {} ({}):\n{}", "[{}] See log at {} ({}):\n{}",
record.level(), record.level(),
logfile_path, logfile_path,
@ -85,7 +85,7 @@ impl Logger {
_ => unreachable!(), _ => unreachable!(),
}; };
let mut message = Message::new(msg, message_type); let mut message = Message::new(message, message_type);
message.set_target(record.target().to_owned()); message.set_target(record.target().to_owned());
let _ = event_proxy.send_event(Event::Message(message)); let _ = event_proxy.send_event(Event::Message(message));
@ -107,12 +107,12 @@ impl log::Log for Logger {
return; return;
} }
let now = time::strftime("%F %T.%f", &time::now()).unwrap(); // Create log message for the given `record` and `target`.
let msg = format!("[{}] [{:<5}] [{}] {}\n", now, record.level(), target, record.args()); let message = create_log_message(record, &target);
if let Ok(mut logfile) = self.logfile.lock() { if let Ok(mut logfile) = self.logfile.lock() {
// Write to logfile. // Write to logfile.
let _ = logfile.write_all(msg.as_ref()); let _ = logfile.write_all(message.as_ref());
// Write to message bar. // Write to message bar.
if record.level() <= Level::Warn { if record.level() <= Level::Warn {
@ -122,13 +122,33 @@ impl log::Log for Logger {
// Write to stdout. // Write to stdout.
if let Ok(mut stdout) = self.stdout.lock() { if let Ok(mut stdout) = self.stdout.lock() {
let _ = stdout.write_all(msg.as_ref()); let _ = stdout.write_all(message.as_ref());
} }
} }
fn flush(&self) {} fn flush(&self) {}
} }
fn create_log_message(record: &log::Record<'_>, target: &str) -> String {
let now = time::strftime("%F %T.%f", &time::now()).unwrap();
let mut message = format!("[{}] [{:<5}] [{}] ", now, record.level(), target);
// Alignment for the lines after the first new line character in the payload. We don't deal
// with fullwidth/unicode chars here, so just `message.len()` is sufficient.
let alignment = message.len();
// Push lines with added extra padding on the next line, which is trimmed later.
let lines = record.args().to_string();
for line in lines.split('\n') {
let line = format!("{}\n{:width$}", line, "", width = alignment);
message.push_str(&line);
}
// Drop extra trailing alignment.
message.truncate(message.len() - alignment);
message
}
struct OnDemandLogFile { struct OnDemandLogFile {
file: Option<LineWriter<File>>, file: Option<LineWriter<File>>,
created: Arc<AtomicBool>, created: Arc<AtomicBool>,

View File

@ -130,10 +130,8 @@ fn run(
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
info!("Welcome to Alacritty"); info!("Welcome to Alacritty");
info!("Configuration files loaded from:"); // Log the configuration paths.
for path in &config.ui_config.config_paths { log_config_path(&config);
info!(" \"{}\"", path.display());
}
// Set environment variables. // Set environment variables.
tty::setup_env(&config); tty::setup_env(&config);
@ -242,3 +240,12 @@ fn run(
Ok(()) Ok(())
} }
fn log_config_path(config: &Config) {
let mut msg = String::from("Configuration files loaded from:");
for path in &config.ui_config.config_paths {
msg.push_str(&format!("\n {:?}", path.display()));
}
info!("{}", msg);
}