Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

metrics

+33 -7
Cargo.lock
···
"indexmap 2.9.0",
"ipnet",
"metrics",
-
"metrics-util",
+
"metrics-util 0.19.0",
"quanta",
"thiserror 1.0.69",
"tokio",
···
[[package]]
name = "metrics-exporter-prometheus"
-
version = "0.17.1"
+
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "989903b4c7abfa6827a8d1128ef42faf83f8969d429797c5431f236f2cae8b8b"
+
checksum = "2b166dea96003ee2531cf14833efedced545751d800f03535801d833313f8c15"
dependencies = [
"base64 0.22.1",
"http-body-util",
···
"indexmap 2.9.0",
"ipnet",
"metrics",
-
"metrics-util",
+
"metrics-util 0.20.0",
"quanta",
"thiserror 2.0.12",
"tokio",
···
"metrics",
"quanta",
"rand 0.8.5",
-
"rand_xoshiro",
+
"rand_xoshiro 0.6.0",
+
"sketches-ddsketch",
+
]
+
+
[[package]]
+
name = "metrics-util"
+
version = "0.20.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fe8db7a05415d0f919ffb905afa37784f71901c9a773188876984b4f769ab986"
+
dependencies = [
+
"crossbeam-epoch",
+
"crossbeam-utils",
+
"hashbrown 0.15.2",
+
"metrics",
+
"quanta",
+
"rand 0.9.1",
+
"rand_xoshiro 0.7.0",
"sketches-ddsketch",
···
[[package]]
+
name = "rand_xoshiro"
+
version = "0.7.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41"
+
dependencies = [
+
"rand_core 0.9.3",
+
]
+
+
[[package]]
name = "ratelimit"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"links",
"log",
"metrics",
-
"metrics-exporter-prometheus 0.17.1",
+
"metrics-exporter-prometheus 0.17.2",
"rand 0.9.1",
"schemars",
"semver",
···
"log",
"lsm-tree",
"metrics",
-
"metrics-exporter-prometheus 0.17.1",
+
"metrics-exporter-prometheus 0.17.2",
"schemars",
"semver",
"serde",
···
"handlebars",
"hickory-resolver",
"metrics",
+
"metrics-exporter-prometheus 0.17.2",
"rand 0.9.1",
"reqwest",
"serde",
+1
who-am-i/Cargo.toml
···
handlebars = { version = "6.3.2", features = ["dir_source"] }
hickory-resolver = "0.25.2"
metrics = "0.24.2"
+
metrics-exporter-prometheus = { version = "0.17.2", features = ["http-listener"] }
rand = "0.9.1"
reqwest = { version = "0.12.22", features = ["native-tls-vendored"] }
serde = { version = "1.0.219", features = ["derive"] }
+4 -1
who-am-i/src/expiring_task_map.rs
···
.run_until_cancelled(sleep(expiration))
.await
.is_some()
-
// is Some if the (sleep) task completed first
{
+
// is Some if the (sleep) task completed first
map.remove(&k);
cancel.cancel();
+
metrics::counter!("whoami_task_map_completions", "result" => "expired")
+
.increment(1);
}
});
···
}
pub fn take(&self, key: &str) -> Option<JoinHandle<T>> {
+
metrics::counter!("whoami_task_map_completions", "result" => "retrieved").increment(1);
// when the _guard drops, the token gets cancelled for us
self.0.map.remove(key).map(|(_, (_guard, handle))| handle)
}
+21 -1
who-am-i/src/main.rs
···
use clap::{ArgAction, Parser};
+
use metrics_exporter_prometheus::PrometheusBuilder;
use tokio_util::sync::CancellationToken;
use who_am_i::serve;
···
let args = Args::parse();
if args.allowed_hosts.is_empty() {
-
panic!("at least one --one-click host must be set");
+
panic!("at least one --allowed-host host must be set");
}
println!("starting with allowed_hosts hosts:");
for host in &args.allowed_hosts {
println!(" - {host}");
}
+
+
if let Err(e) = install_metrics_server() {
+
eprintln!("failed to install metrics server: {e:?}");
+
};
serve(shutdown, args.app_secret, args.allowed_hosts, args.dev).await;
}
+
+
fn install_metrics_server() -> Result<(), metrics_exporter_prometheus::BuildError> {
+
println!("installing metrics server...");
+
let host = [0, 0, 0, 0];
+
let port = 8765;
+
PrometheusBuilder::new()
+
.set_enable_unit_suffix(false)
+
.with_http_listener((host, port))
+
.install()?;
+
println!(
+
"metrics server installed! listening on http://{}.{}.{}.{}:{port}",
+
host[0], host[1], host[2], host[3]
+
);
+
Ok(())
+
}
+10 -7
who-am-i/src/oauth.rs
···
&self,
query: &str,
) -> core::result::Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
-
Ok(self
-
.0
-
.txt_lookup(query)
-
.await?
-
.iter()
-
.map(|txt| txt.to_string())
-
.collect())
+
match self.0.txt_lookup(query).await {
+
Ok(r) => {
+
metrics::counter!("whoami_resolve_dns_txt", "success" => "true").increment(1);
+
Ok(r.iter().map(|r| r.to_string()).collect())
+
}
+
Err(e) => {
+
metrics::counter!("whoami_resolve_dns_txt", "success" => "false").increment(1);
+
Err(e.into())
+
}
+
}
}
}
+25 -6
who-am-i/src/server.rs
···
headers: HeaderMap,
) -> impl IntoResponse {
let err = |reason, check_frame| {
+
metrics::counter!("whoami_auth_prompt", "ok" => "false", "reason" => reason).increment(1);
let info = json!({ "reason": reason, "check_frame": check_frame });
let html = RenderHtml("prompt-error", engine.clone(), info);
(StatusCode::BAD_REQUEST, html).into_response()
···
shutdown.child_token(),
);
+
metrics::counter!("whoami_auth_prompt", "ok" => "true", "known" => "true").increment(1);
let info = json!({
"did": did,
"fetch_key": fetch_key,
"parent_host": parent_host,
"parent_origin": parent_origin,
});
-
(frame_headers, jar, RenderHtml("prompt", engine, info)).into_response()
} else {
+
metrics::counter!("whoami_auth_prompt", "ok" => "true", "known" => "false").increment(1);
let info = json!({
"parent_host": parent_host,
"parent_origin": parent_origin,
···
}): State<AppState>,
Query(params): Query<UserInfoParams>,
) -> impl IntoResponse {
-
let err = |status, reason| (status, Json(json!({ "reason": reason }))).into_response();
+
let err = |status, reason: &str| {
+
metrics::counter!("whoami_user_info", "found" => "false", "reason" => reason.to_string())
+
.increment(1);
+
(status, Json(json!({ "reason": reason }))).into_response()
+
};
let Some(task_handle) = resolve_handles.take(&params.fetch_key) else {
return err(StatusCode::NOT_FOUND, "fetch key does not exist or expired");
···
StatusCode::INTERNAL_SERVER_ERROR,
&format!("handle appears invalid: {reason}"),
),
-
Ok(Ok(handle)) => Json(json!({ "handle": handle })).into_response(),
+
Ok(Ok(handle)) => {
+
metrics::counter!("whoami_user_info", "found" => "true").increment(1);
+
Json(json!({ "handle": handle })).into_response()
+
}
}
}
···
use atrium_identity::Error as IdError;
use atrium_oauth::Error as OAuthError;
-
let err = |code, reason| {
+
let err = |code, reason: &str| {
+
metrics::counter!("whoami_auth_start", "ok" => "false", "reason" => reason.to_string())
+
.increment(1);
let info = json!({
"result": "fail",
"reason": reason,
···
};
match oauth.begin(&params.handle).await {
-
Ok(auth_url) => (jar, Redirect::to(&auth_url)).into_response(),
Err(OAuthError::Identity(
IdError::NotFound | IdError::HttpStatus(StatusCode::NOT_FOUND),
)) => err(StatusCode::NOT_FOUND, "handle not found"),
···
Err(e) => {
eprintln!("begin auth failed: {e:?}");
err(StatusCode::INTERNAL_SERVER_ERROR, "unknown")
+
}
+
Ok(auth_url) => {
+
metrics::counter!("whoami_auth_start", "ok" => "true").increment(1);
+
(jar, Redirect::to(&auth_url)).into_response()
}
}
}
···
Query(params): Query<OAuthCallbackParams>,
jar: SignedCookieJar,
) -> Response {
-
let err = |code, result, reason| {
+
let err = |code, result, reason: &str| {
+
metrics::counter!("whoami_auth_complete", "ok" => "false", "reason" => reason.to_string())
+
.increment(1);
let info = json!({
"result": result,
"reason": reason,
···
},
shutdown.child_token(),
);
+
+
metrics::counter!("whoami_auth_complete", "ok" => "true").increment(1);
let info = json!({
"did": did,
"fetch_key": fetch_key,
···
}
async fn disconnect(jar: SignedCookieJar) -> impl IntoResponse {
+
metrics::counter!("whoami_disconnect").increment(1);
let jar = jar.remove(DID_COOKIE_KEY);
(jar, Json(json!({ "ok": true })))
}