Skip to content

Commit e77699c

Browse files
committed
Add metrics tracking number of recently loaded crates/versions/platforms
1 parent 6d459cb commit e77699c

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

src/metrics/macros.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ macro_rules! metrics {
2020
$(#[$meta])*
2121
$metric_vis $metric: $ty,
2222
)*
23+
pub(crate) recent_releases: RecentReleases,
2324
}
2425
impl $name {
2526
$vis fn new() -> Result<Self, prometheus::Error> {
@@ -36,6 +37,7 @@ macro_rules! metrics {
3637
)*
3738
Ok(Self {
3839
registry,
40+
recent_releases: RecentReleases::new(),
3941
$(
4042
$(#[$meta])*
4143
$metric,

src/metrics/mod.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[macro_use]
22
mod macros;
33

4+
use std::{time::{Duration, Instant}, collections::HashMap, sync::Mutex};
45
use self::macros::MetricFromOpts;
56
use crate::db::Pool;
67
use crate::BuildQueue;
@@ -10,6 +11,7 @@ use prometheus::proto::MetricFamily;
1011
load_metric_type!(IntGauge as single);
1112
load_metric_type!(IntCounter as single);
1213
load_metric_type!(IntCounterVec as vec);
14+
load_metric_type!(IntGaugeVec as vec);
1315
load_metric_type!(HistogramVec as vec);
1416

1517
metrics! {
@@ -44,6 +46,13 @@ metrics! {
4446
/// The time it takes to render a rustdoc page
4547
pub(crate) rustdoc_rendering_times: HistogramVec["step"],
4648

49+
/// Count of recently accessed crates
50+
pub(crate) recent_krates: IntGaugeVec["duration"],
51+
/// Count of recently accessed versions of crates
52+
pub(crate) recent_versions: IntGaugeVec["duration"],
53+
/// Count of recently accessed platforms of versions of crates
54+
pub(crate) recent_platforms: IntGaugeVec["duration"],
55+
4756
/// Number of crates built
4857
pub(crate) total_builds: IntCounter,
4958
/// Number of builds that successfully generated docs
@@ -67,6 +76,69 @@ metrics! {
6776
namespace: "docsrs",
6877
}
6978

79+
#[derive(Debug)]
80+
pub(crate) struct RecentReleases {
81+
krates: Mutex<HashMap<String, Instant>>,
82+
versions: Mutex<HashMap<String, Instant>>,
83+
platforms: Mutex<HashMap<String, Instant>>,
84+
}
85+
86+
impl RecentReleases {
87+
pub(crate) fn new() -> Self {
88+
Self {
89+
krates: Mutex::new(HashMap::new()),
90+
versions: Mutex::new(HashMap::new()),
91+
platforms: Mutex::new(HashMap::new()),
92+
}
93+
}
94+
95+
pub(crate) fn record(&self, krate: &str, version: &str, target: &str) {
96+
self.krates.lock().unwrap().insert(krate.to_owned(), Instant::now());
97+
self.versions.lock().unwrap().insert(format!("{}/{}", krate, version), Instant::now());
98+
self.platforms.lock().unwrap().insert(format!("{}/{}/{}", krate, version, target), Instant::now());
99+
}
100+
101+
pub(crate) fn gather(&self, metrics: &Metrics) {
102+
fn inner(map: &mut HashMap<String, Instant>, metric: &IntGaugeVec) {
103+
let mut hour_count = 0;
104+
let mut half_hour_count = 0;
105+
let mut five_minute_count = 0;
106+
map.retain(|_, instant| {
107+
let elapsed = instant.elapsed();
108+
if elapsed > Duration::from_secs(60 * 60) {
109+
return false;
110+
}
111+
hour_count += 1;
112+
if elapsed > Duration::from_secs(30 * 60) {
113+
return true;
114+
}
115+
half_hour_count += 1;
116+
if elapsed > Duration::from_secs(5 * 60) {
117+
return true;
118+
}
119+
five_minute_count += 1;
120+
true
121+
});
122+
123+
metric
124+
.with_label_values(&["one hour"])
125+
.set(hour_count);
126+
127+
metric
128+
.with_label_values(&["half hour"])
129+
.set(half_hour_count);
130+
131+
metric
132+
.with_label_values(&["five minutes"])
133+
.set(five_minute_count);
134+
}
135+
136+
inner(&mut *self.krates.lock().unwrap(), &metrics.recent_krates);
137+
inner(&mut *self.versions.lock().unwrap(), &metrics.recent_versions);
138+
inner(&mut *self.platforms.lock().unwrap(), &metrics.recent_platforms);
139+
}
140+
}
141+
70142
impl Metrics {
71143
pub(crate) fn gather(
72144
&self,
@@ -82,6 +154,7 @@ impl Metrics {
82154
.set(queue.prioritized_count()? as i64);
83155
self.failed_crates_count.set(queue.failed_count()? as i64);
84156

157+
self.recent_releases.gather(self);
85158
self.gather_system_performance();
86159
Ok(self.registry.gather())
87160
}

src/web/metrics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct RequestRecorder {
3535
route_name: String,
3636
}
3737

38+
3839
impl RequestRecorder {
3940
pub fn new(handler: impl iron::Handler, route: impl Into<String>) -> Self {
4041
Self {

src/web/rustdoc.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
389389
format!("/crate/{}/{}", name, latest_version)
390390
};
391391

392+
let mut target = "";
393+
392394
// The path within this crate version's rustdoc output
393395
let inner_path = {
394396
let mut inner_path = req_path.clone();
@@ -397,12 +399,14 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
397399
inner_path.drain(..3).for_each(drop);
398400

399401
if inner_path.len() > 1 && krate.doc_targets.iter().any(|s| s == inner_path[0]) {
400-
inner_path.remove(0);
402+
target = inner_path.remove(0);
401403
}
402404

403405
inner_path.join("/")
404406
};
405407

408+
metrics.recent_releases.record(&name, &version, target);
409+
406410
rendering_time.step("rewrite html");
407411
RustdocPage {
408412
latest_path,

0 commit comments

Comments
 (0)