melib/connections: add opt id string for tracing

pull/262/head
Manos Pitsidianakis 2023-07-22 21:51:37 +03:00
parent 8ecdb6df31
commit 9216e7bc65
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
4 changed files with 147 additions and 16 deletions

View File

@ -186,7 +186,7 @@ impl ImapStream {
TcpStream::connect(addr)?
});
#[cfg(feature = "imap-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("imap");
conn
})?;
if server_conf.use_starttls {
@ -288,7 +288,7 @@ impl ImapStream {
TcpStream::connect(addr)?
});
#[cfg(feature = "imap-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("imap");
conn
})?
};

View File

@ -85,7 +85,7 @@ impl NntpStream {
std::time::Duration::new(16, 0),
)?);
#[cfg(feature = "nntp-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("nntp");
conn
})?
};
@ -178,7 +178,7 @@ impl NntpStream {
ret.stream = AsyncWrapper::new({
let conn = Connection::new_tls(conn_result?);
#[cfg(feature = "nntp-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("nntp");
conn
})
.chain_err_summary(|| format!("Could not initiate TLS negotiation to {}.", path))?;

View File

@ -268,7 +268,7 @@ impl SmtpConnection {
std::time::Duration::new(4, 0),
)?);
#[cfg(feature = "smtp-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("smtp");
AsyncWrapper::new(conn)?
};
@ -351,7 +351,7 @@ impl SmtpConnection {
AsyncWrapper::new({
let conn = Connection::new_tls(conn);
#[cfg(feature = "smtp-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("smtp");
conn
})?
};
@ -366,7 +366,7 @@ impl SmtpConnection {
std::time::Duration::new(4, 0),
)?);
#[cfg(feature = "smtp-trace")]
let conn = conn.trace(true);
let conn = conn.trace(true).with_id("smtp");
conn
})?;
res.clear();

View File

@ -38,28 +38,84 @@ use libc::TCP_KEEPALIVE as KEEPALIVE_OPTION;
use libc::TCP_KEEPIDLE as KEEPALIVE_OPTION;
use libc::{self, c_int, c_void};
#[derive(Debug)]
pub enum Connection {
Tcp {
inner: std::net::TcpStream,
id: Option<&'static str>,
trace: bool,
},
Fd {
inner: std::os::unix::io::RawFd,
id: Option<&'static str>,
trace: bool,
},
#[cfg(feature = "tls")]
Tls {
inner: native_tls::TlsStream<Self>,
id: Option<&'static str>,
trace: bool,
},
#[cfg(feature = "deflate_compression")]
Deflate {
inner: DeflateEncoder<DeflateDecoder<Box<Self>>>,
id: Option<&'static str>,
trace: bool,
},
}
impl std::fmt::Debug for Connection {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Tcp {
ref trace,
ref inner,
ref id,
} => fmt
.debug_struct(stringify!(Connection))
.field("variant", &stringify!(Tcp))
.field(stringify!(trace), trace)
.field(stringify!(id), id)
.field(stringify!(inner), inner)
.finish(),
#[cfg(feature = "tls")]
Tls {
ref trace,
ref inner,
ref id,
} => fmt
.debug_struct(stringify!(Connection))
.field("variant", &stringify!(Tls))
.field(stringify!(trace), trace)
.field(stringify!(id), id)
.field(stringify!(inner), inner.get_ref())
.finish(),
Fd {
ref trace,
ref inner,
ref id,
} => fmt
.debug_struct(stringify!(Connection))
.field("variant", &stringify!(Fd))
.field(stringify!(trace), trace)
.field(stringify!(id), id)
.field(stringify!(inner), inner)
.finish(),
#[cfg(feature = "deflate_compression")]
Deflate {
ref trace,
ref inner,
ref id,
} => fmt
.debug_struct(stringify!(Connection))
.field("variant", &stringify!(Deflate))
.field(stringify!(trace), trace)
.field(stringify!(id), id)
.field(stringify!(inner), inner)
.finish(),
}
}
}
use Connection::*;
macro_rules! syscall {
@ -81,12 +137,14 @@ impl Connection {
#[cfg(feature = "deflate_compression")]
pub fn deflate(mut self) -> Self {
let trace = self.is_trace_enabled();
let id = self.id();
self.set_trace(false);
Self::Deflate {
inner: DeflateEncoder::new(
DeflateDecoder::new_with_buf(Box::new(self), vec![0; Self::IO_BUF_SIZE]),
Compression::default(),
),
id,
trace,
}
}
@ -94,15 +152,17 @@ impl Connection {
#[cfg(feature = "tls")]
pub fn new_tls(mut inner: native_tls::TlsStream<Self>) -> Self {
let trace = inner.get_ref().is_trace_enabled();
let id = inner.get_ref().id();
if trace {
inner.get_mut().set_trace(false);
}
Self::Tls { inner, trace }
Self::Tls { inner, id, trace }
}
pub fn new_tcp(inner: std::net::TcpStream) -> Self {
Self::Tcp {
inner,
id: None,
trace: false,
}
}
@ -121,6 +181,20 @@ impl Connection {
self
}
pub fn with_id(mut self, val: &'static str) -> Self {
match self {
Tcp { ref mut id, .. } => *id = Some(val),
#[cfg(feature = "tls")]
Tls { ref mut id, .. } => *id = Some(val),
Fd { ref mut id, .. } => {
*id = Some(val);
}
#[cfg(feature = "deflate_compression")]
Deflate { ref mut id, .. } => *id = Some(val),
}
self
}
pub fn set_trace(&mut self, val: bool) {
match self {
Tcp { ref mut trace, .. } => *trace = val,
@ -136,7 +210,15 @@ impl Connection {
pub fn set_nonblocking(&self, nonblocking: bool) -> std::io::Result<()> {
if self.is_trace_enabled() {
log::trace!("{:?} set_nonblocking({:?})", self, nonblocking);
let id = self.id();
log::trace!(
"{}{}{}{:?} set_nonblocking({:?})",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
nonblocking
);
}
match self {
Tcp { ref inner, .. } => inner.set_nonblocking(nonblocking),
@ -162,7 +244,15 @@ impl Connection {
pub fn set_read_timeout(&self, dur: Option<Duration>) -> std::io::Result<()> {
if self.is_trace_enabled() {
log::trace!("{:?} set_read_timeout({:?})", self, dur);
let id = self.id();
log::trace!(
"{}{}{}{:?} set_read_timeout({:?})",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
dur
);
}
match self {
Tcp { ref inner, .. } => inner.set_read_timeout(dur),
@ -176,7 +266,15 @@ impl Connection {
pub fn set_write_timeout(&self, dur: Option<Duration>) -> std::io::Result<()> {
if self.is_trace_enabled() {
log::trace!("{:?} set_write_timeout({:?})", self, dur);
let id = self.id();
log::trace!(
"{}{}{}{:?} set_write_timeout({:?})",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
dur
);
}
match self {
Tcp { ref inner, .. } => inner.set_write_timeout(dur),
@ -207,7 +305,15 @@ impl Connection {
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> std::io::Result<()> {
if self.is_trace_enabled() {
log::trace!("{:?} set_keepalive({:?})", self, keepalive);
let id = self.id();
log::trace!(
"{}{}{}{:?} set_keepalive({:?})",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
keepalive
);
}
if matches!(self, Fd { .. }) {
return Ok(());
@ -264,6 +370,16 @@ impl Connection {
Deflate { trace, .. } => *trace,
}
}
fn id(&self) -> Option<&'static str> {
match self {
Fd { id, .. } | Tcp { id, .. } => *id,
#[cfg(feature = "tls")]
Tls { id, .. } => *id,
#[cfg(feature = "deflate_compression")]
Deflate { id, .. } => *id,
}
}
}
impl Drop for Connection {
@ -291,15 +407,26 @@ impl std::io::Read for Connection {
Deflate { ref mut inner, .. } => inner.read(buf),
};
if self.is_trace_enabled() {
let id = self.id();
if let Ok(len) = &res {
log::trace!(
"{:?} read {:?} bytes:{:?}",
"{}{}{}{:?} read {:?} bytes:{:?}",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
len,
String::from_utf8_lossy(&buf[..*len])
);
} else {
log::trace!("{:?} could not read {:?}", self, &res);
log::trace!(
"{}{}{}{:?} could not read {:?}",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
&res
);
}
}
res
@ -309,8 +436,12 @@ impl std::io::Read for Connection {
impl std::io::Write for Connection {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
if self.is_trace_enabled() {
let id = self.id();
log::trace!(
"{:?} writing {} bytes:{:?}",
"{}{}{}{:?} writing {} bytes:{:?}",
if id.is_some() { "[" } else { "" },
if let Some(id) = id.as_ref() { id } else { "" },
if id.is_some() { "]: " } else { "" },
self,
buf.len(),
String::from_utf8_lossy(buf)