Expose HTTP /stats endpoint

This commit is contained in:
Igor Katson 2024-08-21 12:20:36 +01:00
parent 5d3a93b8bd
commit 561c8b8a1d
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
5 changed files with 46 additions and 1 deletions

View file

@ -14,6 +14,7 @@ use crate::{
session::{
AddTorrent, AddTorrentOptions, AddTorrentResponse, ListOnlyResponse, Session, TorrentId,
},
session_stats::snapshot::SessionStatsSnapshot,
torrent_state::{
peer::stats::snapshot::{PeerStatsFilter, PeerStatsSnapshot},
FileStream, ManagedTorrentHandle,
@ -171,6 +172,10 @@ impl Api {
make_torrent_details(&info_hash, &handle.info().info, only_files.as_deref())
}
pub fn api_session_stats(&self) -> SessionStatsSnapshot {
self.session().stats_snapshot()
}
pub fn torrent_file_mime_type(
&self,
idx: TorrentIdOrHash,

View file

@ -63,6 +63,7 @@ impl HttpApi {
"GET /dht/table": "DHT routing table",
"GET /torrents": "List torrents",
"GET /torrents/playlist": "Generate M3U8 playlist for all files in all torrents",
"GET /stats": "Global session stats",
"POST /torrents/resolve_magnet": "Resolve a magnet to torrent file bytes",
"GET /torrents/{id_or_infohash}": "Torrent details",
"GET /torrents/{id_or_infohash}/haves": "The bitfield of have pieces",
@ -92,6 +93,10 @@ impl HttpApi {
state.api_dht_table().map(axum::Json)
}
async fn session_stats(State(state): State<ApiState>) -> impl IntoResponse {
axum::Json(state.api_session_stats())
}
async fn torrents_list(State(state): State<ApiState>) -> impl IntoResponse {
axum::Json(state.api_torrent_list())
}
@ -450,6 +455,7 @@ impl HttpApi {
.route("/rust_log", post(set_rust_log))
.route("/dht/stats", get(dht_stats))
.route("/dht/table", get(dht_table))
.route("/stats", get(session_stats))
.route("/torrents", get(torrents_list))
.route("/torrents/:id", get(torrent_details))
.route("/torrents/:id/haves", get(torrent_haves))

View file

@ -6,5 +6,5 @@ use crate::torrent_state::live::peers::stats::atomic::AggregatePeerStatsAtomic;
pub struct AtomicSessionStats {
pub fetched_bytes: AtomicU64,
pub uploaded_bytes: AtomicU64,
pub peers: AggregatePeerStatsAtomic,
pub(crate) peers: AggregatePeerStatsAtomic,
}

View file

@ -5,11 +5,13 @@ use std::{
use atomic::AtomicSessionStats;
use librqbit_core::speed_estimator::SpeedEstimator;
use snapshot::SessionStatsSnapshot;
use tracing::error_span;
use crate::Session;
pub mod atomic;
pub mod snapshot;
pub struct SessionStats {
pub atomic: Arc<AtomicSessionStats>,
@ -27,6 +29,12 @@ impl SessionStats {
}
}
impl Default for SessionStats {
fn default() -> Self {
Self::new()
}
}
impl Session {
pub(crate) fn start_speed_estimator_updater(self: &Arc<Self>) {
self.spawn(error_span!(parent: self.rs(), "speed_estimator"), {
@ -47,4 +55,8 @@ impl Session {
}
})
}
pub fn stats_snapshot(&self) -> SessionStatsSnapshot {
SessionStatsSnapshot::from(&self.stats)
}
}

View file

@ -0,0 +1,22 @@
use serde::Serialize;
use crate::torrent_state::{peers::stats::snapshot::AggregatePeerStats, stats::Speed};
use super::SessionStats;
#[derive(Debug, Serialize)]
pub struct SessionStatsSnapshot {
download_speed: Speed,
upload_speed: Speed,
peers: AggregatePeerStats,
}
impl From<&SessionStats> for SessionStatsSnapshot {
fn from(s: &SessionStats) -> Self {
Self {
download_speed: s.down_speed_estimator.mbps().into(),
upload_speed: s.up_speed_estimator.mbps().into(),
peers: AggregatePeerStats::from(&s.atomic.peers),
}
}
}