Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dismiss log messages based on the log level and other small improvements #7

Merged
merged 5 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ documentation = "https://docs.rs/slog-rs/term"
homepage = "https://github.com/slog-rs/slog"
repository = "https://github.com/slog-rs/syslog"
readme = "README.md"
edition = "2018"

[lib]
path = "lib.rs"

[dependencies]
slog = "^2.1.1"
syslog = "3.3.0"
nix = "0.14.0"
104 changes: 76 additions & 28 deletions lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
//! ```
#![warn(missing_docs)]

extern crate nix;
extern crate slog;
extern crate syslog;

use slog::{Drain, Level, OwnedKVList, Record};
use std::{fmt, io};
use std::sync::Mutex;
Expand All @@ -40,19 +36,20 @@ use std::io::{Error, ErrorKind};
use slog::KV;

pub use syslog::Facility;
use syslog::Severity;

thread_local! {
static TL_BUF: RefCell<Vec<u8>> = RefCell::new(Vec::with_capacity(128))
}

fn level_to_severity(level: slog::Level) -> syslog::Severity {
fn level_to_severity(level: slog::Level) -> Severity {
match level {
Level::Critical => syslog::Severity::LOG_CRIT,
Level::Error => syslog::Severity::LOG_ERR,
Level::Warning => syslog::Severity::LOG_WARNING,
Level::Info => syslog::Severity::LOG_NOTICE,
Level::Debug => syslog::Severity::LOG_INFO,
Level::Trace => syslog::Severity::LOG_DEBUG,
Level::Critical => Severity::LOG_CRIT,
Level::Error => Severity::LOG_ERR,
Level::Warning => Severity::LOG_WARNING,
Level::Info => Severity::LOG_NOTICE,
Level::Debug => Severity::LOG_INFO,
Level::Trace => Severity::LOG_DEBUG,
}
}

Expand All @@ -63,42 +60,86 @@ fn level_to_severity(level: slog::Level) -> syslog::Severity {
pub struct Streamer3164 {
io: Mutex<Box<syslog::Logger>>,
format: Format3164,
level: Level,
}

#[cfg(debug_assertions)]
fn get_default_level() -> Level {
if cfg!(feature = "max_level_trace") {
Level::Trace
} else if cfg!(feature = "max_level_debug") {
Level::Debug
} else if cfg!(feature = "max_level_info") {
Level::Info
} else if cfg!(feature = "max_level_warn") {
Level::Warning
} else if cfg!(feature = "max_level_error") {
Level::Error
} else { // max_level_off
Level::Critical
}
}

#[cfg(not(debug_assertions))]
fn get_default_level() -> Level {
if cfg!(feature = "release_max_level_trace") {
Level::Trace
} else if cfg!(feature = "release_max_level_debug") {
Level::Debug
} else if cfg!(feature = "release_max_level_info") {
Level::Info
} else if cfg!(feature = "release_max_level_warn") {
Level::Warning
} else if cfg!(feature = "release_max_level_error") {
Level::Error
} else { // release_max_level_off
Level::Critical
}
}

impl Streamer3164 {
/// Create new syslog ``Streamer` using given `format`
pub fn new(logger: Box<syslog::Logger>) -> Self {
/// Create new syslog ``Streamer` using given `format` and logging level.
pub fn new_with_level(logger: Box<syslog::Logger>, level: Level) -> Self {
Streamer3164 {
io: Mutex::new(logger),
format: Format3164::new(),
level,
}
}

/// Create new syslog ``Streamer` using given `format` and the default logging level.
pub fn new(logger: Box<syslog::Logger>) -> Self {
let level = get_default_level();
Self::new_with_level(logger, level)
}
}

impl Drain for Streamer3164 {
type Err = io::Error;
type Ok = ();

fn log(&self, info: &Record, logger_values: &OwnedKVList) -> io::Result<()> {
if self.level > info.level() {
return Ok(())
}
TL_BUF.with(|buf| {
let mut buf = buf.borrow_mut();
let res = {
|| {
try!(self.format.format(&mut *buf, info, logger_values));
self.format.format(&mut *buf, info, logger_values)?;
let sever = level_to_severity(info.level());
{
let io = try!(
let io =
self.io
.lock()
.map_err(|_| Error::new(ErrorKind::Other, "locking error"))
);
.map_err(|_| Error::new(ErrorKind::Other, "locking error"))?;

let buf = String::from_utf8_lossy(&buf);
let buf = io.format_3164(sever, &buf).into_bytes();

let mut pos = 0;
while pos < buf.len() {
let n = try!(io.send_raw(&buf[pos..]));
let n = io.send_raw(&buf[pos..])?;
if n == 0 {
break;
}
Expand Down Expand Up @@ -127,16 +168,16 @@ impl Format3164 {

fn format(
&self,
io: &mut io::Write,
io: &mut dyn io::Write,
record: &Record,
logger_kv: &OwnedKVList,
) -> io::Result<()> {
try!(write!(io, "{}", record.msg()));
write!(io, "{}", record.msg())?;

let mut ser = KSV::new(io);
{
try!(logger_kv.serialize(record, &mut ser));
try!(record.kv().serialize(record, &mut ser));
logger_kv.serialize(record, &mut ser)?;
record.kv().serialize(record, &mut ser)?;
}
Ok(())
}
Expand All @@ -155,7 +196,7 @@ impl<W: io::Write> KSV<W> {

impl<W: io::Write> slog::Serializer for KSV<W> {
fn emit_arguments(&mut self, key: &str, val: &fmt::Arguments) -> slog::Result {
try!(write!(self.io, ", {}: {}", key, val));
write!(self.io, ", {}: {}", key, val)?;
Ok(())
}
}
Expand All @@ -178,14 +219,14 @@ enum SyslogKind {
/// Builder pattern for constructing a syslog
pub struct SyslogBuilder {
facility: Option<syslog::Facility>,
level: syslog::Severity,
level: Level,
logkind: Option<SyslogKind>,
}
impl Default for SyslogBuilder {
fn default() -> Self {
Self {
facility: None,
level: syslog::Severity::LOG_DEBUG,
level: Level::Trace,
logkind: None,
}
}
Expand All @@ -208,7 +249,7 @@ impl SyslogBuilder {
/// Filter Syslog by level
pub fn level(self, lvl: slog::Level) -> Self {
let mut s = self;
s.level = level_to_severity(lvl);
s.level = lvl;
s
}

Expand Down Expand Up @@ -269,11 +310,18 @@ impl SyslogBuilder {
} => syslog::udp(local, host, hostname, facility)?,
SyslogKind::Tcp { server, hostname } => syslog::tcp(server, hostname, facility)?,
};
Ok(Streamer3164::new(log))
Ok(Streamer3164::new_with_level(log, self.level))
}
}

/// `Streamer` to Unix syslog using RFC 3164 format
pub fn unix_3164_with_level(facility: syslog::Facility, level: Level) -> io::Result<Streamer3164> {
let logger = syslog::unix(facility)?;
Ok(Streamer3164::new_with_level(logger, level))
}

/// `Streamer` to Unix syslog using RFC 3164 format
pub fn unix_3164(facility: syslog::Facility) -> io::Result<Streamer3164> {
syslog::unix(facility).map(Streamer3164::new)
let logger = syslog::unix(facility)?;
Ok(Streamer3164::new(logger))
}