WEB Debug + Trace

Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
Alexey
2026-08-25 12:59:41 +03:00
parent 0779cd0901
commit e774bc8c9a
48 changed files with 3744 additions and 435 deletions
+45 -2
View File
@@ -8,6 +8,7 @@ use hyper::body::{Body, Frame, SizeHint};
use parking_lot::Mutex;
use super::{BoxError, HttpBody};
use crate::web::trace::{HttpTraceExchange, TraceBodyState, TraceDirection};
/// Request lifecycle guard that refreshes HTTP connection activity on completion.
pub(super) struct RequestActivity {
@@ -32,12 +33,33 @@ impl Drop for RequestActivity {
pub(super) struct ActivityBody {
inner: HttpBody,
activity: RequestActivity,
trace: Option<Arc<HttpTraceExchange>>,
terminal: bool,
}
impl ActivityBody {
/// Binds one response body to its request activity guard.
pub(super) fn new(inner: HttpBody, activity: RequestActivity) -> Self {
Self { inner, activity }
pub(super) fn new(
inner: HttpBody,
activity: RequestActivity,
trace: Option<Arc<HttpTraceExchange>>,
) -> Self {
Self {
inner,
activity,
trace,
terminal: false,
}
}
fn finish(&mut self, state: TraceBodyState) {
if self.terminal {
return;
}
self.terminal = true;
if let Some(trace) = &self.trace {
trace.body_finished(TraceDirection::Response, state);
}
}
}
@@ -50,6 +72,21 @@ impl Body for ActivityBody {
context: &mut Context<'_>,
) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
let result = Pin::new(&mut self.inner).poll_frame(context);
match &result {
Poll::Ready(Some(Ok(frame))) => {
if let Some(data) = frame.data_ref()
&& let Some(trace) = &self.trace
{
trace.body_data(TraceDirection::Response, data);
}
if self.inner.is_end_stream() {
self.finish(TraceBodyState::Complete);
}
}
Poll::Ready(Some(Err(_))) => self.finish(TraceBodyState::Error),
Poll::Ready(None) => self.finish(TraceBodyState::Complete),
Poll::Pending => {}
}
if result.is_ready() {
*self.activity.last_activity.lock() = Instant::now();
}
@@ -64,3 +101,9 @@ impl Body for ActivityBody {
self.inner.size_hint()
}
}
impl Drop for ActivityBody {
fn drop(&mut self) {
self.finish(TraceBodyState::Aborted);
}
}