Skip to content

Commit b6da88f

Browse files
committed
Implement logger adapter
1 parent a67ddbd commit b6da88f

5 files changed

Lines changed: 151 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ env_logger = { version = "0.6", optional = true }
3434
[dev-dependencies]
3535
bincode = "1.0"
3636
criterion = "0.2"
37+
fast-logger = "0.5.0"
3738
serde = "1.0"
3839
serde_derive = "1.0"
3940
quickcheck = "0.8"

src/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use crate::log;
12
use crate::net::constants::{DEFAULT_MTU, FRAGMENT_SIZE_DEFAULT, MAX_FRAGMENTS_DEFAULT};
2-
use std::{default::Default, time::Duration};
3+
use std::{default::Default, rc::Rc, time::Duration};
34

45
#[derive(Clone, Debug)]
56
/// Contains the configuration options to configure laminar for special use-cases.
@@ -54,6 +55,8 @@ pub struct Config {
5455
/// When we send a reliable packet, it is stored locally until an acknowledgement comes back to
5556
/// us, if that store grows to a size
5657
pub max_packets_in_flight: u16,
58+
/// Logger used for this instance of laminar. See [log::LaminarLogger] for more details.
59+
pub logger: Rc<dyn log::LaminarLogger>,
5760
}
5861

5962
impl Default for Config {
@@ -72,6 +75,7 @@ impl Default for Config {
7275
socket_event_buffer_size: 1024,
7376
socket_polling_timeout: Some(Duration::from_millis(1)),
7477
max_packets_in_flight: 512,
78+
logger: Rc::new(log::DefaultLogger),
7579
}
7680
}
7781
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ mod config;
2626
mod either;
2727
mod error;
2828
mod infrastructure;
29+
pub mod log;
2930
mod net;
3031
mod packet;
3132
mod protocol_version;

src/log.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//! Logging adapter for Laminar
2+
//!
3+
//! This module implements a simple, threaded-logger-friendly logging adapter. Logging adapters are
4+
//! used to attach an arbitrary logger into Laminar.
5+
use std::fmt;
6+
use std::sync::Arc;
7+
8+
/// Logger trait for laminar
9+
///
10+
/// Any user of Laminar can implement this trait to attach their favorite logger to an instance of
11+
/// laminar. The log levels correspond to the same log levels as in the `log` crate.
12+
pub trait LaminarLogger {
13+
/// Log a trace message
14+
fn trace(&self, disp: Displayer);
15+
/// Log a debug message
16+
fn debug(&self, disp: Displayer);
17+
/// Log an info message
18+
fn info(&self, disp: Displayer);
19+
/// Log a warning message
20+
fn warn(&self, disp: Displayer);
21+
/// Log an error message
22+
fn error(&self, disp: Displayer);
23+
}
24+
25+
// ---
26+
27+
/// Holds a handle to a formatter function while implementing the [fmt::Display] trait.
28+
pub struct Displayer {
29+
data: Arc<dyn Fn(&mut ::std::fmt::Formatter) -> ::std::fmt::Result + Send + Sync>,
30+
}
31+
32+
impl Displayer {
33+
pub(crate) fn new(
34+
delegate: Arc<dyn Fn(&mut ::std::fmt::Formatter) -> ::std::fmt::Result + Send + Sync>,
35+
) -> Self {
36+
Self { data: delegate }
37+
}
38+
}
39+
40+
impl fmt::Display for Displayer {
41+
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
42+
(self.data)(f)
43+
}
44+
}
45+
46+
// ---
47+
48+
pub(crate) struct DefaultLogger;
49+
50+
impl LaminarLogger for DefaultLogger {
51+
fn trace(&self, _: Displayer) {}
52+
fn debug(&self, _: Displayer) {}
53+
fn info(&self, _: Displayer) {}
54+
fn warn(&self, _: Displayer) {}
55+
fn error(&self, _: Displayer) {}
56+
}
57+
58+
impl fmt::Debug for dyn LaminarLogger {
59+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60+
write![f, "LaminarLogger"]
61+
}
62+
}
63+
64+
// ---
65+
66+
/// Format-friendly form of [log::LaminarLogger::trace]
67+
#[macro_export]
68+
macro_rules! trace {
69+
($logger:expr, $($fmt:expr),* $(,)?) => {{
70+
$logger.trace($crate::log::Displayer::new(::std::sync::Arc::new(move |f: &mut ::std::fmt::Formatter| { write![f, $($fmt),*] }) ));
71+
}};
72+
}
73+
74+
/// Format-friendly form of [log::LaminarLogger::debug]
75+
#[macro_export]
76+
macro_rules! debug {
77+
($logger:expr, $($fmt:expr),* $(,)?) => {{
78+
$logger.debug($crate::log::Displayer::new(::std::sync::Arc::new(move |f: &mut ::std::fmt::Formatter| { write![f, $($fmt),*] }) ));
79+
}};
80+
}
81+
82+
/// Format-friendly form of [log::LaminarLogger::info]
83+
#[macro_export]
84+
macro_rules! info {
85+
($logger:expr, $($fmt:expr),* $(,)?) => {{
86+
$logger.info($crate::log::Displayer::new(::std::sync::Arc::new(move |f: &mut ::std::fmt::Formatter| { write![f, $($fmt),*] }) ));
87+
}};
88+
}
89+
90+
/// Format-friendly form of [log::LaminarLogger::warn]
91+
#[macro_export]
92+
macro_rules! warn {
93+
($logger:expr, $($fmt:expr),* $(,)?) => {{
94+
$logger.warn($crate::log::Displayer::new(::std::sync::Arc::new(move |f: &mut ::std::fmt::Formatter| { write![f, $($fmt),*] }) ));
95+
}};
96+
}
97+
98+
/// Format-friendly form of [log::LaminarLogger::error]
99+
#[macro_export]
100+
macro_rules! error {
101+
($logger:expr, $($fmt:expr),* $(,)?) => {{
102+
$logger.error($crate::log::Displayer::new(::std::sync::Arc::new(move |f: &mut ::std::fmt::Formatter| { write![f, $($fmt),*] }) ));
103+
}};
104+
}

src/net/socket.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,4 +1204,44 @@ mod tests {
12041204

12051205
assert_eq!["99999", last_payload];
12061206
}
1207+
1208+
#[test]
1209+
fn log_adapter() {
1210+
use crate::log::{Displayer, LaminarLogger};
1211+
use fast_logger::Logger;
1212+
use std::{cell::RefCell, rc::Rc};
1213+
1214+
let mut cfg = Config::default();
1215+
1216+
struct MyAdapter {
1217+
logger: RefCell<Logger<Displayer>>,
1218+
}
1219+
1220+
impl LaminarLogger for MyAdapter {
1221+
fn trace(&self, disp: Displayer) {
1222+
self.logger.borrow_mut().trace(disp);
1223+
}
1224+
fn debug(&self, disp: Displayer) {
1225+
self.logger.borrow_mut().debug(disp);
1226+
}
1227+
fn info(&self, disp: Displayer) {
1228+
self.logger.borrow_mut().info(disp);
1229+
}
1230+
fn warn(&self, disp: Displayer) {
1231+
self.logger.borrow_mut().warn(disp);
1232+
}
1233+
fn error(&self, disp: Displayer) {
1234+
self.logger.borrow_mut().error(disp);
1235+
}
1236+
}
1237+
1238+
let mut logger = Logger::<Displayer>::spawn("laminar");
1239+
logger.set_colorize(true);
1240+
1241+
cfg.logger = Rc::new(MyAdapter {
1242+
logger: RefCell::new(logger),
1243+
});
1244+
1245+
Socket::bind_any_with_config(cfg).unwrap();
1246+
}
12071247
}

0 commit comments

Comments
 (0)