mirror of https://github.com/zino-rs/zino
Add http request metrics
This commit is contained in:
parent
21b323d5a1
commit
5b676373a0
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue