use qlog::{
CommonFields, Configuration, TraceSeq, VantagePoint, VantagePointType, streamer::QlogStreamer,
};
usecrate::Role;
#[derive(Debug, Clone, Default)] pubstruct Qlog { /// Both the inner and the outer `Option` are set to `None` /// on failure. The inner `None` will disable qlog for all other /// references (correctness). The outer `None` will prevent /// the local instance from de-referencing the `Rc` again /// (performance).
inner: Option<Rc<RefCell<Option<SharedStreamer>>>>,
}
impl Qlog { /// Create an enabled `Qlog` configuration backed by a file. /// /// # Errors /// /// Will return `qlog::Error` if it cannot write to the new file. pubfn enabled_with_file<D: Display>( mut qlog_path: PathBuf,
role: Role,
title: Option<String>,
description: Option<String>,
file_prefix: D,
now: Instant,
) -> Result<Self, qlog::Error> {
qlog_path.push(format!("{file_prefix}.sqlog"));
let file = OpenOptions::new()
.write(true) // As a server, the original DCID is chosen by the client. Using // create_new() prevents attackers from overwriting existing logs.
.create_new(true)
.open(&qlog_path)?;
/// Create an enabled `Qlog` configuration. /// /// This needs to be called before the connection is used, because otherwise `Qlog`-logging will /// remain disabled (for performance reasons). /// /// # Errors /// /// Will return `qlog::Error` if it cannot write to the new log. pubfn enabled(mut streamer: QlogStreamer, qlog_path: PathBuf) -> Result<Self, qlog::Error> {
streamer.start_log()?;
/// Returns true if qlog is enabled. #[must_use] pubfn is_enabled(&self) -> bool { self.inner.as_ref().is_some_and(|rc| rc.borrow().is_some())
}
/// If logging enabled, closure may generate an event to be logged. pubfn add_event_at<F>(&mutself, f: F, now: Instant) where
F: FnOnce() -> Option<qlog::events::EventData>,
{ self.add_event_with_stream(|s| { iflet Some(ev_data) = f() {
s.add_event_data_with_instant(ev_data, now)?;
}
Ok(())
});
}
/// If logging enabled, closure is given the Qlog stream to write events and /// frames to. pubfn add_event_with_stream<F>(&mutself, f: F) where
F: FnOnce(&mut QlogStreamer) -> Result<(), qlog::Error>,
{ let Some(inner) = self.inner.as_mut() else { return;
};
letmut borrow = inner.borrow_mut();
let Some(shared_streamer) = borrow.as_mut() else {
drop(borrow); // Set the outer Option to None to prevent future dereferences. self.inner = None; return;
};
match f(&mut shared_streamer.streamer) { // `Error::Done` means "event was below the importance threshold" - not an actual error.
Ok(()) | Err(qlog::Error::Done) => (),
Err(e) => {
log::error!("Qlog event generation failed with error {e}; closing qlog."); // Set the inner Option to None to disable future logging for other references.
*borrow = None; // Explicitly drop the RefCell borrow to release the mutable borrow.
drop(borrow); // Set the outer Option to None to prevent future dereferences. self.inner = None;
}
}
}
}
#[test] fn add_event_with_stream_error_disables_logging() { let (mut log, contents) = test_fixture::new_neqo_qlog(); letmut log_clone = log.clone(); let before_error = contents.to_string();
log.add_event_with_stream(|_| Err(qlog::Error::IoError(std::io::Error::other("e")))); // The cloned instance still has inner=Some, but the RefCell contains None.
log_clone.add_event_at(|| Some(EV_DATA), test_fixture::now());
assert_eq!(contents.to_string(), before_error);
}
#[test] fn is_enabled() { // Disabled by default.
assert!(!Qlog::disabled().is_enabled()); // Enabled when backed by a live streamer. let (log, _contents) = test_fixture::new_neqo_qlog();
assert!(log.is_enabled()); // Disabled on a clone whose underlying streamer was killed by a write error. letmut log = log; let clone = log.clone();
log.add_event_with_stream(|_| Err(qlog::Error::IoError(std::io::Error::other("e"))));
assert!(!clone.is_enabled());
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet am 2026-08-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.