log error handlin

This commit is contained in:
Christoph J. Scherr 2024-01-16 10:18:29 +01:00
parent c679bed538
commit 074dcf9c0f
Signed by: cscherrNT
GPG Key ID: 8E2B45BC51A27EA7
4 changed files with 14 additions and 87 deletions

View File

@ -34,6 +34,8 @@ categories = ["command-line-utilities", "development-tools", "development-tools:
[workspace.dependencies] [workspace.dependencies]
pyo3 = "0.19" pyo3 = "0.19"
anyhow = "1.0.79"
thiserror = "1.0.56"
[package] [package]
name = "libpt" name = "libpt"

View File

@ -16,7 +16,8 @@ categories.workspace = true
tracing = "0.1.37" tracing = "0.1.37"
tracing-appender = "0.2.2" tracing-appender = "0.2.2"
tracing-subscriber = "0.3.17" tracing-subscriber = "0.3.17"
pyo3 = {workspace = true} anyhow = { workspace = true }
thiserror = { workspace = true }
[dev-dependencies] [dev-dependencies]
gag = "1.0.0" gag = "1.0.0"

View File

@ -12,12 +12,11 @@
#![warn(clippy::pedantic)] #![warn(clippy::pedantic)]
//// IMPORTS /////////////////////////////////////////////////////////////////////////////////////// //// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
use pyo3::{exceptions::PyException, PyErr};
use tracing::subscriber::SetGlobalDefaultError; use tracing::subscriber::SetGlobalDefaultError;
use anyhow;
use thiserror::Error;
//// TYPES ///////////////////////////////////////////////////////////////////////////////////////// //// TYPES /////////////////////////////////////////////////////////////////////////////////////////
/// a quick alias for a result with a [`Error`]
pub type Result<T> = std::result::Result<T, Error>;
//// CONSTANTS ///////////////////////////////////////////////////////////////////////////////////// //// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
@ -27,12 +26,16 @@ pub type Result<T> = std::result::Result<T, Error>;
//// ENUMS ///////////////////////////////////////////////////////////////////////////////////////// //// ENUMS /////////////////////////////////////////////////////////////////////////////////////////
/// ## Errors for the [Logger](super::Logger) /// ## Errors for the [Logger](super::Logger)
#[derive(Error)]
pub enum Error { pub enum Error {
/// Bad IO operation /// Bad IO operation
#[error("Bad IO operation")]
IO(std::io::Error), IO(std::io::Error),
/// Various errors raised when the messenger is used in a wrong way /// Various errors raised when the messenger is used in a wrong way
#[error("Bad usage")]
Usage(String), Usage(String),
/// Could not assign logger as the global default /// Could not assign logger as the global default
#[error("Could not assign as global default")] // TODO: make this more clear
SetGlobalDefaultFail(SetGlobalDefaultError), SetGlobalDefaultFail(SetGlobalDefaultError),
} }
@ -52,19 +55,6 @@ impl From<SetGlobalDefaultError> for Error {
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
impl Into<PyErr> for Error {
fn into(self) -> PyErr {
match self {
Error::IO(err) => PyException::new_err(format!("LoggerError: IO {err:?}")),
Error::Usage(err) => PyException::new_err(format!("LoggerError: Usage {err}")),
Error::SetGlobalDefaultFail(err) => {
PyException::new_err(format!("LoggerError: SetGlobalDefaultFail {err}"))
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
impl std::fmt::Debug for Error { impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -76,17 +66,6 @@ impl std::fmt::Debug for Error {
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::IO(e) => write!(f, "IO Error {e}"),
Error::Usage(e) => write!(f, "Usage Error {e}"),
Error::SetGlobalDefaultFail(e) => write!(f, "SetGlobalDefaultFail {e}"),
}
}
}
//// PUBLIC FUNCTIONS ////////////////////////////////////////////////////////////////////////////// //// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS ///////////////////////////////////////////////////////////////////////////// //// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,8 @@ pub use tracing::{debug, error, info, trace, warn, Level};
use tracing_appender; use tracing_appender;
use tracing_subscriber::{fmt::format::FmtSpan, prelude::*}; use tracing_subscriber::{fmt::format::FmtSpan, prelude::*};
use pyo3::prelude::*; use anyhow::{Result,bail};
//// CONSTANTS ///////////////////////////////////////////////////////////////////////////////////// //// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
/// The log level used when none is specified /// The log level used when none is specified
pub const DEFAULT_LOG_LEVEL: Level = Level::INFO; pub const DEFAULT_LOG_LEVEL: Level = Level::INFO;
@ -47,8 +48,7 @@ static INITIALIZED: AtomicBool = AtomicBool::new(false);
/// ///
/// This struct exists mainly for the python module, so that we can use the same logger with both /// This struct exists mainly for the python module, so that we can use the same logger with both
/// python and rust. /// python and rust.
#[pyclass] pub struct Logger;
pub struct Logger {}
//// IMPLEMENTATION //////////////////////////////////////////////////////////////////////////////// //// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
/// ## Main implementation /// ## Main implementation
@ -98,7 +98,7 @@ impl Logger {
// only init if no init has been performed yet // only init if no init has been performed yet
if INITIALIZED.load(Ordering::Relaxed) { if INITIALIZED.load(Ordering::Relaxed) {
warn!("trying to reinitialize the logger, ignoring"); warn!("trying to reinitialize the logger, ignoring");
return Err(Error::Usage(format!("logging is already initialized"))); bail!(Error::Usage(format!("logging is already initialized")));
} else { } else {
let filter = tracing_subscriber::filter::FilterFn::new(|_metadata| { let filter = tracing_subscriber::filter::FilterFn::new(|_metadata| {
// let mut filter = false; // let mut filter = false;
@ -184,61 +184,6 @@ impl Logger {
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Implementation of the python interface
#[pymethods]
impl Logger {
/// ## Python version of [`new()`](Logger::new)
#[new]
pub fn py_new() -> PyResult<Self> {
Ok(Logger::new())
}
/// ## Python version of [`init()`](Logger::init)
#[pyo3(name = "init")]
#[staticmethod]
pub fn py_init(log_dir: Option<PathBuf>, max_level: Option<String>) -> Result<()> {
Self::init(
log_dir,
match max_level {
Some(s) => match s.to_uppercase().as_str() {
"TRACE" => Some(tracing::Level::TRACE),
"DEBUG" => Some(tracing::Level::DEBUG),
"INFO" => Some(tracing::Level::INFO),
"WARN" => Some(tracing::Level::WARN),
"ERROR" => Some(tracing::Level::ERROR),
_ => return Err(Error::Usage(format!("'{s}' is not a valid log level"))),
},
None => None,
},
)
}
/// ## Python version of [`error()`](Logger::error)
#[pyo3(name = "error")]
pub fn py_error(&self, printable: String) {
self.error(printable)
}
/// ## Python version of [`warn()`](Logger::warn)
#[pyo3(name = "warn")]
pub fn py_warn(&self, printable: String) {
self.warn(printable)
}
/// ## Python version of [`info()`](Logger::info)
#[pyo3(name = "info")]
pub fn py_info(&self, printable: String) {
self.info(printable)
}
/// ## Python version of [`debug()`](Logger::debug)
#[pyo3(name = "debug")]
pub fn py_debug(&self, printable: String) {
self.debug(printable)
}
/// ## Python version of [`trace()`](Logger::trace)
#[pyo3(name = "trace")]
pub fn py_trace(&self, printable: String) {
self.trace(printable)
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
impl fmt::Debug for Logger { impl fmt::Debug for Logger {
/// ## DEBUG representation for [`Logger`] /// ## DEBUG representation for [`Logger`]