Skip to content

Commit 3eda0d0

Browse files
authored
feat: impl send_formatted (#4)
Signed-off-by: tison <[email protected]>
1 parent 674e2ac commit 3eda0d0

File tree

10 files changed

+100
-116
lines changed

10 files changed

+100
-116
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

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

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

2929
## Getting Started

src/facility.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use std::str::FromStr;
1919
///
2020
/// See also [RFC 5427] (Textual Conventions for Syslog Management) for the labels.
2121
///
22-
/// [RFC 5424]: https://tools.ietf.org/html/rfc5424.
23-
/// [RFC 5427]: https://tools.ietf.org/html/rfc5427.
22+
/// [RFC 5424]: https://datatracker.ietf.org/doc/html/rfc5424.
23+
/// [RFC 5427]: https://datatracker.ietf.org/doc/html/rfc5427.
2424
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
2525
#[repr(u8)]
2626
pub enum Facility {

src/format.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn nullable_value(value: Option<&str>) -> &str {
134134

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

171171
/// Format the Syslog message as [RFC 5424] (The Syslog Protocol)
172172
///
173-
/// [RFC 5424]: https://tools.ietf.org/html/rfc5424
173+
/// [RFC 5424]: https://datatracker.ietf.org/doc/html/rfc5424
174174
#[derive(Debug)]
175175
pub struct RFC5424Formatter<'a, M> {
176176
context: &'a SyslogContext,

src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
//!
2121
//! This crate provides facilities to send log messages via syslog. Support implementations:
2222
//!
23-
//! * [RFC-3164 Formatter]: [The BSD syslog Protocol](http://tools.ietf.org/html/rfc3164)
24-
//! * [RFC-5424 Formatter]: [The Syslog Protocol](http://tools.ietf.org/html/rfc5424)
25-
//! * [`UdpSender`]: [RFC 5426 - Transmission of Syslog Messages over UDP](http://tools.ietf.org/html/rfc5426)
26-
//! * [`TcpSender`]: [RFC 6587 - Transmission of Syslog Messages over TCP](http://tools.ietf.org/html/rfc6587)
23+
//! * [RFC-3164 Formatter]: [The BSD syslog Protocol](https://datatracker.ietf.org/doc/html/rfc3164)
24+
//! * [RFC-5424 Formatter]: [The Syslog Protocol](https://datatracker.ietf.org/doc/html/rfc5424)
25+
//! * [`UdpSender`]: [RFC 5426 - Transmission of Syslog Messages over UDP](https://datatracker.ietf.org/doc/html/rfc5426)
26+
//! * [`TcpSender`]: [RFC 6587 - Transmission of Syslog Messages over TCP](https://datatracker.ietf.org/doc/html/rfc6587)
2727
//! * (unix only) Unix domain socket sender (datagram or stream)
2828
//!
2929
//! [RFC-3164 Formatter]: format::RFC3164Formatter

src/sender/internal.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2024 FastLabs Developers
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
macro_rules! impl_syslog_sender_common {
16+
($sender:ident) => {
17+
impl $sender {
18+
/// Send a message with the given severity as defined in RFC-3164.
19+
pub fn send_rfc3164<M: std::fmt::Display>(
20+
&mut self,
21+
severity: $crate::Severity,
22+
message: M,
23+
) -> io::Result<()> {
24+
let message = self.context.format_rfc3164(severity, Some(message));
25+
self.send_formatted(message.to_string().as_bytes())
26+
}
27+
28+
/// Send a message with the given severity as defined in RFC-5424.
29+
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
30+
&mut self,
31+
severity: $crate::Severity,
32+
msgid: Option<S>,
33+
elements: Vec<$crate::SDElement>,
34+
message: M,
35+
) -> io::Result<()> {
36+
let message = self
37+
.context
38+
.format_rfc5424(severity, msgid, elements, Some(message));
39+
self.send_formatted(message.to_string().as_bytes())
40+
}
41+
}
42+
};
43+
}
44+
45+
pub(crate) use impl_syslog_sender_common;

src/sender/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub use tcp::*;
3131
mod udp;
3232
pub use udp::*;
3333

34+
pub(crate) mod internal;
35+
3436
/// Static dispatch for the different sender types.
3537
#[derive(Debug)]
3638
pub enum SyslogSender {
@@ -81,6 +83,18 @@ impl SyslogSender {
8183
}
8284
}
8385

86+
/// Send a pre-formatted message.
87+
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
88+
match self {
89+
SyslogSender::Tcp(sender) => sender.send_formatted(formatted),
90+
SyslogSender::Udp(sender) => sender.send_formatted(formatted),
91+
#[cfg(unix)]
92+
SyslogSender::UnixDatagram(sender) => sender.send_formatted(formatted),
93+
#[cfg(unix)]
94+
SyslogSender::UnixStream(sender) => sender.send_formatted(formatted),
95+
}
96+
}
97+
8498
/// Flush the underlying writer if needed.
8599
pub fn flush(&mut self) -> io::Result<()> {
86100
match self {

src/sender/tcp.rs

+10-27
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
use std::borrow::Cow;
1616
use std::io;
1717
use std::io::BufWriter;
18+
use std::io::Write;
1819
use std::net::TcpStream;
1920
use std::net::ToSocketAddrs;
2021

2122
use crate::format::SyslogContext;
22-
use crate::SDElement;
23-
use crate::Severity;
23+
use crate::sender::internal::impl_syslog_sender_common;
2424

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

77-
/// Send a message with the given severity as defined in RFC-3164.
78-
pub fn send_rfc3164<M: std::fmt::Display>(
79-
&mut self,
80-
severity: Severity,
81-
message: M,
82-
) -> io::Result<()> {
83-
use std::io::Write;
84-
let message = self.context.format_rfc3164(severity, Some(message));
85-
write!(&mut self.writer, "{}{}", message, self.postfix)
86-
}
87-
88-
/// Send a message with the given severity as defined in RFC-5424.
89-
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
90-
&mut self,
91-
severity: Severity,
92-
msgid: Option<S>,
93-
elements: Vec<SDElement>,
94-
message: M,
95-
) -> io::Result<()> {
96-
use std::io::Write;
97-
let message = self
98-
.context
99-
.format_rfc5424(severity, msgid, elements, Some(message));
100-
write!(&mut self.writer, "{}{}", message, self.postfix)
77+
/// Send a pre-formatted message.
78+
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
79+
self.writer.write_all(formatted)?;
80+
self.writer.write_all(self.postfix.as_bytes())?;
81+
Ok(())
10182
}
10283

10384
/// Flush the writer.
@@ -106,3 +87,5 @@ impl TcpSender {
10687
self.writer.flush()
10788
}
10889
}
90+
91+
impl_syslog_sender_common!(TcpSender);

src/sender/udp.rs

+6-25
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use std::net::ToSocketAddrs;
1717
use std::net::UdpSocket;
1818

1919
use crate::format::SyslogContext;
20-
use crate::SDElement;
21-
use crate::Severity;
20+
use crate::sender::internal::impl_syslog_sender_common;
2221

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

65-
/// Send a message with the given severity as defined in RFC-3164.
66-
pub fn send_rfc3164<M: std::fmt::Display>(
67-
&mut self,
68-
severity: Severity,
69-
message: M,
70-
) -> io::Result<()> {
71-
let message = self.context.format_rfc3164(severity, Some(message));
72-
self.socket.send(message.to_string().as_bytes())?;
73-
Ok(())
74-
}
75-
76-
/// Send a message with the given severity as defined in RFC-5424.
77-
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
78-
&mut self,
79-
severity: Severity,
80-
msgid: Option<S>,
81-
elements: Vec<SDElement>,
82-
message: M,
83-
) -> io::Result<()> {
84-
let message = self
85-
.context
86-
.format_rfc5424(severity, msgid, elements, Some(message));
87-
self.socket.send(message.to_string().as_bytes())?;
64+
/// Send a pre-formatted message.
65+
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
66+
self.socket.send(formatted)?;
8867
Ok(())
8968
}
9069
}
70+
71+
impl_syslog_sender_common!(UdpSender);

src/sender/unix.rs

+12-51
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414

1515
use std::io;
1616
use std::io::BufWriter;
17+
use std::io::Write;
1718
use std::os::unix::net::UnixDatagram;
1819
use std::os::unix::net::UnixStream;
1920
use std::path::Path;
2021

2122
use crate::format::SyslogContext;
23+
use crate::sender::internal::impl_syslog_sender_common;
2224
use crate::sender::SyslogSender;
23-
use crate::SDElement;
24-
use crate::Severity;
2525

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

98-
/// Send a message with the given severity as defined in RFC-3164.
99-
pub fn send_rfc3164<M: std::fmt::Display>(
100-
&mut self,
101-
severity: Severity,
102-
message: M,
103-
) -> io::Result<()> {
104-
let message = self.context.format_rfc3164(severity, Some(message));
105-
self.socket.send(message.to_string().as_bytes())?;
106-
Ok(())
107-
}
108-
109-
/// Send a message with the given severity as defined in RFC-5424.
110-
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
111-
&mut self,
112-
severity: Severity,
113-
msgid: Option<S>,
114-
elements: Vec<SDElement>,
115-
message: M,
116-
) -> io::Result<()> {
117-
let message = self
118-
.context
119-
.format_rfc5424(severity, msgid, elements, Some(message));
120-
self.socket.send(message.to_string().as_bytes())?;
98+
/// Send a pre-formatted message.
99+
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
100+
self.socket.send(formatted)?;
121101
Ok(())
122102
}
123103
}
124104

105+
impl_syslog_sender_common!(UnixDatagramSender);
106+
125107
/// A syslog sender that sends messages to a Unix stream socket.
126108
///
127109
/// Typically, this sender is used to send messages to the local syslog daemon. Typical paths are
@@ -152,32 +134,9 @@ impl UnixStreamSender {
152134
&mut self.context
153135
}
154136

155-
/// Send a message with the given severity as defined in RFC-3164.
156-
pub fn send_rfc3164<M: std::fmt::Display>(
157-
&mut self,
158-
severity: Severity,
159-
message: M,
160-
) -> io::Result<()> {
161-
use std::io::Write;
162-
let message = self.context.format_rfc3164(severity, Some(message));
163-
write!(&mut self.writer, "{}", message)?;
164-
self.writer.write_all(&[0; 1])?;
165-
Ok(())
166-
}
167-
168-
/// Send a message with the given severity as defined in RFC-5424.
169-
pub fn send_rfc5424<S: Into<String>, M: std::fmt::Display>(
170-
&mut self,
171-
severity: Severity,
172-
msgid: Option<S>,
173-
elements: Vec<SDElement>,
174-
message: M,
175-
) -> io::Result<()> {
176-
use std::io::Write;
177-
let message = self
178-
.context
179-
.format_rfc5424(severity, msgid, elements, Some(message));
180-
write!(&mut self.writer, "{}", message)?;
137+
/// Send a pre-formatted message.
138+
pub fn send_formatted(&mut self, formatted: &[u8]) -> io::Result<()> {
139+
self.writer.write_all(formatted)?;
181140
self.writer.write_all(&[0; 1])?;
182141
Ok(())
183142
}
@@ -188,3 +147,5 @@ impl UnixStreamSender {
188147
self.writer.flush()
189148
}
190149
}
150+
151+
impl_syslog_sender_common!(UnixStreamSender);

src/severity.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::str::FromStr;
1717

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

0 commit comments

Comments
 (0)