Add subcommand to print log file location
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/356/head
parent
5af2e1ee66
commit
62aee4644b
|
@ -95,6 +95,8 @@ Print location of configuration file that will be loaded on normal app startup.
|
||||||
Print default theme keys and values in TOML syntax, to be used as a blueprint.
|
Print default theme keys and values in TOML syntax, to be used as a blueprint.
|
||||||
.It Cm print-loaded-themes
|
.It Cm print-loaded-themes
|
||||||
Print all loaded themes in TOML syntax.
|
Print all loaded themes in TOML syntax.
|
||||||
|
.It Cm print-log-path
|
||||||
|
Print log file location.
|
||||||
.It Cm view
|
.It Cm view
|
||||||
View mail from input file.
|
View mail from input file.
|
||||||
.El
|
.El
|
||||||
|
|
|
@ -76,6 +76,8 @@ pub enum SubCommand {
|
||||||
#[structopt(display_order = 5)]
|
#[structopt(display_order = 5)]
|
||||||
/// print compile time feature flags of this binary
|
/// print compile time feature flags of this binary
|
||||||
CompiledWith,
|
CompiledWith,
|
||||||
|
/// Print log file location.
|
||||||
|
PrintLogPath,
|
||||||
/// View mail from input file.
|
/// View mail from input file.
|
||||||
View {
|
View {
|
||||||
#[structopt(value_name = "INPUT", parse(from_os_str))]
|
#[structopt(value_name = "INPUT", parse(from_os_str))]
|
||||||
|
|
|
@ -585,7 +585,7 @@ pub struct Settings {
|
||||||
pub terminal: TerminalSettings,
|
pub terminal: TerminalSettings,
|
||||||
pub log: LogSettings,
|
pub log: LogSettings,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
_logger: StderrLogger,
|
pub _logger: StderrLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
|
|
@ -157,6 +157,11 @@ fn run_app(opt: Opt) -> Result<()> {
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
Some(SubCommand::PrintLogPath) => {
|
||||||
|
let settings = crate::conf::Settings::new()?;
|
||||||
|
println!("{}", settings._logger.log_dest().display());
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use std::{fs::OpenOptions, path::PathBuf};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::{
|
use std::{
|
||||||
io::{BufWriter, Write},
|
io::{BufWriter, Write},
|
||||||
|
path::PathBuf,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU8, Ordering},
|
atomic::{AtomicU8, Ordering},
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
@ -133,12 +134,17 @@ pub enum Destination {
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FileOutput {
|
||||||
|
#[cfg(test)]
|
||||||
|
writer: BufWriter<std::io::Stderr>,
|
||||||
|
#[cfg(not(test))]
|
||||||
|
writer: BufWriter<std::fs::File>,
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct StderrLogger {
|
pub struct StderrLogger {
|
||||||
#[cfg(test)]
|
dest: Arc<Mutex<FileOutput>>,
|
||||||
dest: Arc<Mutex<BufWriter<std::io::Stderr>>>,
|
|
||||||
#[cfg(not(test))]
|
|
||||||
dest: Arc<Mutex<BufWriter<std::fs::File>>>,
|
|
||||||
level: Arc<AtomicU8>,
|
level: Arc<AtomicU8>,
|
||||||
print_level: bool,
|
print_level: bool,
|
||||||
print_module_names: bool,
|
print_module_names: bool,
|
||||||
|
@ -170,13 +176,23 @@ impl StderrLogger {
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
let logger = {
|
let logger = {
|
||||||
let data_dir = xdg::BaseDirectories::with_prefix("meli").unwrap();
|
#[inline(always)]
|
||||||
let log_file = OpenOptions::new().append(true) /* writes will append to a file instead of overwriting previous contents */
|
fn __inline_err_wrap() -> Result<(PathBuf, File), Box<dyn std::error::Error>> {
|
||||||
.create(true) /* a new file will be created if the file does not yet already exist.*/
|
let data_dir = xdg::BaseDirectories::with_prefix("meli")?;
|
||||||
.read(true)
|
let path = data_dir.place_data_file("meli.log")?;
|
||||||
.open(data_dir.place_data_file("meli.log").unwrap()).unwrap();
|
let log_file = OpenOptions::new().append(true) /* writes will append to a file instead of overwriting previous contents */
|
||||||
|
.create(true) /* a new file will be created if the file does not yet already exist.*/
|
||||||
|
.read(true)
|
||||||
|
.open(&path)?;
|
||||||
|
Ok((path, log_file))
|
||||||
|
}
|
||||||
|
let (path, log_file) =
|
||||||
|
__inline_err_wrap().expect("Could not create log file in XDG_DATA_DIR");
|
||||||
Self {
|
Self {
|
||||||
dest: Arc::new(Mutex::new(BufWriter::new(log_file))),
|
dest: Arc::new(Mutex::new(FileOutput {
|
||||||
|
writer: BufWriter::new(log_file),
|
||||||
|
path,
|
||||||
|
})),
|
||||||
level: Arc::new(AtomicU8::new(level as u8)),
|
level: Arc::new(AtomicU8::new(level as u8)),
|
||||||
print_level: true,
|
print_level: true,
|
||||||
print_module_names: true,
|
print_module_names: true,
|
||||||
|
@ -190,7 +206,10 @@ impl StderrLogger {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
let logger = {
|
let logger = {
|
||||||
Self {
|
Self {
|
||||||
dest: Arc::new(Mutex::new(BufWriter::new(std::io::stderr()))),
|
dest: Arc::new(Mutex::new(FileOutput {
|
||||||
|
writer: BufWriter::new(std::io::stderr()),
|
||||||
|
path: PathBuf::new(),
|
||||||
|
})),
|
||||||
level: Arc::new(AtomicU8::new(level as u8)),
|
level: Arc::new(AtomicU8::new(level as u8)),
|
||||||
print_level: true,
|
print_level: true,
|
||||||
print_module_names: true,
|
print_module_names: true,
|
||||||
|
@ -225,10 +244,17 @@ impl StderrLogger {
|
||||||
|
|
||||||
let path = path.expand(); // expand shell stuff
|
let path = path.expand(); // expand shell stuff
|
||||||
let mut dest = self.dest.lock().unwrap();
|
let mut dest = self.dest.lock().unwrap();
|
||||||
*dest = BufWriter::new(OpenOptions::new().append(true) /* writes will append to a file instead of overwriting previous contents */
|
*dest = FileOutput {
|
||||||
|
writer: BufWriter::new(OpenOptions::new().append(true) /* writes will append to a file instead of overwriting previous contents */
|
||||||
.create(true) /* a new file will be created if the file does not yet already exist.*/
|
.create(true) /* a new file will be created if the file does not yet already exist.*/
|
||||||
.read(true)
|
.read(true)
|
||||||
.open(path).unwrap());
|
.open(&path).unwrap()),
|
||||||
|
path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_dest(&self) -> PathBuf {
|
||||||
|
self.dest.lock().unwrap().path.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +310,7 @@ impl Log for StderrLogger {
|
||||||
(Destination::None | Destination::File, _) => {
|
(Destination::None | Destination::File, _) => {
|
||||||
_ = self.dest.lock().ok().and_then(|mut d| {
|
_ = self.dest.lock().ok().and_then(|mut d| {
|
||||||
write(
|
write(
|
||||||
&mut (*d),
|
&mut d.writer,
|
||||||
record,
|
record,
|
||||||
(self.print_level, self.print_module_names),
|
(self.print_level, self.print_module_names),
|
||||||
)
|
)
|
||||||
|
@ -293,7 +319,7 @@ impl Log for StderrLogger {
|
||||||
(Destination::Stderr, true) => {
|
(Destination::Stderr, true) => {
|
||||||
_ = self.dest.lock().ok().and_then(|mut d| {
|
_ = self.dest.lock().ok().and_then(|mut d| {
|
||||||
write(
|
write(
|
||||||
&mut (*d),
|
&mut d.writer,
|
||||||
record,
|
record,
|
||||||
(self.print_level, self.print_module_names),
|
(self.print_level, self.print_module_names),
|
||||||
)
|
)
|
||||||
|
@ -315,6 +341,9 @@ impl Log for StderrLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {
|
fn flush(&self) {
|
||||||
self.dest.lock().ok().and_then(|mut w| w.flush().ok());
|
self.dest
|
||||||
|
.lock()
|
||||||
|
.ok()
|
||||||
|
.and_then(|mut w| w.writer.flush().ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue