Skip to content

Commit

Permalink
[0.29.0] Release
Browse files Browse the repository at this point in the history
  • Loading branch information
emabee committed Aug 25, 2024
1 parent 0570649 commit dcb1717
Show file tree
Hide file tree
Showing 16 changed files with 844 additions and 537 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.29.0] - 2024-08-25

Revised `SyslogWriter` (-> version bump): introduced builder pattern,
added a configuration option for the message format
(resolves [issue #168](https://github.com/emabee/flexi_logger/issues/168), kudos to [krims0n32](https://github.com/krims0n32)).

`LoggerHandle::existing_log_files` now also returns a meaningful result if file rotation is not
used. Kudos to [drdo](https://github.com/drdo) for
[discussion 170](https://github.com/emabee/flexi_logger/discussions/170).

## [0.28.5] - 2024-06-21

Remove unnecessary dependency to `is-terminal`.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "flexi_logger"
version = "0.28.5"
version = "0.29.0"
authors = ["emabee <meinolf.block@sap.com>"]
categories = ["development-tools::debugging"]
description = """
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ and you use the ```log``` macros to write log lines from your code):

```toml
[dependencies]
flexi_logger = "0.28"
flexi_logger = "0.29"
log = "0.4"
```

Expand Down Expand Up @@ -74,15 +74,15 @@ Make use of the non-default features by specifying them in your `Cargo.toml`, e.

```toml
[dependencies]
flexi_logger = { version = "0.28", features = ["async", "specfile", "compress"] }
flexi_logger = { version = "0.29", features = ["async", "specfile", "compress"] }
log = "0.4"
```

or, to get the smallest footprint (and no colors), switch off even the default features:

```toml
[dependencies]
flexi_logger = { version = "0.28", default_features = false }
flexi_logger = { version = "0.29", default_features = false }
log = "0.4"
```

Expand Down
14 changes: 14 additions & 0 deletions src/logger_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,20 @@ impl LoggerHandle {
pub fn validate_logs(&self, expected: &[(&'static str, &'static str, &'static str)]) {
self.writers_handle.primary_writer.validate_logs(expected);
}

// Allows checking the logs written so far to the writer
#[doc(hidden)]
pub fn validate_additional_logs(
&self,
target: &str,
expected: &[(&'static str, &'static str, &'static str)],
) {
self.writers_handle
.other_writers
.get(target)
.unwrap(/*fail fast*/)
.validate_logs(expected);
}
}

/// Used in [`LoggerHandle::existing_log_files`].
Expand Down
56 changes: 32 additions & 24 deletions src/writers.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
//! Contains the trait [`LogWriter`] for extending `flexi_logger`
//! with additional log writers,
//! and two concrete implementations
//! for writing to files ([`FileLogWriter`])
//! or to the syslog ([`SyslogWriter`]).
//! You can also use your own implementations of [`LogWriter`].
//! Describes how to extend `flexi_logger` with additional log writers
//! (implementations of the trait [`LogWriter`]), and contains two ready-to-use log writers,
//! one for writing to files ([`FileLogWriter`]), one for writing to the syslog ([`SyslogWriter`]).
//!
//! Such log writers can be used in two ways:
//! Log writers can be used in two ways:
//!
//! * You can influence to which output stream normal log messages will be written,
//! i.e. those from normal log macro calls without explicit target specification.
//! By default, the logs are sent to stderr. With one of the methods
//! * _Default output channel:_ <br>
//! You can influence to which output stream normal log messages will be written,
//! i.e. those from log macro calls without explicit target specification
//! (like in `log::error!("File not found")`).
//!
//! With one of the methods
//!
//! * [`Logger::log_to_stderr`](crate::Logger::log_to_stderr) (default)
//! * [`Logger::log_to_stdout`](crate::Logger::log_to_stdout)
//! * [`Logger::log_to_file`](crate::Logger::log_to_file)
//! * [`Logger::log_to_writer`](crate::Logger::log_to_writer)
//! * [`Logger::log_to_file_and_writer`](crate::Logger::log_to_file_and_writer)
//! * [`Logger::do_not_log`](crate::Logger::do_not_log)
//!
//! you can specify a different log target. See there for more details.
//! you can change the default output channel. The fourth and the fifth of these methods
//! take log writers as input. See their documentation for more details.
//!
//! Messages will only be written to the default output channel
//! if they match the current [log specification](crate::LogSpecification).
//!
//! Normal log calls will only be written to the chosen output channel if they match the current
//! [log specification](crate::LogSpecification).
//! <br>
//!
//! * You can register additional log writers under a target name with
//! * _Additional output channels:_ <br>
//! You can register additional log writers under a _target name_ with
//! [`Logger::add_writer()`](crate::Logger::add_writer), and address these log writers by
//! specifying the target name in calls to the
//! specifying the _target name_ in calls to the
//! [log macros](https://docs.rs/log/latest/log/macro.log.html).
//!
//! A log call with a target value that has the form `{Name1,Name2,...}`, i.e.,
//! a comma-separated list of target names, within braces, is not sent to the default logger,
//! but to the loggers specified explicitly in the list.
//! In such a list you can again specify the default logger with the target name `_Default`.
//! The message of a log call with a _target value_ that has the form `{Name1,Name2,...}`, i.e.,
//! a comma-separated list of _target names_, within braces, is not sent to the default output
//! channel, but to the loggers specified explicitly in the list. In such a list
//! you can also specify the default output channel with the built-in target name `_Default`.
//!
//! These log calls will not be affected by the value of `flexi_logger`'s log specification;
//! they will always be written, as you might want it for alerts or auditing.
//! Log calls that are directed to an additional output channel will not be affected by
//! the value of `flexi_logger`'s log specification;
//! they will always be handed over to the respective `LogWriter`,
//! as you might want it for alerts or auditing.
//!
//! In the following example we define an alert writer, and a macro to facilitate using it
//! (and avoid using the explicit target specification in the macro call), and
Expand Down Expand Up @@ -103,12 +110,13 @@ mod log_writer;

#[cfg(feature = "syslog_writer")]
#[cfg_attr(docsrs, doc(cfg(feature = "syslog_writer")))]
mod syslog_writer;
mod syslog;

#[cfg(feature = "syslog_writer")]
#[cfg_attr(docsrs, doc(cfg(feature = "syslog_writer")))]
pub use self::syslog_writer::{
LevelToSyslogSeverity, Syslog, SyslogFacility, SyslogSeverity, SyslogWriter,
pub use self::syslog::{
syslog_default_format, syslog_format_with_thread, LevelToSyslogSeverity, SyslogConnection,
SyslogFacility, SyslogLineHeader, SyslogSeverity, SyslogWriter, SyslogWriterBuilder,
};

pub use self::file_log_writer::{
Expand Down
19 changes: 19 additions & 0 deletions src/writers/syslog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
mod builder;
mod connection;
mod facility;
mod formats;
mod line;
mod severity;
mod syslog_connection;
mod writer;

#[allow(clippy::module_name_repetitions)]
pub use self::{
builder::SyslogWriterBuilder,
facility::SyslogFacility,
formats::{syslog_default_format, syslog_format_with_thread},
line::SyslogLineHeader,
severity::{LevelToSyslogSeverity, SyslogSeverity},
syslog_connection::SyslogConnection,
writer::SyslogWriter,
};
90 changes: 90 additions & 0 deletions src/writers/syslog/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use super::{
line::SyslogLineHeader, severity::default_mapping, syslog_default_format,
LevelToSyslogSeverity, SyslogConnection, SyslogFacility, SyslogWriter,
};
use crate::FormatFunction;
use std::io::{Error as IoError, ErrorKind, Result as IoResult};

#[allow(clippy::module_name_repetitions)]
/// Builder for the `SyslogWriter`.
///
/// Is created with [`SyslogWriter::builder`].
pub struct SyslogWriterBuilder {
syslog_connection: SyslogConnection,
syslog_line_header: SyslogLineHeader,
syslog_facility: SyslogFacility,
determine_severity: LevelToSyslogSeverity,
max_log_level: log::LevelFilter,
format: FormatFunction,
}
impl SyslogWriterBuilder {
#[must_use]
pub(super) fn new(
syslog: SyslogConnection,
syslog_line_header: SyslogLineHeader,
syslog_facility: SyslogFacility,
) -> SyslogWriterBuilder {
SyslogWriterBuilder {
syslog_connection: syslog,
syslog_line_header,
syslog_facility,
determine_severity: default_mapping,
max_log_level: log::LevelFilter::Warn,
format: syslog_default_format,
}
}

/// Use the given function to map the rust log levels to the syslog severities.
/// By default a trivial mapping is used, which should be good enough in most cases.
#[must_use]
pub fn determine_severity(mut self, mapping: LevelToSyslogSeverity) -> Self {
self.determine_severity = mapping;
self
}

/// Specify up to which level log messages should be sent to the syslog.
///
/// Default is: only warnings and errors.
#[must_use]
pub fn max_log_level(mut self, max_log_level: log::LevelFilter) -> Self {
self.max_log_level = max_log_level;
self
}

/// Use the given format function to write the message part of the syslog entries.
///
/// By default, [`syslog_default_format`](crate::writers::syslog_default_format) is used.
///
/// You can instead use [`syslog_format_with_thread`](crate::writers::syslog_format_with_thread)
/// or your own `FormatFunction`
/// (see the source code of the provided functions if you want to write your own).
#[must_use]
pub fn format(mut self, format: FormatFunction) -> Self {
self.format = format;
self
}

/// Returns a boxed instance of `SysLogWriter`.
///
/// # Errors
///
/// `std::io::Error` if the program's argument list is empty so that the process
/// identifier for the syslog cannot be determined
pub fn build(self) -> IoResult<Box<SyslogWriter>> {
Ok(Box::new(SyslogWriter::new(
std::process::id(),
std::env::args().next().ok_or_else(|| {
IoError::new(
ErrorKind::Other,
"Can't infer app name as no env args are present".to_owned(),
)
})?,
self.syslog_line_header,
self.syslog_facility,
self.determine_severity,
self.syslog_connection,
self.max_log_level,
self.format,
)?))
}
}
69 changes: 69 additions & 0 deletions src/writers/syslog/connection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::{
io::{Result as IoResult, Write},
net::{TcpStream, UdpSocket},
};

// Writable and flushable connection to the syslog backend.
#[derive(Debug)]
pub(super) enum Connection {
// Sends log lines to the syslog via a
// [UnixStream](https://doc.rust-lang.org/std/os/unix/net/struct.UnixStream.html).
#[cfg_attr(docsrs, doc(cfg(target_family = "unix")))]
#[cfg(target_family = "unix")]
Stream(std::os::unix::net::UnixStream),

// Sends log lines to the syslog via a
// [UnixDatagram](https://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html).
#[cfg_attr(docsrs, doc(cfg(target_family = "unix")))]
#[cfg(target_family = "unix")]
Datagram(std::os::unix::net::UnixDatagram),

// Sends log lines to the syslog via UDP.
//
// UDP is fragile and thus discouraged except for local communication.
Udp(UdpSocket),

// Sends log lines to the syslog via TCP.
Tcp(TcpStream),
}

impl Write for Connection {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
match *self {
#[cfg(target_family = "unix")]
Self::Datagram(ref ud) => {
// todo: reconnect if conn is broken
ud.send(buf)
}
#[cfg(target_family = "unix")]
Self::Stream(ref mut w) => {
// todo: reconnect if conn is broken
w.write(buf)
.and_then(|sz| w.write_all(&[0; 1]).map(|()| sz))
}
Self::Tcp(ref mut w) => {
// todo: reconnect if conn is broken
let n = w.write(buf)?;
Ok(w.write(b"\n")? + n)
}
Self::Udp(ref socket) => {
// ??
socket.send(buf)
}
}
}

fn flush(&mut self) -> IoResult<()> {
match *self {
#[cfg(target_family = "unix")]
Self::Datagram(_) => Ok(()),

#[cfg(target_family = "unix")]
Self::Stream(ref mut w) => w.flush(),

Self::Udp(_) => Ok(()),

Self::Tcp(ref mut w) => w.flush(),
}
}
}
55 changes: 55 additions & 0 deletions src/writers/syslog/facility.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/// Syslog Facility, according to [RFC 5424](https://datatracker.ietf.org/doc/rfc5424).
///
/// Note that the original integer values are already multiplied by 8.
#[derive(Copy, Clone, Debug)]
#[allow(clippy::module_name_repetitions)]
pub enum SyslogFacility {
/// kernel messages.
Kernel = 0 << 3,
/// user-level messages.
UserLevel = 1 << 3,
/// mail system.
MailSystem = 2 << 3,
/// system daemons.
SystemDaemons = 3 << 3,
/// security/authorization messages.
Authorization = 4 << 3,
/// messages generated internally by syslogd.
SyslogD = 5 << 3,
/// line printer subsystem.
LinePrinter = 6 << 3,
/// network news subsystem.
News = 7 << 3,
/// UUCP subsystem.
Uucp = 8 << 3,
/// clock daemon.
Clock = 9 << 3,
/// security/authorization messages.
Authorization2 = 10 << 3,
/// FTP daemon.
Ftp = 11 << 3,
/// NTP subsystem.
Ntp = 12 << 3,
/// log audit.
LogAudit = 13 << 3,
/// log alert.
LogAlert = 14 << 3,
/// clock daemon (note 2).
Clock2 = 15 << 3,
/// local use 0 (local0).
LocalUse0 = 16 << 3,
/// local use 1 (local1).
LocalUse1 = 17 << 3,
/// local use 2 (local2).
LocalUse2 = 18 << 3,
/// local use 3 (local3).
LocalUse3 = 19 << 3,
/// local use 4 (local4).
LocalUse4 = 20 << 3,
/// local use 5 (local5).
LocalUse5 = 21 << 3,
/// local use 6 (local6).
LocalUse6 = 22 << 3,
/// local use 7 (local7).
LocalUse7 = 23 << 3,
}
Loading

0 comments on commit dcb1717

Please sign in to comment.