parent
4151400783
commit
7070b7c9a8
@ -0,0 +1,19 @@
|
||||
use super::*;
|
||||
|
||||
/// Command to interrupt an `Imouto` worker
|
||||
#[derive(Debug, PartialEq,Eq,Hash)]
|
||||
pub enum Command {
|
||||
/// Ungraceful shutdown
|
||||
Abort,
|
||||
/// Graceful shutdown
|
||||
Shutdown,
|
||||
|
||||
/// Update interval
|
||||
Reset(interval::Time),
|
||||
|
||||
/// Full reload
|
||||
Reload,
|
||||
|
||||
/// Debug informations
|
||||
Dump,
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
//! Global logging state
|
||||
|
||||
use std::{
|
||||
fmt::{
|
||||
self,
|
||||
Display,
|
||||
},
|
||||
io::{
|
||||
self,
|
||||
Write,
|
||||
},
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
/// Logging level
|
||||
#[derive(PartialEq,Copy,Eq,Debug,Clone,Hash,Ord,PartialOrd)]
|
||||
pub enum Level
|
||||
{
|
||||
Silent,
|
||||
Error,
|
||||
Warn,
|
||||
Info,
|
||||
Debug,
|
||||
}
|
||||
|
||||
impl Default for Level
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Level
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
return Level::Debug;
|
||||
#[cfg(not(debug_assertions))]
|
||||
return Level::Warn;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Level
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
use recolored::Colorize;
|
||||
write!(f, "{}", match &self {
|
||||
Self::Silent => "Fatal".bright_red().bold(),
|
||||
Self::Error => "Error".red(),
|
||||
Self::Warn => "Warning".yellow(),
|
||||
Self::Info => "Info".normal(),
|
||||
Self::Debug => "Debug".dimmed(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A logger that prints to stdout and stderr idk.
|
||||
/// # TODO
|
||||
/// Make this a trait and have variants that print to files and such
|
||||
#[derive(Debug)]
|
||||
pub struct Logger
|
||||
{
|
||||
level: Level,
|
||||
title: String,
|
||||
use_local_time: bool,
|
||||
}
|
||||
|
||||
static INSTANCE: OnceCell<Logger> = OnceCell::new();
|
||||
|
||||
impl Logger
|
||||
{
|
||||
pub fn new(level: Level) -> Self
|
||||
{
|
||||
Self {
|
||||
level,
|
||||
title: String::new(),
|
||||
use_local_time: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn global() -> &'static Logger
|
||||
{
|
||||
INSTANCE.get().expect("[logger] uninitialised")
|
||||
}
|
||||
|
||||
|
||||
fn initialise(level: Level) -> &'static Logger
|
||||
{
|
||||
INSTANCE.set(Logger::new(level)).expect("[logger] already initialised");
|
||||
Logger::global()
|
||||
}
|
||||
|
||||
pub fn println(&self, mut to: impl Write, level: Level, what: impl Display) -> io::Result<()>
|
||||
{
|
||||
//lol
|
||||
enum Date {
|
||||
Local(chrono::DateTime<chrono::offset::Local>),
|
||||
Utc(chrono::DateTime<chrono::offset::Utc>),
|
||||
}
|
||||
impl std::fmt::Display for Date
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
match self {
|
||||
Self::Local(l) => write!(f, "{}", l),
|
||||
Self::Utc(l) => write!(f, "{}", l),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<chrono::DateTime<chrono::offset::Local>> for Date
|
||||
{
|
||||
#[inline]
|
||||
fn from(from: chrono::DateTime<chrono::offset::Local>) -> Self
|
||||
{
|
||||
Self::Local(from)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chrono::DateTime<chrono::offset::Utc>> for Date
|
||||
{
|
||||
#[inline]
|
||||
fn from(from: chrono::DateTime<chrono::offset::Utc>) -> Self
|
||||
{
|
||||
Self::Utc(from)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if self.level >= level {
|
||||
let now: Date = if self.use_local_time {
|
||||
chrono::offset::Local::now().into()
|
||||
} else {
|
||||
chrono::offset::Utc::now().into()
|
||||
};
|
||||
|
||||
if self.title.len() > 0 {
|
||||
write!(to, "{} [{}] <{}>: ", now, level, self.title)?;
|
||||
} else {
|
||||
write!(to, "{} [{}]: ", now, level)?;
|
||||
}
|
||||
writeln!(to, "{}", what)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! debug {
|
||||
($obj:expr) => {
|
||||
{
|
||||
let stdout = std::io::stdout();
|
||||
let stdout = stdout.lock();
|
||||
$crate::log::Logger::global().println(stdout, $crate::log::Level::Debug, $obj).expect("i/o error")
|
||||
}
|
||||
};
|
||||
($fmt:literal, $($args:expr),*) => {
|
||||
debug!(lazy_format::lazy_format!($fmt, $($args,)*))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! info {
|
||||
($obj:expr) => {
|
||||
{
|
||||
let stdout = std::io::stdout();
|
||||
let stdout = stdout.lock();
|
||||
$crate::log::Logger::global().println(stdout, $crate::log::Level::Info, $obj).expect("i/o error")
|
||||
}
|
||||
};
|
||||
($fmt:literal, $($args:expr),*) => {
|
||||
info!(lazy_format::lazy_format!($fmt, $($args,)*))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#[macro_export] macro_rules! warn {
|
||||
($obj:expr) => {
|
||||
{
|
||||
let stderr = std::io::stderr();
|
||||
let stderr = stderr.lock();
|
||||
$crate::log::Logger::global().println(stderr, $crate::log::Level::Warn, $obj).expect("i/o error")
|
||||
}
|
||||
};
|
||||
($fmt:literal, $($args:expr),*) => {
|
||||
warn!(lazy_format::lazy_format!($fmt, $($args,)*))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! error {
|
||||
($obj:expr) => {
|
||||
{
|
||||
let stderr = std::io::stderr();
|
||||
let stderr = stderr.lock();
|
||||
$crate::log::Logger::global().println(stderr, $crate::log::Level::Error, $obj).expect("i/o error")
|
||||
}
|
||||
};
|
||||
($fmt:literal, $($args:expr),*) => {
|
||||
error!(lazy_format::lazy_format!($fmt, $($args,)*))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! fatal {
|
||||
($obj:expr) => {
|
||||
{
|
||||
let stdout = std::io::stdout();
|
||||
let stdout = stdout.lock();
|
||||
$crate::log::Logger::global().println(stdout, $crate::log::Level::Silent, $obj).expect("i/o error");
|
||||
|
||||
std::process::exit(-1)
|
||||
}
|
||||
};
|
||||
($fmt:literal, $($args:expr),*) => {
|
||||
error!(lazy_format::lazy_format!($fmt, $($args,)*))
|
||||
};
|
||||
}
|
||||
|
||||
/// Initialise the global logger instance. If logging macros are called before this, they will panic.
|
||||
#[inline]
|
||||
pub fn init(level: Level)
|
||||
{
|
||||
Logger::initialise(level);
|
||||
}
|
||||
|
||||
/// The global logger's level
|
||||
#[inline]
|
||||
pub fn level() -> &'static Level
|
||||
{
|
||||
&Logger::global().level
|
||||
}
|
Loading…
Reference in new issue