Skip to content

Commit 271b621

Browse files
authored
feat: add metrics to perms middleware (#86)
* feat: add metrics to perms middleware * feat: attempts
1 parent 8493d96 commit 271b621

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
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.15.0"
88
edition = "2021"
99
rust-version = "1.85"
1010
authors = ["init4", "James Prestwich", "evalir"]
@@ -16,8 +16,8 @@ repository = "https://github.com/init4tech/bin-base"
1616
init4-from-env-derive = "0.1.0"
1717

1818
# Signet
19-
signet-constants = { version = "0.11.1" }
20-
signet-tx-cache = { version = "0.11.1", optional = true }
19+
signet-constants = { version = "0.12" }
20+
signet-tx-cache = { version = "0.12", optional = true }
2121

2222
# alloy
2323
alloy = { version = "1.0.35", optional = true, default-features = false, features = ["std", "signer-local", "consensus", "network"] }

src/perms/middleware.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,39 @@ 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 ATTEMPTS: &str = "init4.perms.attempts";
28+
const ATTEMPTS_DESCR: &str = "Counts the number of builder permissioning attempts";
29+
30+
const MISSING_HEADER: &str = "init4.perms.missing_header";
31+
const MISSING_HEADER_DESCR: &str =
32+
"Counts the number of requests missing the authentication header";
33+
34+
const PERMISSION_DENIED: &str = "init4.perms.permission_denied";
35+
const PERMISSION_DENIED_DESCR: &str =
36+
"Counts the number of requests denied due to builder permissioning";
37+
38+
const SUCCESS: &str = "init4.perms.success";
39+
const SUCCESS_DESCR: &str = "Counts the number of auths allowed due to builder permissioning";
40+
41+
static DESCRIBE: LazyLock<()> = LazyLock::new(|| {
42+
describe_counter!(ATTEMPTS, ATTEMPTS_DESCR);
43+
describe_counter!(MISSING_HEADER, MISSING_HEADER_DESCR);
44+
describe_counter!(PERMISSION_DENIED, PERMISSION_DENIED_DESCR);
45+
describe_counter!(SUCCESS, SUCCESS_DESCR);
46+
});
1847

1948
/// Possible API error responses when a builder permissioning check fails.
2049
#[derive(Serialize)]
@@ -155,6 +184,8 @@ where
155184
fn call(&mut self, req: Request) -> Self::Future {
156185
let mut this = self.clone();
157186

187+
LazyLock::force(&DESCRIBE);
188+
158189
Box::pin(async move {
159190
let span = tracing::info_span!(
160191
"builder::permissioning",
@@ -167,37 +198,44 @@ where
167198
.calc()
168199
.current_point_within_slot()
169200
.expect("host chain has started"),
170-
permissioning_error = tracing::field::Empty,
201+
otel.status_code = tracing::field::Empty
171202
);
172203

173204
let guard = span.enter();
174205

175-
info!("builder permissioning check started");
206+
counter!(ATTEMPTS).increment(1);
176207

177208
// Check if the sub is in the header.
178209
let sub = match validate_header_sub(req.headers().get("x-jwt-claim-sub")) {
179210
Ok(sub) => sub,
180211
Err(err) => {
181-
span.record("permissioning_error", err.1.message);
212+
span.set_status(Status::Error {
213+
description: Cow::Owned(err.1.message.to_string()),
214+
});
182215
info!(api_err = %err.1.message, "permission denied");
216+
counter!("init4.perms.missing_header").increment(1);
183217
return Ok(err.into_response());
184218
}
185219
};
186220

187221
span.record("requesting_builder", sub);
188222

189223
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");
224+
span.set_status(Status::Error {
225+
description: Cow::Owned(err.to_string()),
226+
});
192227

193228
let hint = builder_permissioning_hint(&err);
194229

230+
counter!("init4.perms.permission_denied", "builder" => sub.to_string())
231+
.increment(1);
232+
195233
return Ok(ApiError::permission_denied(hint).into_response());
196234
}
197235

198-
info!("builder permissioned successfully");
199-
200236
drop(guard);
237+
info!("builder permissioned successfully");
238+
counter!(SUCCESS, "builder" => sub.to_string()).increment(1);
201239

202240
this.inner.call(req).await
203241
})

0 commit comments

Comments
 (0)