-
Notifications
You must be signed in to change notification settings - Fork 35
Open
Description
Hello.
I've checked examples but could find a way to instrument the axum app to include additional metrics.
Here is the code:
main.rs
Instrument handler with #[autometrics] macro work great - I get the defaults
use autometrics::{autometrics, prometheus_exporter};
use axum::{routing::get, Json, Router};
use serde::Serialize;
use serde_json::{json, Value};
mod images;
use images::get_images;
const DEFAULT_PORT: &str = "8000";
const DEFAULT_HOST: &str = "0.0.0.0";
#[derive(Serialize)]
#[serde(rename_all(serialize = "lowercase"))]
enum Status {
OK,
ERROR,
}
#[derive(Serialize)]
struct AppResponse<'a> {
status: Status,
#[serde(skip_serializing_if = "Option::is_none")]
message: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
result: Option<Value>,
}
impl<'a> AppResponse<'a> {
fn ok() -> Self {
Self {
status: Status::OK,
message: None,
result: None,
}
}
fn error() -> Self {
Self {
status: Status::ERROR,
message: None,
result: None,
}
}
fn with_message(self, message: &'a str) -> Self {
Self {
status: self.status,
message: Some(message),
result: self.result,
}
}
fn with_result(self, result: Option<Value>) -> Self {
Self {
status: self.status,
message: self.message,
result,
}
}
}
#[tokio::main]
async fn main() -> Result<(), axum::BoxError> {
let app = Router::new()
.route("/api/images", get(images))
.route(
"/metrics",
get(|| async { prometheus_exporter::encode_http_response() }),
);
let port = std::env::var("PORT").unwrap_or(DEFAULT_PORT.to_string());
let host = std::env::var("PORT").unwrap_or(DEFAULT_HOST.to_string());
let listener =
tokio::net::TcpListener::bind(format!("{}:{}", host, port)).await?;
axum::serve(listener, app).await?;
Ok(())
}
async fn health() -> Json<AppResponse<'static>> {
Json(AppResponse::ok().with_message("up"))
}
#[autometrics]
async fn images() -> Json<AppResponse<'static>> {
get_images().await;
Json(AppResponse::ok().with_message("saved"))
}
images.rs
I'm trying to add additional metrics to measure some parts of the handler
use std::time::{Instant, SystemTime};
use tokio::time::{sleep, Duration};
use uuid::Uuid;
#[allow(dead_code)]
#[derive(Debug)]
struct Image {
uuid: Uuid,
modified: SystemTime,
}
impl Image {
fn new() -> Self {
Image {
uuid: Uuid::new_v4(),
modified: SystemTime::now(),
}
}
}
async fn download() {
sleep(Duration::from_millis(5)).await;
}
async fn save(_image: Image) {
sleep(Duration::from_millis(2)).await;
}
pub async fn get_images() {
let start = Instant::now();
let latency = start.elapsed().as_secs_f64();
let labels = [("operation", "s3".to_string())];
download().await;
metrics::counter!("http_requests_total", &labels).increment(1);
metrics::histogram!(
"myapp_request_duration_seconds",
&labels
)
.record(latency);
let image = Image::new();
save(image).await;
}
But this does nothing.
Is there a way to include new metrics to the storage? Thank you.
Metadata
Metadata
Assignees
Labels
No labels