bug: fix Tokenserver metrics (#1218)

Closes #1214
This commit is contained in:
Ethan Donowitz 2022-03-16 10:32:33 -04:00 committed by GitHub
parent 0e9b0f6e6c
commit d2dc0063ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 21 deletions

View File

@ -23,9 +23,9 @@ pub struct MetricTimer {
#[derive(Debug, Clone)]
pub struct Metrics {
client: Option<StatsdClient>,
tags: Option<Tags>,
timer: Option<MetricTimer>,
pub client: Option<StatsdClient>,
pub tags: Option<Tags>,
pub timer: Option<MetricTimer>,
}
impl Drop for Metrics {
@ -63,21 +63,27 @@ impl FromRequest for Metrics {
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let exts = req.extensions();
let def_tags = Tags::from(req.head());
let tags = exts.get::<Tags>().unwrap_or(&def_tags);
future::ok(metrics_from_request(
req,
req.app_data::<Data<ServerState>>()
.map(|state| state.metrics.clone()),
))
}
}
future::ok(Metrics {
client: match req.app_data::<Data<ServerState>>() {
Some(v) => Some(*v.metrics.clone()),
None => {
warn!("⚠️ metric error: No App State");
None
}
},
tags: Some(tags.clone()),
timer: None,
})
pub fn metrics_from_request(req: &HttpRequest, client: Option<Box<StatsdClient>>) -> Metrics {
let exts = req.extensions();
let def_tags = Tags::from(req.head());
let tags = exts.get::<Tags>().unwrap_or(&def_tags);
if client.is_none() {
warn!("⚠️ metric error: No App State");
}
Metrics {
client: client.as_deref().cloned(),
tags: Some(tags.clone()),
timer: None,
}
}

View File

@ -12,7 +12,7 @@ use actix_web::{
Error, FromRequest, HttpRequest,
};
use actix_web_httpauth::extractors::bearer::BearerAuth;
use futures::future::LocalBoxFuture;
use futures::future::{self, LocalBoxFuture, Ready};
use hmac::{Hmac, Mac, NewMac};
use lazy_static::lazy_static;
use regex::Regex;
@ -22,8 +22,8 @@ use sha2::Sha256;
use super::db::{models::Db, params, pool::DbPool, results};
use super::error::{ErrorLocation, TokenserverError};
use super::support::TokenData;
use super::{LogItemsMutator, NodeType, ServerState};
use crate::server::metrics::Metrics;
use super::{LogItemsMutator, NodeType, ServerState, TokenserverMetrics};
use crate::server::metrics;
use crate::settings::Secrets;
lazy_static! {
@ -329,7 +329,7 @@ impl FromRequest for TokenData {
let state = get_server_state(&req)?.as_ref().as_ref().unwrap();
let oauth_verifier = state.oauth_verifier.clone();
let mut metrics = Metrics::extract(&req).await?;
let TokenserverMetrics(mut metrics) = TokenserverMetrics::extract(&req).await?;
metrics.start_timer("tokenserver.oauth_token_verification", None);
web::block(move || oauth_verifier.verify_token(auth.token()))
@ -419,6 +419,26 @@ impl FromRequest for KeyId {
}
}
impl FromRequest for TokenserverMetrics {
type Config = ();
type Error = Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
let state = match get_server_state(req) {
// XXX: Tokenserver state will no longer be an Option once the Tokenserver
// code is rolled out, so we will eventually be able to remove this unwrap().
Ok(state) => state.as_ref().as_ref().unwrap(),
Err(e) => return future::err(e),
};
future::ok(TokenserverMetrics(metrics::metrics_from_request(
req,
Some(state.metrics.clone()),
)))
}
}
fn get_server_state(req: &HttpRequest) -> Result<&Data<Option<ServerState>>, Error> {
req.app_data::<Data<Option<ServerState>>>().ok_or_else(|| {
error!("⚠️ Could not load the app state");

View File

@ -85,6 +85,8 @@ impl ServerState {
}
}
pub struct TokenserverMetrics(Metrics);
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum NodeType {
#[serde(rename = "mysql")]