mirror of https://github.com/linkerd/linkerd2.git
Move `metrics::Serve` into its own module (#877)
With this change, metrics/mod.rs now contains only metrics types.
This commit is contained in:
parent
84d131b6b0
commit
f73fdc1eae
|
@ -30,18 +30,7 @@ use std::default::Default;
|
|||
use std::{fmt, time};
|
||||
use std::hash::Hash;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::io::Write;
|
||||
|
||||
use deflate::CompressionOptions;
|
||||
use deflate::write::GzEncoder;
|
||||
use futures::future::{self, FutureResult};
|
||||
use hyper::{self, Body, StatusCode};
|
||||
use hyper::header::{AcceptEncoding, ContentEncoding, ContentType, Encoding, QualityItem};
|
||||
use hyper::server::{
|
||||
Response as HyperResponse,
|
||||
Request as HyperRequest,
|
||||
Service as HyperService,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use ctx;
|
||||
|
@ -52,6 +41,7 @@ mod histogram;
|
|||
mod labels;
|
||||
mod latency;
|
||||
mod record;
|
||||
mod serve;
|
||||
|
||||
use self::counter::Counter;
|
||||
use self::gauge::Gauge;
|
||||
|
@ -64,6 +54,7 @@ use self::labels::{
|
|||
};
|
||||
pub use self::labels::DstLabels;
|
||||
pub use self::record::Record;
|
||||
pub use self::serve::Serve;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Metrics {
|
||||
|
@ -96,12 +87,6 @@ struct Metric<M, L: Hash + Eq> {
|
|||
values: IndexMap<L, M>
|
||||
}
|
||||
|
||||
/// Serve Prometheues metrics.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Serve {
|
||||
metrics: Arc<Mutex<Metrics>>,
|
||||
}
|
||||
|
||||
/// Construct the Prometheus metrics.
|
||||
///
|
||||
/// Returns the `Record` and `Serve` sides. The `Serve` side
|
||||
|
@ -393,65 +378,3 @@ impl<L, V> fmt::Display for Metric<Histogram<V>, L> where
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Serve =====
|
||||
|
||||
impl Serve {
|
||||
fn new(metrics: &Arc<Mutex<Metrics>>) -> Self {
|
||||
Serve {
|
||||
metrics: metrics.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_gzip(req: &HyperRequest) -> bool {
|
||||
if let Some(accept_encodings) = req
|
||||
.headers()
|
||||
.get::<AcceptEncoding>()
|
||||
{
|
||||
return accept_encodings
|
||||
.iter()
|
||||
.any(|&QualityItem { ref item, .. }| item == &Encoding::Gzip)
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
impl HyperService for Serve {
|
||||
type Request = HyperRequest;
|
||||
type Response = HyperResponse;
|
||||
type Error = hyper::Error;
|
||||
type Future = FutureResult<Self::Response, Self::Error>;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
if req.path() != "/metrics" {
|
||||
return future::ok(HyperResponse::new()
|
||||
.with_status(StatusCode::NotFound));
|
||||
}
|
||||
|
||||
let metrics = self.metrics.lock()
|
||||
.expect("metrics lock poisoned");
|
||||
|
||||
let resp = if is_gzip(&req) {
|
||||
trace!("gzipping metrics");
|
||||
let mut writer = GzEncoder::new(Vec::<u8>::new(), CompressionOptions::fast());
|
||||
write!(&mut writer, "{}", *metrics)
|
||||
.and_then(|_| writer.finish())
|
||||
.map(|body| {
|
||||
HyperResponse::new()
|
||||
.with_header(ContentEncoding(vec![Encoding::Gzip]))
|
||||
.with_header(ContentType::plaintext())
|
||||
.with_body(Body::from(body))
|
||||
})
|
||||
} else {
|
||||
let mut writer = Vec::<u8>::new();
|
||||
write!(&mut writer, "{}", *metrics)
|
||||
.map(|_| {
|
||||
HyperResponse::new()
|
||||
.with_header(ContentType::plaintext())
|
||||
.with_body(Body::from(writer))
|
||||
})
|
||||
};
|
||||
|
||||
future::result(resp.map_err(hyper::Error::Io))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
use deflate::CompressionOptions;
|
||||
use deflate::write::GzEncoder;
|
||||
use futures::future::{self, FutureResult};
|
||||
use hyper::{self, Body, StatusCode};
|
||||
use hyper::header::{AcceptEncoding, ContentEncoding, ContentType, Encoding, QualityItem};
|
||||
use hyper::server::{Request, Response, Service};
|
||||
use std::io::Write;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::Metrics;
|
||||
|
||||
/// Serve Prometheues metrics.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Serve {
|
||||
metrics: Arc<Mutex<Metrics>>,
|
||||
}
|
||||
|
||||
// ===== impl Serve =====
|
||||
|
||||
impl Serve {
|
||||
pub(super) fn new(metrics: &Arc<Mutex<Metrics>>) -> Self {
|
||||
Serve {
|
||||
metrics: metrics.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_gzip(req: &Request) -> bool {
|
||||
if let Some(accept_encodings) = req
|
||||
.headers()
|
||||
.get::<AcceptEncoding>()
|
||||
{
|
||||
return accept_encodings
|
||||
.iter()
|
||||
.any(|&QualityItem { ref item, .. }| item == &Encoding::Gzip)
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Service for Serve {
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = hyper::Error;
|
||||
type Future = FutureResult<Self::Response, Self::Error>;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
if req.path() != "/metrics" {
|
||||
return future::ok(Response::new()
|
||||
.with_status(StatusCode::NotFound));
|
||||
}
|
||||
|
||||
let metrics = self.metrics.lock()
|
||||
.expect("metrics lock poisoned");
|
||||
|
||||
let resp = if Self::is_gzip(&req) {
|
||||
trace!("gzipping metrics");
|
||||
let mut writer = GzEncoder::new(Vec::<u8>::new(), CompressionOptions::fast());
|
||||
write!(&mut writer, "{}", *metrics)
|
||||
.and_then(|_| writer.finish())
|
||||
.map(|body| {
|
||||
Response::new()
|
||||
.with_header(ContentEncoding(vec![Encoding::Gzip]))
|
||||
.with_header(ContentType::plaintext())
|
||||
.with_body(Body::from(body))
|
||||
})
|
||||
} else {
|
||||
let mut writer = Vec::<u8>::new();
|
||||
write!(&mut writer, "{}", *metrics)
|
||||
.map(|_| {
|
||||
Response::new()
|
||||
.with_header(ContentType::plaintext())
|
||||
.with_body(Body::from(writer))
|
||||
})
|
||||
};
|
||||
|
||||
future::result(resp.map_err(hyper::Error::Io))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue