Skip to content

Commit 81a39f6

Browse files
Nemo157Joshua Nelson
authored and
Joshua Nelson
committed
Add metrics tracking number of recently loaded crates/versions/platforms
1 parent 9c27d80 commit 81a39f6

File tree

3 files changed

+102
-4
lines changed

3 files changed

+102
-4
lines changed

src/metrics/macros.rs

+2
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

+90
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ use crate::db::Pool;
66
use crate::BuildQueue;
77
use failure::Error;
88
use prometheus::proto::MetricFamily;
9+
use std::{
10+
collections::HashMap,
11+
sync::Mutex,
12+
time::{Duration, Instant},
13+
};
914

1015
load_metric_type!(IntGauge as single);
1116
load_metric_type!(IntCounter as single);
1217
load_metric_type!(IntCounterVec as vec);
18+
load_metric_type!(IntGaugeVec as vec);
1319
load_metric_type!(HistogramVec as vec);
1420

1521
metrics! {
@@ -44,6 +50,13 @@ metrics! {
4450
/// The time it takes to render a rustdoc page
4551
pub(crate) rustdoc_rendering_times: HistogramVec["step"],
4652

53+
/// Count of recently accessed crates
54+
pub(crate) recent_krates: IntGaugeVec["duration"],
55+
/// Count of recently accessed versions of crates
56+
pub(crate) recent_versions: IntGaugeVec["duration"],
57+
/// Count of recently accessed platforms of versions of crates
58+
pub(crate) recent_platforms: IntGaugeVec["duration"],
59+
4760
/// Number of crates built
4861
pub(crate) total_builds: IntCounter,
4962
/// Number of builds that successfully generated docs
@@ -67,6 +80,82 @@ metrics! {
6780
namespace: "docsrs",
6881
}
6982

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

174+
self.recent_releases.gather(self);
85175
self.gather_system_performance();
86176
Ok(self.registry.gather())
87177
}

src/web/rustdoc.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -415,16 +415,22 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
415415
.iter()
416416
.any(|s| s == inner_path[0])
417417
{
418-
let mut target = inner_path.remove(0).to_string();
419-
target.push('/');
420-
target
418+
inner_path.remove(0)
421419
} else {
422-
String::new()
420+
""
423421
};
424422

425423
(target, inner_path.join("/"))
426424
};
427425

426+
metrics.recent_releases.record(&name, &version, target);
427+
428+
let target = if target == "" {
429+
String::new()
430+
} else {
431+
format!("{}/", target)
432+
};
433+
428434
rendering_time.step("rewrite html");
429435
RustdocPage {
430436
latest_path,

0 commit comments

Comments
 (0)