Add a logger

OpenSMTPD plans to gather all logs from filters. Therefore, a default
logger that implements the smtpd (future) log interface has to be
available.
This commit is contained in:
Rodolphe Breard 2019-01-17 19:53:04 +01:00
parent 4b1f99db7e
commit ae8b64941e
6 changed files with 64 additions and 13 deletions

View file

@ -12,9 +12,9 @@ license = "CECILL-B"
include = ["src/**/*", "Cargo.toml", "Licence_*.txt"] include = ["src/**/*", "Cargo.toml", "Licence_*.txt"]
[dependencies] [dependencies]
log = "0.4" log = {version = "0.4", features = ["std"]}
nom = "4.1" nom = "4.1"
opensmtpd_derive = { path = "../opensmtpd-derive", version="0.1" } opensmtpd_derive = { path = "../opensmtpd-derive", version = "0.1" }
[[example]] [[example]]
name = "dummy" name = "dummy"
@ -23,6 +23,3 @@ path = "examples/dummy.rs"
[[example]] [[example]]
name = "counter" name = "counter"
path = "examples/session_event_counter.rs" path = "examples/session_event_counter.rs"
[dev-dependencies]
env_logger = "0.6"

View file

@ -1,6 +1,5 @@
use env_logger::{Builder, Env}; use log::{debug, info, Level};
use log::{debug, info}; use opensmtpd::{event, handlers, Entry, SmtpIn, SmtpdLogger};
use opensmtpd::{event, handlers, Entry, SmtpIn};
#[event(Any)] #[event(Any)]
fn on_event(entry: &Entry) { fn on_event(entry: &Entry) {
@ -13,7 +12,7 @@ fn on_connect(entry: &Entry) {
} }
fn main() { fn main() {
Builder::from_env(Env::default().default_filter_or("debug")).init(); let _ = SmtpdLogger::new().set_level(Level::Debug).init();
SmtpIn::new() SmtpIn::new()
.event_handlers(handlers!(on_event, on_connect)) .event_handlers(handlers!(on_event, on_connect))
.run(); .run();

View file

@ -1,6 +1,5 @@
use env_logger::{Builder, Env}; use log::{info, Level};
use log::info; use opensmtpd::{event, handlers, Entry, SmtpIn, SmtpdLogger};
use opensmtpd::{event, handlers, Entry, SmtpIn};
#[derive(Clone, Default)] #[derive(Clone, Default)]
struct MyContext { struct MyContext {
@ -14,6 +13,6 @@ fn on_event(ctx: &mut MyContext, entry: &Entry) {
} }
fn main() { fn main() {
Builder::from_env(Env::default().default_filter_or("debug")).init(); let _ = SmtpdLogger::new().set_level(Level::Debug).init();
SmtpIn::new().event_handlers(handlers!(on_event)).run(); SmtpIn::new().event_handlers(handlers!(on_event)).run();
} }

View file

@ -26,6 +26,12 @@ impl From<std::io::Error> for Error {
} }
} }
impl From<log::SetLoggerError> for Error {
fn from(error: log::SetLoggerError) -> Self {
Error::new(&format!("Logger error: {}", error))
}
}
impl From<nom::Err<&str>> for Error { impl From<nom::Err<&str>> for Error {
fn from(error: nom::Err<&str>) -> Self { fn from(error: nom::Err<&str>) -> Self {
let msg = match error { let msg = match error {

View file

@ -1,6 +1,7 @@
mod entry; mod entry;
mod errors; mod errors;
mod event_handlers; mod event_handlers;
mod logger;
use log::{debug, error, warn}; use log::{debug, error, warn};
use std::collections::HashMap; use std::collections::HashMap;
@ -12,6 +13,7 @@ use std::thread;
pub use crate::entry::{Entry, Event}; pub use crate::entry::{Entry, Event};
pub use crate::errors::Error; pub use crate::errors::Error;
pub use crate::event_handlers::{Callback, EventHandler, MatchEvent}; pub use crate::event_handlers::{Callback, EventHandler, MatchEvent};
pub use crate::logger::SmtpdLogger;
pub use opensmtpd_derive::event; pub use opensmtpd_derive::event;
#[macro_export] #[macro_export]

48
opensmtpd/src/logger.rs Normal file
View file

@ -0,0 +1,48 @@
use crate::errors::Error;
use log::{Level, Metadata, Record};
use std::io::{self, Write};
#[derive(Clone)]
pub struct SmtpdLogger {
level: Level,
}
impl SmtpdLogger {
pub fn new() -> Self {
SmtpdLogger::default()
}
pub fn set_level(&mut self, level: Level) -> Self {
self.level = level;
self.clone()
}
pub fn init(self) -> Result<(), Error> {
let level = self.level.to_level_filter();
log::set_boxed_logger(Box::new(self))?;
log::set_max_level(level);
Ok(())
}
}
impl Default for SmtpdLogger {
fn default() -> Self {
SmtpdLogger { level: Level::Warn }
}
}
impl log::Log for SmtpdLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
let stderr = io::stderr();
let mut handle = stderr.lock();
writeln!(handle, "{}: {}", record.level(), record.args()).unwrap();
}
}
fn flush(&self) {}
}