Skip to content
This repository has been archived by the owner on Jul 26, 2024. It is now read-only.

Feat/21 extra #23

Merged
merged 7 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl Drop for Metrics {
impl From<&HttpRequest> for Metrics {
fn from(req: &HttpRequest) -> Self {
let exts = req.extensions();
let def_tags = Tags::from_request_head(req.head());
let def_tags = Tags::from(req.head());
let tags = exts.get::<Tags>().unwrap_or(&def_tags);
Metrics {
client: match req.app_data::<Data<ServerState>>() {
Expand Down Expand Up @@ -109,7 +109,7 @@ impl Metrics {
pub fn start_timer(&mut self, label: &str, tags: Option<Tags>) {
let mut mtags = self.tags.clone().unwrap_or_default();
if let Some(t) = tags {
mtags.extend(t.tags)
mtags.extend(t)
}

trace!("⌚ Starting timer... {:?}", &label; &mtags);
Expand All @@ -130,7 +130,7 @@ impl Metrics {
let mut tagged = client.incr_with_tags(label);
let mut mtags = self.tags.clone().unwrap_or_default();
if let Some(tags) = tags {
mtags.extend(tags.tags);
mtags.extend(tags);
}
for key in mtags.tags.keys().clone() {
if let Some(val) = mtags.tags.get(key) {
Expand Down Expand Up @@ -158,7 +158,7 @@ impl Metrics {
let mut tagged = client.count_with_tags(label, count);
let mut mtags = self.tags.clone().unwrap_or_default();
if let Some(tags) = tags {
mtags.extend(tags.tags);
mtags.extend(tags);
}
for key in mtags.tags.keys().clone() {
if let Some(val) = mtags.tags.get(key) {
Expand Down Expand Up @@ -232,7 +232,7 @@ mod tests {
),
);

let tags = Tags::from_request_head(&rh);
let tags = Tags::from(&rh);

let mut result = HashMap::<String, String>::new();
result.insert("ua.os.ver".to_owned(), "NT 10.0".to_owned());
Expand All @@ -258,7 +258,7 @@ mod tests {
header::HeaderValue::from_static("Mozilla/5.0 (curl) Gecko/20100101 curl"),
);

let tags = Tags::from_request_head(&rh);
let tags = Tags::from(&rh);
assert!(!tags.tags.contains_key("ua.os.ver"));
println!("{:?}", tags);
}
Expand Down
60 changes: 46 additions & 14 deletions src/tags.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use core::cell::RefMut;
use std::collections::{BTreeMap, HashMap};

use actix_http::Extensions;
use actix_web::{
dev::{Payload, RequestHead},
http::header::USER_AGENT,
Expand Down Expand Up @@ -90,17 +92,8 @@ fn insert_if_not_empty(label: &str, val: &str, tags: &mut HashMap<String, String
}
}

// Tags are extra data to be recorded in metric and logging calls.
// If additional tags are required or desired, you will need to add them to the
// mutable extensions, e.g.
// ```
// let mut tags = request.extensions_mut().get::<Tags>();
// tags.insert("SomeLabel".to_owned(), "whatever".to_owned());
// ```
// how you get the request (or the response, and it's set of `extensions`) to whatever
// function requires it, is left as an exercise for the reader.
impl Tags {
pub fn from_request_head(req_head: &RequestHead) -> Tags {
impl From<&RequestHead> for Tags {
fn from(req_head: &RequestHead) -> Self {
// Return an Option<> type because the later consumers (HandlerErrors) presume that
// tags are optional and wrapped by an Option<> type.
let mut tags = HashMap::new();
Expand All @@ -123,7 +116,26 @@ impl Tags {
extra.insert("uri.path".to_owned(), req_head.uri.to_string());
Tags { tags, extra }
}
}

impl From<HttpRequest> for Tags {
fn from(request: HttpRequest) -> Self {
match request.extensions().get::<Self>() {
Some(v) => v.clone(),
None => Tags::from(request.head()),
}
}
}

/// Tags are extra data to be recorded in metric and logging calls.
/// If additional tags are required or desired, you will need to add them to the
/// mutable extensions, e.g.
/// ```compile_fail
jrconlin marked this conversation as resolved.
Show resolved Hide resolved
/// let mut tags = Tags::default();
/// tags.add_tag("SomeLabel", "whatever");
/// tags.commit(&mut request.extensions_mut());
/// ```
impl Tags {
pub fn with_tags(tags: HashMap<String, String>) -> Tags {
if tags.is_empty() {
return Tags::default();
Expand All @@ -134,13 +146,26 @@ impl Tags {
}
}

pub fn add_extra(&mut self, key: &str, value: &str) {
if !value.is_empty() {
self.extra.insert(key.to_owned(), value.to_owned());
}
}

pub fn add_tag(&mut self, key: &str, value: &str) {
if !value.is_empty() {
self.tags.insert(key.to_owned(), value.to_owned());
}
}

pub fn get(&self, label: &str) -> String {
let none = "None".to_owned();
self.tags.get(label).map(String::from).unwrap_or(none)
}

pub fn extend(&mut self, tags: HashMap<String, String>) {
self.tags.extend(tags);
pub fn extend(&mut self, tags: Self) {
self.tags.extend(tags.tags);
self.extra.extend(tags.extra);
}

pub fn tag_tree(self) -> BTreeMap<String, String> {
Expand All @@ -160,6 +185,13 @@ impl Tags {
}
result
}

pub fn commit(self, exts: &mut RefMut<'_, Extensions>) {
match exts.get_mut::<Tags>() {
Some(t) => t.extend(self),
None => exts.insert(self),
}
}
}

impl FromRequest for Tags {
Expand All @@ -172,7 +204,7 @@ impl FromRequest for Tags {
let exts = req.extensions();
match exts.get::<Tags>() {
Some(t) => t.clone(),
None => Tags::from_request_head(req.head()),
None => Tags::from(req.head()),
}
};

Expand Down
14 changes: 13 additions & 1 deletion src/web/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! API Handlers
use std::collections::HashMap;

use actix_web::{web, Error, HttpResponse};
use actix_web::{web, Error, HttpRequest, HttpResponse};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use url::Url;

use super::user_agent;
use crate::tags::Tags;
use crate::{error::HandlerError, server::ServerState, web::extractors::TilesRequest};

#[derive(Debug, Deserialize, Serialize)]
Expand All @@ -27,6 +28,7 @@ struct AdmTile {
pub async fn get_tiles(
treq: TilesRequest,
state: web::Data<ServerState>,
request: HttpRequest,
) -> Result<HttpResponse, HandlerError> {
trace!("get_tiles");

Expand Down Expand Up @@ -55,6 +57,16 @@ pub async fn get_tiles(
.map_err(|e| HandlerError::internal(&e.to_string()))?;
let adm_url = adm_url.as_str();

{
// for demonstration purposes
let mut tags = Tags::default();
tags.add_extra("ip", fake_ip.as_str());
tags.add_extra("ua", &stripped_ua);
tags.add_extra("sub2", &treq.placement);
// Add/modify the existing request tags.
tags.commit(&mut request.extensions_mut());
}

trace!("get_tiles GET {}", adm_url);
let mut response: AdmTileResponse = state
.reqwest_client
Expand Down
2 changes: 1 addition & 1 deletion src/web/middleware/sentry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ where
}
jrconlin marked this conversation as resolved.
Show resolved Hide resolved

fn call(&mut self, sreq: ServiceRequest) -> Self::Future {
let mut tags = Tags::from_request_head(sreq.head());
let mut tags = Tags::from(sreq.head());
sreq.extensions_mut().insert(tags.clone());

Box::pin(self.service.call(sreq).and_then(move |mut sresp| {
Expand Down