Add http request metrics

This commit is contained in:
photino 2023-01-13 22:00:01 +08:00
parent 21b323d5a1
commit 5b676373a0
6 changed files with 35 additions and 11 deletions

View File

@ -16,7 +16,6 @@ port = 6082
[database]
type = "postgres"
schema = "public"
namespace = "dc"
[[postgres]]
@ -28,6 +27,8 @@ password = "QAx01wnh1i5ER713zfHmZi6dIUYn/Iq9ag+iUGtvKzEFJFYW"
[tracing]
filter = "info,sqlx=trace,tower_http=trace,zino=trace,zino_core=trace"
display-filename = true
display-line-number = true
[metrics]
exporter = "prometheus"

View File

@ -16,7 +16,6 @@ port = 6082
[database]
type = "postgres"
schema = "public"
namespace = "dc"
[[postgres]]
@ -27,7 +26,7 @@ username = "postgres"
password = "G76hTg8T5Aa+SZQFc+0QnsRLo1UOjqpkp/jUQ+lySc8QCt4B"
[tracing]
filter = "info,sqlx=warn,tower_http=warn"
filter = "info,sqlx=warn"
[metrics]
exporter = "prometheus"

View File

@ -69,9 +69,18 @@ pub trait RequestContext {
header.split(':').nth(3).map(|s| s.to_string())
})
});
let mut ctx = Context::new(request_id);
ctx.set_trace_id(trace_id);
ctx.set_session_id(session_id);
// Emit metrics.
metrics::increment_gauge!("zino_http_requests_pending", 1.0);
metrics::increment_counter!(
"zino_http_requests_total",
"method" => self.request_method().to_string(),
);
ctx
}

View File

@ -336,10 +336,11 @@ impl From<Validation> for Response<http::StatusCode> {
impl From<Response<http::StatusCode>> for http::Response<Full<Bytes>> {
fn from(mut response: Response<http::StatusCode>) -> Self {
let status_code = response.status_code;
let mut res = match response.content_type {
Some(ref content_type) => match serde_json::to_vec(&response.data) {
Ok(bytes) => http::Response::builder()
.status(response.status_code)
.status(status_code)
.header(header::CONTENT_TYPE, content_type.as_ref())
.body(Full::from(bytes))
.unwrap_or_default(),
@ -357,7 +358,7 @@ impl From<Response<http::StatusCode>> for http::Response<Full<Bytes>> {
"application/problem+json"
};
http::Response::builder()
.status(response.status_code)
.status(status_code)
.header(header::CONTENT_TYPE, content_type)
.body(Full::from(bytes))
.unwrap_or_default()
@ -377,7 +378,8 @@ impl From<Response<http::StatusCode>> for http::Response<Full<Bytes>> {
res.headers_mut().insert("traceparent", header_value);
}
response.record_server_timing("total", response.start_time.elapsed(), None);
let duration = response.start_time.elapsed();
response.record_server_timing("total", duration, None);
if let Ok(header_value) = HeaderValue::try_from(response.server_timing.value().as_str()) {
res.headers_mut().insert("server-timing", header_value);
}
@ -388,6 +390,17 @@ impl From<Response<http::StatusCode>> for http::Response<Full<Bytes>> {
res.headers_mut().insert("x-request-id", header_value);
}
}
// Emit metrics.
let labels = [("status", status_code.to_string())];
metrics::decrement_gauge!("zino_http_requests_pending", 1.0);
metrics::increment_counter!("zino_http_responses_total", &labels);
metrics::histogram!(
"zino_http_requests_duration_seconds",
duration.as_secs_f64(),
&labels,
);
res
}
}

View File

@ -78,7 +78,7 @@ pub fn schema_macro(item: TokenStream) -> TokenStream {
} else if INTEGER_TYPES.contains(&type_name.as_str()) {
default_value = default_value.or_else(|| Some("0".to_string()));
}
let quote_value = match default_value {
let value_quote = match default_value {
Some(value) => {
if value.contains("::") {
if let Some((type_name, type_fn)) = value.split_once("::") {
@ -94,12 +94,12 @@ pub fn schema_macro(item: TokenStream) -> TokenStream {
}
None => quote! { None },
};
let quote_index = match index_type {
let index_quote = match index_type {
Some(index) => quote! { Some(#index) },
None => quote! { None },
};
let column = quote! {
zino_core::database::Column::new(#name, #type_name, #quote_value, #not_null, #quote_index)
zino_core::database::Column::new(#name, #type_name, #value_quote, #not_null, #index_quote)
};
columns.push(column);
}

View File

@ -82,6 +82,8 @@ impl RequestContext for AxumExtractor<Request<Body>> {
}
fn matched_path(&self) -> &str {
// The `MatchedPath` extension is always accessible on handlers added via `Router::route`,
// but it is not accessible in middleware on nested routes.
if let Some(path) = self.extensions().get::<MatchedPath>() {
path.as_str()
} else {
@ -90,11 +92,11 @@ impl RequestContext for AxumExtractor<Request<Body>> {
}
fn original_uri(&self) -> &Uri {
// The `OriginalUri` extension will always be present if using
// `Router` unless another extractor or middleware has removed it.
if let Some(original_uri) = self.extensions().get::<OriginalUri>() {
&original_uri.0
} else {
// The `OriginalUri` extension will always be present if using
// `Router` unless another extractor or middleware has removed it
self.uri()
}
}