6 releases
0.1.2 | Sep 29, 2022 |
---|---|
0.1.2-beta.10 | Oct 21, 2021 |
0.1.2-beta.8 | Aug 5, 2021 |
#1304 in HTTP server
9,053 downloads per month
Used in todors
38KB
332 lines
Prometheus instrumentation for actix-web.
This middleware is inspired by and forked from actix-web-prom.
By default three metrics are tracked (this assumes the namespace actix_web_prometheus
):
actix_web_prometheus_incoming_requests
(labels: endpoint, method, status): the total number of HTTP requests handled by the actix HttpServer.actix_web_prometheus_response_code
(labels: endpoint, method, statuscode, type): Response codes of all HTTP requests handled by the actix HttpServer.actix_web_prometheus_response_time
(labels: endpoint, method, status): Total the request duration of all HTTP requests handled by the actix HttpServer.
Usage
First add actix-web-prom
to your Cargo.toml
:
[dependencies]
actix-web-prometheus = "0.1.0-beta.8"
You then instantiate the prometheus middleware and pass it to .wrap()
:
use std::collections::HashMap;
use actix_web::{web, App, HttpResponse, HttpServer};
use actix_web_prometheus::{PrometheusMetrics, PrometheusMetricsBuilder};
fn health() -> HttpResponse {
HttpResponse::Ok().finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut labels = HashMap::new();
labels.insert("label1".to_string(), "value1".to_string());
let prometheus = PrometheusMetricsBuilder::new("api")
.endpoint("/metrics")
.const_labels(labels)
.build()
.unwrap();
HttpServer::new(move || {
App::new()
.wrap(prometheus.clone())
.service(web::resource("/health").to(health))
})
.bind("127.0.0.1:8080")?
.run()
.await?;
Ok(())
}
Using the above as an example, a few things are worth mentioning:
api
is the metrics namespace/metrics
will be auto exposed (GET requests only) with Content-Type headercontent-type: text/plain; version=0.0.4; charset=utf-8
Some(labels)
is used to add fixed labels to the metrics;None
can be passed instead if no additional labels are necessary. A call to the /metrics endpoint will expose your metrics:
$ curl http://localhost:8080/metrics
# HELP actix_web_prometheus_incoming_requests Incoming Requests
# TYPE actix_web_prometheus_incoming_requests counter
actix_web_prometheus_incoming_requests{endpoint="/metrics",method="GET",status="200"} 23
# HELP actix_web_prometheus_response_code Response Codes
# TYPE actix_web_prometheus_response_code counter
actix_web_prometheus_response_code{endpoint="/metrics",method="GET",statuscode="200",type="200"} 23
# HELP actix_web_prometheus_response_time Response Times
# TYPE actix_web_prometheus_response_time histogram
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.005"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.01"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.025"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.05"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.1"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.25"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="0.5"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="1"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="2.5"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="5"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="10"} 23
actix_web_prometheus_response_time_bucket{endpoint="/metrics",method="GET",status="200",le="+Inf"} 23
actix_web_prometheus_response_time_sum{endpoint="/metrics",method="GET",status="200"} 0.00410981
actix_web_prometheus_response_time_count{endpoint="/metrics",method="GET",status="200"} 23
Features
If you enable process
feature of this crate, default process metrics will also be collected.
Default process metrics
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.22
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1048576
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 78
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 17526784
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1628105774.92
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1893163008
Custom metrics
You instantiate PrometheusMetrics
and then use its .registry
to register your custom
metric (in this case, we use a IntCounterVec
).
Then you can pass this counter through .data()
to have it available within the resource
responder.
use actix_web::{web, App, HttpResponse, HttpServer};
use actix_web_prometheus::{PrometheusMetrics, PrometheusMetricsBuilder};
use prometheus::{opts, IntCounterVec};
fn health(counter: web::Data<IntCounterVec>) -> HttpResponse {
counter.with_label_values(&["endpoint", "method", "status"]).inc();
HttpResponse::Ok().finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let prometheus = PrometheusMetricsBuilder::new("api")
.endpoint("/metrics")
.build()
.unwrap();
let counter_opts = opts!("counter", "some random counter").namespace("api");
let counter = IntCounterVec::new(counter_opts, &["endpoint", "method", "status"]).unwrap();
prometheus
.registry
.register(Box::new(counter.clone()))
.unwrap();
HttpServer::new(move || {
App::new()
.wrap(prometheus.clone())
.app_data(web::Data::new(counter.clone()))
.service(web::resource("/health").to(health))
})
.bind("127.0.0.1:8080")?
.run()
.await?;
Ok(())
}
Dependencies
~16–30MB
~527K SLoC