zlog: Use zlog as default log implementation (#28612)

Still TODO:

- [x] Remove old log implementations
- [x] More cleanup
- [x] Verify atomic/lock logic
- [x] More tests
- [ ] ??? Ansi coloring when logging to stdout

Release Notes:

- N/A
This commit is contained in:
Ben Kunkle 2025-04-14 10:17:07 -04:00 committed by GitHub
parent 0eb0a3c7dc
commit 4a57664c7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 872 additions and 706 deletions

View file

@ -108,7 +108,6 @@ session.workspace = true
settings.workspace = true
settings_ui.workspace = true
shellexpand.workspace = true
simplelog.workspace = true
smol.workspace = true
snippet_provider.workspace = true
snippets_ui.workspace = true

View file

@ -1,122 +0,0 @@
use chrono::Offset;
use env_logger::Builder;
use log::LevelFilter;
use simplelog::ConfigBuilder;
use std::fs::{self, File, OpenOptions};
use std::io::{self, Write};
use time::UtcOffset;
pub fn init_logger() {
let level = LevelFilter::Info;
// Prevent log file from becoming too large.
const KIB: u64 = 1024;
const MIB: u64 = 1024 * KIB;
const MAX_LOG_BYTES: u64 = MIB;
if std::fs::metadata(paths::log_file()).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES)
{
let _ = std::fs::rename(paths::log_file(), paths::old_log_file());
}
match LogWriter::new(MAX_LOG_BYTES) {
Ok(writer) => {
let mut config_builder = ConfigBuilder::new();
config_builder.set_time_format_rfc3339();
let local_offset = chrono::Local::now().offset().fix().local_minus_utc();
if let Ok(offset) = UtcOffset::from_whole_seconds(local_offset) {
config_builder.set_time_offset(offset);
}
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
{
config_builder.add_filter_ignore_str("zbus");
config_builder.add_filter_ignore_str("blade_graphics::hal::resource");
config_builder.add_filter_ignore_str("naga::back::spv::writer");
}
let config = config_builder.build();
simplelog::WriteLogger::init(level, config, writer)
.expect("could not initialize logger");
}
Err(err) => {
init_stdout_logger();
log::error!(
"could not open log file, defaulting to stdout logging: {}",
err
);
}
}
}
pub fn init_stdout_logger() {
Builder::new()
.parse_default_env()
.format(|buf, record| {
use env_logger::fmt::style::{AnsiColor, Style};
let subtle = Style::new().fg_color(Some(AnsiColor::BrightBlack.into()));
write!(buf, "{subtle}[{subtle:#}")?;
write!(
buf,
"{} ",
chrono::Local::now().format("%Y-%m-%dT%H:%M:%S%:z")
)?;
let level_style = buf.default_level_style(record.level());
write!(buf, "{level_style}{:<5}{level_style:#}", record.level())?;
if let Some(path) = record.module_path() {
write!(buf, " {path}")?;
}
write!(buf, "{subtle}]{subtle:#}")?;
writeln!(buf, " {}", record.args())
})
.init();
}
struct LogWriter {
file: File,
max_size: u64,
current_size: u64,
}
impl LogWriter {
fn new(max_size: u64) -> io::Result<Self> {
let file = OpenOptions::new()
.create(true)
.append(true)
.open(paths::log_file())?;
let current_size = file.metadata()?.len();
Ok(LogWriter {
file,
max_size,
current_size,
})
}
fn replace(&mut self) -> io::Result<()> {
self.file.sync_all()?;
fs::rename(paths::log_file(), paths::old_log_file())?;
self.file = OpenOptions::new()
.create(true)
.append(true)
.open(paths::log_file())?;
self.current_size = 0;
Ok(())
}
}
impl Write for LogWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.current_size + buf.len() as u64 > self.max_size {
self.replace()?;
}
let bytes = self.file.write(buf)?;
self.current_size += bytes as u64;
Ok(bytes)
}
fn flush(&mut self) -> io::Result<()> {
self.file.flush()
}
}

View file

@ -1,7 +1,6 @@
// Disable command line from opening on release mode
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
mod logger;
mod reliability;
mod zed;
@ -28,7 +27,6 @@ use prompt_store::PromptBuilder;
use reqwest_client::ReqwestClient;
use assets::Assets;
use logger::{init_logger, init_stdout_logger};
use node_runtime::{NodeBinaryOptions, NodeRuntime};
use parking_lot::Mutex;
use project::project_settings::ProjectSettings;
@ -195,11 +193,15 @@ fn main() {
return;
}
zlog::init_from_env();
zlog::init();
if stdout_is_a_pty() {
init_stdout_logger();
zlog::init_output_stdout();
} else {
init_logger();
let result = zlog::init_output_file(paths::log_file(), Some(paths::old_log_file()));
if let Err(err) = result {
eprintln!("Could not open log file: {}... Defaulting to stdout", err);
zlog::init_output_stdout();
};
}
log::info!("========== starting zed ==========");