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

feat: impl send_formatted #4

Merged
merged 2 commits into from
Nov 12, 2024
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
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