log_json: cache an open failure so a misconfigured path doesn't re-issue an open() syscall (and silently drop) on every notice — the error is now surfaced once via stderr and not retried until the path changes; the write-failure reopen (for logrotate) is preserved
This commit is contained in:
parent
65bedaf417
commit
b557c9887f
1 changed files with 15 additions and 10 deletions
|
|
@ -11,8 +11,10 @@ use std::io::Write;
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
/// (configured path, open append handle) cached for reuse.
|
/// (configured path, open append handle or `None` if opening it failed) cached
|
||||||
static SINK: RefCell<Option<(String, File)>> = const { RefCell::new(None) };
|
/// for reuse. Caching the failure stops us re-issuing an `open` syscall — and a
|
||||||
|
/// silent drop — on every single notice when the path is misconfigured.
|
||||||
|
static SINK: RefCell<Option<(String, Option<File>)>> = const { RefCell::new(None) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append `msg` as a JSON line to the configured log file. Called at the tail of
|
/// Append `msg` as a JSON line to the configured log file. Called at the tail of
|
||||||
|
|
@ -30,16 +32,19 @@ pub fn tee(s: &Server, msg: &str) {
|
||||||
None => true,
|
None => true,
|
||||||
};
|
};
|
||||||
if need_open {
|
if need_open {
|
||||||
*slot = OpenOptions::new()
|
match OpenOptions::new().create(true).append(true).open(path) {
|
||||||
.create(true)
|
Ok(f) => *slot = Some((path.to_string(), Some(f))),
|
||||||
.append(true)
|
Err(e) => {
|
||||||
.open(path)
|
// surface once (this branch only runs when the path changes),
|
||||||
.ok()
|
// then remember the failure so we don't retry every notice
|
||||||
.map(|f| (path.to_string(), f));
|
eprintln!("echoircd: log_json cannot open {path}: {e}");
|
||||||
|
*slot = Some((path.to_string(), None));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some((_, f)) = slot.as_mut() {
|
if let Some((_, Some(f))) = slot.as_mut() {
|
||||||
if writeln!(f, "{line}").is_err() {
|
if writeln!(f, "{line}").is_err() {
|
||||||
*slot = None; // reopen next time
|
*slot = None; // reopen next time (e.g. after a logrotate rename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue