Skip to content

Commit 86c59b0

Browse files
committed
feat: add metrics to perms middleware
1 parent 8493d96 commit 86c59b0

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ name = "init4-bin-base"
44
description = "Internal utilities for binaries produced by the init4 team"
55
keywords = ["init4", "bin", "base"]
66

7-
version = "0.14.0"
7+
version = "0.14.1"
88
edition = "2021"
99
rust-version = "1.85"
1010
authors = ["init4", "James Prestwich", "evalir"]

src/perms/middleware.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,35 @@ use axum::{
1111
Json,
1212
};
1313
use core::fmt;
14+
use metrics::{counter, describe_counter};
15+
use opentelemetry::trace::Status;
1416
use serde::Serialize;
15-
use std::{future::Future, pin::Pin, sync::Arc};
17+
use std::{
18+
borrow::Cow,
19+
future::Future,
20+
pin::Pin,
21+
sync::{Arc, LazyLock},
22+
};
1623
use tower::{Layer, Service};
1724
use tracing::info;
25+
use tracing_opentelemetry::OpenTelemetrySpanExt;
26+
27+
const MISSING_HEADER: &str = "init4.perms.missing_header";
28+
const MISSING_HEADER_DESCR: &str =
29+
"Counts the number of requests missing the authentication header";
30+
31+
const PERMISSION_DENIED: &str = "init4.perms.permission_denied";
32+
const PERMISSION_DENIED_DESCR: &str =
33+
"Counts the number of requests denied due to builder permissioning";
34+
35+
const SUCCESS: &str = "init4.perms.success";
36+
const SUCCESS_DESCR: &str = "Counts the number of auths allowed due to builder permissioning";
37+
38+
static DESCRIBE: LazyLock<()> = LazyLock::new(|| {
39+
describe_counter!(MISSING_HEADER, MISSING_HEADER_DESCR);
40+
describe_counter!(PERMISSION_DENIED, PERMISSION_DENIED_DESCR);
41+
describe_counter!(SUCCESS, SUCCESS_DESCR);
42+
});
1843

1944
/// Possible API error responses when a builder permissioning check fails.
2045
#[derive(Serialize)]
@@ -155,6 +180,8 @@ where
155180
fn call(&mut self, req: Request) -> Self::Future {
156181
let mut this = self.clone();
157182

183+
LazyLock::force(&DESCRIBE);
184+
158185
Box::pin(async move {
159186
let span = tracing::info_span!(
160187
"builder::permissioning",
@@ -167,37 +194,42 @@ where
167194
.calc()
168195
.current_point_within_slot()
169196
.expect("host chain has started"),
170-
permissioning_error = tracing::field::Empty,
197+
otel.status_code = tracing::field::Empty
171198
);
172199

173200
let guard = span.enter();
174201

175-
info!("builder permissioning check started");
176-
177202
// Check if the sub is in the header.
178203
let sub = match validate_header_sub(req.headers().get("x-jwt-claim-sub")) {
179204
Ok(sub) => sub,
180205
Err(err) => {
181-
span.record("permissioning_error", err.1.message);
206+
span.set_status(Status::Error {
207+
description: Cow::Owned(err.1.message.to_string()),
208+
});
182209
info!(api_err = %err.1.message, "permission denied");
210+
counter!("init4.perms.missing_header").increment(1);
183211
return Ok(err.into_response());
184212
}
185213
};
186214

187215
span.record("requesting_builder", sub);
188216

189217
if let Err(err) = this.builders.is_builder_permissioned(sub) {
190-
span.record("permissioning_error", err.to_string());
191-
info!(api_err = %err, "permission denied");
218+
span.set_status(Status::Error {
219+
description: Cow::Owned(err.to_string()),
220+
});
192221

193222
let hint = builder_permissioning_hint(&err);
194223

224+
counter!("init4.perms.permission_denied", "builder" => sub.to_string())
225+
.increment(1);
226+
195227
return Ok(ApiError::permission_denied(hint).into_response());
196228
}
197229

198-
info!("builder permissioned successfully");
199-
200230
drop(guard);
231+
info!("builder permissioned successfully");
232+
counter!(SUCCESS, "builder" => sub.to_string()).increment(1);
201233

202234
this.inner.call(req).await
203235
})

0 commit comments

Comments
 (0)