···
1587
1587
]
1588
1588
1589
1589
[[package]]
1590
1590
+
name = "endian-type"
1591
1591
+
version = "0.1.2"
1592
1592
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1593
1593
+
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
1594
1594
+
1595
1595
+
[[package]]
1590
1596
name = "enum-as-inner"
1591
1597
version = "0.6.1"
1592
1598
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2680
2686
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
2681
2687
dependencies = [
2682
2688
"equivalent",
2683
2683
-
"hashbrown 0.15.2",
2689
2689
+
"hashbrown 0.16.1",
2684
2690
"serde",
2685
2691
"serde_core",
2686
2692
]
···
3273
3279
"indexmap 2.11.4",
3274
3280
"ipnet",
3275
3281
"metrics",
3276
3276
-
"metrics-util 0.20.0",
3282
3282
+
"metrics-util 0.20.1",
3277
3283
"quanta",
3278
3284
"thiserror 2.0.16",
3279
3285
"tokio",
···
3314
3320
3315
3321
[[package]]
3316
3322
name = "metrics-util"
3317
3317
-
version = "0.20.0"
3323
3323
+
version = "0.20.1"
3318
3324
source = "registry+https://github.com/rust-lang/crates.io-index"
3319
3319
-
checksum = "fe8db7a05415d0f919ffb905afa37784f71901c9a773188876984b4f769ab986"
3325
3325
+
checksum = "cdfb1365fea27e6dd9dc1dbc19f570198bc86914533ad639dae939635f096be4"
3320
3326
dependencies = [
3327
3327
+
"aho-corasick",
3321
3328
"crossbeam-epoch",
3322
3329
"crossbeam-utils",
3323
3323
-
"hashbrown 0.15.2",
3330
3330
+
"hashbrown 0.16.1",
3331
3331
+
"indexmap 2.11.4",
3324
3332
"metrics",
3333
3333
+
"ordered-float",
3325
3334
"quanta",
3335
3335
+
"radix_trie",
3326
3336
"rand 0.9.1",
3327
3337
"rand_xoshiro 0.7.0",
3328
3338
"sketches-ddsketch",
···
3460
3470
]
3461
3471
3462
3472
[[package]]
3473
3473
+
name = "nibble_vec"
3474
3474
+
version = "0.1.0"
3475
3475
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3476
3476
+
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
3477
3477
+
dependencies = [
3478
3478
+
"smallvec",
3479
3479
+
]
3480
3480
+
3481
3481
+
[[package]]
3463
3482
name = "nix"
3464
3483
version = "0.30.1"
3465
3484
source = "registry+https://github.com/rust-lang/crates.io-index"
···
3687
3706
"openssl-src",
3688
3707
"pkg-config",
3689
3708
"vcpkg",
3709
3709
+
]
3710
3710
+
3711
3711
+
[[package]]
3712
3712
+
name = "ordered-float"
3713
3713
+
version = "5.1.0"
3714
3714
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3715
3715
+
checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d"
3716
3716
+
dependencies = [
3717
3717
+
"num-traits",
3690
3718
]
3691
3719
3692
3720
[[package]]
···
4316
4344
version = "5.2.0"
4317
4345
source = "registry+https://github.com/rust-lang/crates.io-index"
4318
4346
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
4347
4347
+
4348
4348
+
[[package]]
4349
4349
+
name = "radix_trie"
4350
4350
+
version = "0.2.1"
4351
4351
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4352
4352
+
checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
4353
4353
+
dependencies = [
4354
4354
+
"endian-type",
4355
4355
+
"nibble_vec",
4356
4356
+
]
4319
4357
4320
4358
[[package]]
4321
4359
name = "rand"
···
5215
5253
"log",
5216
5254
"metrics",
5217
5255
"metrics-exporter-prometheus 0.17.2",
5256
5256
+
"metrics-util 0.20.1",
5218
5257
"poem 3.1.12 (git+https://github.com/uniphil/poem.git?branch=acme%2Fissue-async)",
5219
5258
"poem-openapi 5.1.16 (git+https://github.com/uniphil/poem.git?branch=acme%2Fissue-async)",
5220
5259
"reqwest",
···
17
17
links = { path = "../links" }
18
18
log = "0.4.27"
19
19
metrics = "0.24.2"
20
20
+
metrics-util = "0.20.1"
20
21
metrics-exporter-prometheus = { version = "0.17.1", features = ["http-listener"] }
21
22
poem = { git = "https://github.com/uniphil/poem.git", branch = "acme/issue-async", features = ["acme", "static-files"] }
22
23
poem-openapi = { git = "https://github.com/uniphil/poem.git", branch = "acme/issue-async", features = ["scalar"] }
···
278
278
) -> Result<(), metrics_exporter_prometheus::BuildError> {
279
279
log::info!("installing metrics server...");
280
280
PrometheusBuilder::new()
281
281
-
.set_buckets(&[0.001, 0.006, 0.036, 0.216, 1.296, 7.776, 45.656])?
281
281
+
.set_buckets(&[
282
282
+
0.025, 0.045, 0.080, 0.144, 0.259, 0.465, 0.833, 1.495, 2.682, 4.812, 8.633, 15.488,
283
283
+
27.785,
284
284
+
])?
282
285
.set_bucket_duration(std::time::Duration::from_secs(15))?
283
286
.set_bucket_count(std::num::NonZero::new(4).unwrap()) // count * duration = bucket lifetime
287
287
+
.idle_timeout(
288
288
+
metrics_util::MetricKindMask::ALL,
289
289
+
Some(std::time::Duration::from_secs(300)),
290
290
+
)
284
291
.set_enable_unit_suffix(false) // this seemed buggy for constellation (sometimes wouldn't engage)
285
292
.with_http_listener(bind_metrics)
286
293
.install()?;
···
15
15
use poem::{
16
16
Endpoint, EndpointExt, IntoResponse, Route, RouteScheme, Server,
17
17
endpoint::{StaticFileEndpoint, make_sync},
18
18
-
http::Method,
18
18
+
http::{Method, StatusCode},
19
19
listener::{
20
20
Listener, TcpListener,
21
21
acme::{AutoCert, ChallengeType, LETS_ENCRYPT_PRODUCTION, LETS_ENCRYPT_STAGING},
···
1305
1305
}
1306
1306
1307
1307
#[poem::handler]
1308
1308
-
async fn https_plz() -> (poem::http::StatusCode, &'static str) {
1308
1308
+
async fn https_plz() -> (StatusCode, &'static str) {
1309
1309
(
1310
1310
-
poem::http::StatusCode::MISDIRECTED_REQUEST,
1310
1310
+
StatusCode::MISDIRECTED_REQUEST,
1311
1311
"this service must be accessed with https (port 443).",
1312
1312
)
1313
1313
}
···
1543
1543
}
1544
1544
1545
1545
async fn request_counter<E: Endpoint>(next: E, req: poem::Request) -> poem::Result<poem::Response> {
1546
1546
-
let t0 = std::time::Instant::now();
1546
1546
+
// extract request details before we lose access
1547
1547
let method = req.method().to_string();
1548
1548
let path = req.uri().path().to_string();
1549
1549
+
let h = req.headers();
1550
1550
+
let ua = match h.get("user-agent").and_then(|v| v.to_str().ok()) {
1551
1551
+
None => "[no ua]".to_string(),
1552
1552
+
Some(ua) if ua.starts_with("Mozilla/") => "[browser-y]".to_string(),
1553
1553
+
Some(ua) => format!("ua:{ua}"),
1554
1554
+
};
1555
1555
+
let origin = h
1556
1556
+
.get("origin")
1557
1557
+
.and_then(|v| v.to_str().ok())
1558
1558
+
.map(|o| format!("origin:{o}"))
1559
1559
+
.unwrap_or("[no origin]".to_string());
1560
1560
+
1561
1561
+
// actually forward the request down
1562
1562
+
let t0 = std::time::Instant::now();
1549
1563
let res = next.call(req).await?.into_response();
1564
1564
+
let dt = t0.elapsed();
1565
1565
+
1566
1566
+
// grab remaining details
1567
1567
+
let status = res.status();
1568
1568
+
let path = match status {
1569
1569
+
StatusCode::MISDIRECTED_REQUEST => "[rejected http]",
1570
1570
+
StatusCode::NOT_FOUND => "[not found]",
1571
1571
+
_ => &path,
1572
1572
+
};
1550
1573
metrics::histogram!(
1551
1574
"server_request",
1552
1575
"endpoint" => format!("{method} {path}"),
1553
1553
-
"status" => res.status().to_string(),
1576
1576
+
"status" => status.as_str().to_string(), // just the number
1554
1577
)
1555
1555
-
.record(t0.elapsed());
1578
1578
+
.record(dt);
1579
1579
+
1580
1580
+
metrics::counter!(
1581
1581
+
"server_request_source",
1582
1582
+
"ua" => ua,
1583
1583
+
"origin" => origin,
1584
1584
+
)
1585
1585
+
.increment(1);
1586
1586
+
1556
1587
Ok(res)
1557
1588
}