Skip to content

Commit

Permalink
feat: impl send_formatted (#4)
Browse files Browse the repository at this point in the history
Signed-off-by: tison <[email protected]>
  • Loading branch information
tisonkun authored Nov 12, 2024
1 parent 674e2ac commit 3eda0d0
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 116 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

Client library written in Rust to send messages to a Syslog server. Support implementations:

* RFC-3164 Formatter: [The BSD syslog Protocol](http://tools.ietf.org/html/rfc3164)
* RFC-5424 Formatter: [The Syslog Protocol](http://tools.ietf.org/html/rfc5424)
* `UdpSender`: [RFC 5426 - Transmission of Syslog Messages over UDP](http://tools.ietf.org/html/rfc5426)
* `TcpSender`: [RFC 6587 - Transmission of Syslog Messages over TCP](http://tools.ietf.org/html/rfc6587)
* RFC-3164 Formatter: [The BSD syslog Protocol](https://datatracker.ietf.org/doc/html/rfc3164)
* RFC-5424 Formatter: [The Syslog Protocol](https://datatracker.ietf.org/doc/html/rfc5424)
* `UdpSender`: [RFC 5426 - Transmission of Syslog Messages over UDP](https://datatracker.ietf.org/doc/html/rfc5426)
* `TcpSender`: [RFC 6587 - Transmission of Syslog Messages over TCP](https://datatracker.ietf.org/doc/html/rfc6587)
* (unix only) Unix domain socket sender (datagram or stream)

## Getting Started
Expand Down
4 changes: 2 additions & 2 deletions src/facility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use std::str::FromStr;
///
/// See also [RFC 5427] (Textual Conventions for Syslog Management) for the labels.
///
/// [RFC 5424]: https://tools.ietf.org/html/rfc5424.
/// [RFC 5427]: https://tools.ietf.org/html/rfc5427.
/// [RFC 5424]: https://datatracker.ietf.org/doc/html/rfc5424.
/// [RFC 5427]: https://datatracker.ietf.org/doc/html/rfc5427.
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[repr(u8)]
pub enum Facility {
Expand Down
4 changes: 2 additions & 2 deletions src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ fn nullable_value(value: Option<&str>) -> &str {

/// Format the Syslog message as [RFC-3164] (BSD syslog Protocol).
///
/// [RFC-3164]: https://tools.ietf.org/html/rfc3164
/// [RFC-3164]: https://datatracker.ietf.org/doc/html/rfc3164
#[derive(Debug)]
pub struct RFC3164Formatter<'a, M> {
context: &'a SyslogContext,
Expand Down Expand Up @@ -170,7 +170,7 @@ where

/// Format the Syslog message as [RFC 5424] (The Syslog Protocol)
///
/// [RFC 5424]: https://tools.ietf.org/html/rfc5424
/// [RFC 5424]: https://datatracker.ietf.org/doc/html/rfc5424
#[derive(Debug)]
pub struct RFC5424Formatter<'a, M> {
context: &'a SyslogContext,
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
//!
//! This crate provides facilities to send log messages via syslog. Support implementations:
//!
//! * [RFC-3164 Formatter]: [The BSD syslog Protocol](http://tools.ietf.org/html/rfc3164)
//! * [RFC-5424 Formatter]: [The Syslog Protocol](http://tools.ietf.org/html/rfc5424)
//! * [`UdpSender`]: [RFC 5426 - Transmission of Syslog Messages over UDP](http://tools.ietf.org/html/rfc5426)
//! * [`TcpSender`]: [RFC 6587 - Transmission of Syslog Messages over TCP](http://tools.ietf.org/html/rfc6587)
//! * [RFC-3164 Formatter]: [The BSD syslog Protocol](https://datatracker.ietf.org/doc/html/rfc3164)
//! * [RFC-5424 Formatter]: [The Syslog Protocol](https://datatracker.ietf.org/doc/html/rfc5424)
//! * [`UdpSender`]: [RFC 5426 - Transmission of Syslog Messages over UDP](https://datatracker.ietf.org/doc/html/rfc5426)
//! * [`TcpSender`]: [RFC 6587 - Transmission of Syslog Messages over TCP](https://datatracker.ietf.org/doc/html/rfc6587)
//! * (unix only) Unix domain socket sender (datagram or stream)
//!
//! [RFC-3164 Formatter]: format::RFC3164Formatter
Expand Down
45 changes: 45 additions & 0 deletions src/sender/internal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2024 FastLabs Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

macro_rules! impl_syslog_sender_common {
($sender:ident) => {
impl $sender {
/// Send a message with the given severity as defined in RFC-3164.
pub fn send_rfc3164<M: std::fmt::Display>(
&mut self,
severity: $crate::Severity,
message: M,
) -> io::Result<()> {
let message = self.context.format_rfc3164(severity, Some(message));
self.send_formatted(message.to_string().as_bytes())
}

/// Send a message with the given severity as defined in RFC-5424.
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
&mut self,
severity: $crate::Severity,
msgid: Option<S>,
elements: Vec<$crate::SDElement>,
message: M,
) -> io::Result<()> {
let message = self
.context
.format_rfc5424(severity, msgid, elements, Some(message));
self.send_formatted(message.to_string().as_bytes())
}
}
};
}

pub(crate) use impl_syslog_sender_common;
14 changes: 14 additions & 0 deletions src/sender/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub use tcp::*;
mod udp;
pub use udp::*;

pub(crate) mod internal;

/// Static dispatch for the different sender types.
#[derive(Debug)]
pub enum SyslogSender {
Expand Down Expand Up @@ -81,6 +83,18 @@ impl SyslogSender {
}
}

/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
match self {
SyslogSender::Tcp(sender) => sender.send_formatted(formatted),
SyslogSender::Udp(sender) => sender.send_formatted(formatted),
#[cfg(unix)]
SyslogSender::UnixDatagram(sender) => sender.send_formatted(formatted),
#[cfg(unix)]
SyslogSender::UnixStream(sender) => sender.send_formatted(formatted),
}
}

/// Flush the underlying writer if needed.
pub fn flush(&mut self) -> io::Result<()> {
match self {
Expand Down
37 changes: 10 additions & 27 deletions src/sender/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
use std::borrow::Cow;
use std::io;
use std::io::BufWriter;
use std::io::Write;
use std::net::TcpStream;
use std::net::ToSocketAddrs;

use crate::format::SyslogContext;
use crate::SDElement;
use crate::Severity;
use crate::sender::internal::impl_syslog_sender_common;

/// Create a TCP sender that sends messages to the well-known port (601).
///
Expand Down Expand Up @@ -59,7 +59,7 @@ impl TcpSender {
///
/// This is generally '\r\n' as defined in [RFC-6587] §3.4.2.
///
/// [RFC-6587]: https://tools.ietf.org/html/rfc6587
/// [RFC-6587]: https://datatracker.ietf.org/doc/html/rfc6587
pub fn set_postfix(&mut self, postfix: impl Into<Cow<'static, str>>) {
self.postfix = postfix.into();
}
Expand All @@ -74,30 +74,11 @@ impl TcpSender {
&mut self.context
}

/// Send a message with the given severity as defined in RFC-3164.
pub fn send_rfc3164<M: std::fmt::Display>(
&mut self,
severity: Severity,
message: M,
) -> io::Result<()> {
use std::io::Write;
let message = self.context.format_rfc3164(severity, Some(message));
write!(&mut self.writer, "{}{}", message, self.postfix)
}

/// Send a message with the given severity as defined in RFC-5424.
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
&mut self,
severity: Severity,
msgid: Option<S>,
elements: Vec<SDElement>,
message: M,
) -> io::Result<()> {
use std::io::Write;
let message = self
.context
.format_rfc5424(severity, msgid, elements, Some(message));
write!(&mut self.writer, "{}{}", message, self.postfix)
/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
self.writer.write_all(formatted)?;
self.writer.write_all(self.postfix.as_bytes())?;
Ok(())
}

/// Flush the writer.
Expand All @@ -106,3 +87,5 @@ impl TcpSender {
self.writer.flush()
}
}

impl_syslog_sender_common!(TcpSender);
31 changes: 6 additions & 25 deletions src/sender/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ use std::net::ToSocketAddrs;
use std::net::UdpSocket;

use crate::format::SyslogContext;
use crate::SDElement;
use crate::Severity;
use crate::sender::internal::impl_syslog_sender_common;

/// Create a UDP sender that sends messages to the well-known port (514).
///
Expand Down Expand Up @@ -62,29 +61,11 @@ impl UdpSender {
&mut self.context
}

/// Send a message with the given severity as defined in RFC-3164.
pub fn send_rfc3164<M: std::fmt::Display>(
&mut self,
severity: Severity,
message: M,
) -> io::Result<()> {
let message = self.context.format_rfc3164(severity, Some(message));
self.socket.send(message.to_string().as_bytes())?;
Ok(())
}

/// Send a message with the given severity as defined in RFC-5424.
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
&mut self,
severity: Severity,
msgid: Option<S>,
elements: Vec<SDElement>,
message: M,
) -> io::Result<()> {
let message = self
.context
.format_rfc5424(severity, msgid, elements, Some(message));
self.socket.send(message.to_string().as_bytes())?;
/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
self.socket.send(formatted)?;
Ok(())
}
}

impl_syslog_sender_common!(UdpSender);
63 changes: 12 additions & 51 deletions src/sender/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

use std::io;
use std::io::BufWriter;
use std::io::Write;
use std::os::unix::net::UnixDatagram;
use std::os::unix::net::UnixStream;
use std::path::Path;

use crate::format::SyslogContext;
use crate::sender::internal::impl_syslog_sender_common;
use crate::sender::SyslogSender;
use crate::SDElement;
use crate::Severity;

/// Create a Unix datagram sender that sends messages to the given path.
pub fn unix_datagram(path: impl AsRef<Path>) -> io::Result<UnixDatagramSender> {
Expand Down Expand Up @@ -95,33 +95,15 @@ impl UnixDatagramSender {
&mut self.context
}

/// Send a message with the given severity as defined in RFC-3164.
pub fn send_rfc3164<M: std::fmt::Display>(
&mut self,
severity: Severity,
message: M,
) -> io::Result<()> {
let message = self.context.format_rfc3164(severity, Some(message));
self.socket.send(message.to_string().as_bytes())?;
Ok(())
}

/// Send a message with the given severity as defined in RFC-5424.
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
&mut self,
severity: Severity,
msgid: Option<S>,
elements: Vec<SDElement>,
message: M,
) -> io::Result<()> {
let message = self
.context
.format_rfc5424(severity, msgid, elements, Some(message));
self.socket.send(message.to_string().as_bytes())?;
/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
self.socket.send(formatted)?;
Ok(())
}
}

impl_syslog_sender_common!(UnixDatagramSender);

/// A syslog sender that sends messages to a Unix stream socket.
///
/// Typically, this sender is used to send messages to the local syslog daemon. Typical paths are
Expand Down Expand Up @@ -152,32 +134,9 @@ impl UnixStreamSender {
&mut self.context
}

/// Send a message with the given severity as defined in RFC-3164.
pub fn send_rfc3164<M: std::fmt::Display>(
&mut self,
severity: Severity,
message: M,
) -> io::Result<()> {
use std::io::Write;
let message = self.context.format_rfc3164(severity, Some(message));
write!(&mut self.writer, "{}", message)?;
self.writer.write_all(&[0; 1])?;
Ok(())
}

/// Send a message with the given severity as defined in RFC-5424.
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
&mut self,
severity: Severity,
msgid: Option<S>,
elements: Vec<SDElement>,
message: M,
) -> io::Result<()> {
use std::io::Write;
let message = self
.context
.format_rfc5424(severity, msgid, elements, Some(message));
write!(&mut self.writer, "{}", message)?;
/// Send a pre-formatted message.
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
self.writer.write_all(formatted)?;
self.writer.write_all(&[0; 1])?;
Ok(())
}
Expand All @@ -188,3 +147,5 @@ impl UnixStreamSender {
self.writer.flush()
}
}

impl_syslog_sender_common!(UnixStreamSender);
2 changes: 1 addition & 1 deletion src/severity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::str::FromStr;

/// Syslog severity as defined in [RFC 5424] (The Syslog Protocol).
///
/// [RFC 5424]: https://tools.ietf.org/html/rfc5424.
/// [RFC 5424]: https://datatracker.ietf.org/doc/html/rfc5424.
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
#[repr(u8)]
pub enum Severity {
Expand Down

0 comments on commit 3eda0d0

Please sign in to comment.