metrics: Add labels to iocaine_garbage_served

Lifted out the label construction code into its dedicated function, so
it can be reused to add labels to `iocaine_garbage_served` too. The
required information is at hand at that point, so the cost of doing this
is minimal.

Changelog & Grafana dashboard adjusted accordingly.

Signed-off-by: Gergely Nagy <me@gergo.csillger.hu>
This commit is contained in:
Gergely Nagy 2025-03-04 09:21:19 +01:00
parent b7d5fade23
commit 406f8e0f80
No known key found for this signature in database
4 changed files with 46 additions and 20 deletions

View file

@ -6,7 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
## [Unreleased] ## [Unreleased]
No changes yet. ### Added
- The `iocaine_garbage_served` metric will have the same labels applied to it as `iocaine_requests_total`.
## [1.0.0] - 2025-03-01 ## [1.0.0] - 2025-03-01

View file

@ -355,7 +355,7 @@
"targets": [ "targets": [
{ {
"editorMode": "code", "editorMode": "code",
"expr": "iocaine_garbage_served", "expr": "sum(iocaine_garbage_served)",
"legendFormat": "__auto", "legendFormat": "__auto",
"range": true, "range": true,
"refId": "A", "refId": "A",
@ -613,6 +613,6 @@
"timezone": "browser", "timezone": "browser",
"title": "Iocaine", "title": "Iocaine",
"uid": "aec38snrfs4cgf", "uid": "aec38snrfs4cgf",
"version": 52, "version": 54,
"weekStart": "" "weekStart": ""
} }

View file

@ -119,7 +119,11 @@ async fn poison(
let garbage = AssembledStatisticalSequences::generate(&iocaine, host, &path)?; let garbage = AssembledStatisticalSequences::generate(&iocaine, host, &path)?;
if iocaine.config.metrics.enable { if iocaine.config.metrics.enable {
metrics::counter!("iocaine_garbage_served").increment(garbage.len() as u64); tenx_programmer::add_garbage_metrics(
&iocaine.config.metrics,
&headers,
garbage.len() as u64,
)?;
} }
Ok(Html(garbage)) Ok(Html(garbage))

View file

@ -16,38 +16,33 @@ use std::time::{SystemTime, UNIX_EPOCH};
use crate::{ use crate::{
app::{shutdown_signal, AppError, StatefulIocaine}, app::{shutdown_signal, AppError, StatefulIocaine},
config::MetricsLabel, config::{MetricsConfig, MetricsLabel},
}; };
pub async fn track_metrics( fn build_labels(
State(iocaine): State<StatefulIocaine>, config: &MetricsConfig,
req: Request, headers: &axum::http::HeaderMap,
next: Next, ) -> Result<Vec<(&'static str, String)>, AppError> {
) -> Result<Response<Body>, AppError> {
let headers = req.headers().clone();
let response = next.run(req).await;
let cfg = &iocaine.config.metrics;
let mut labels = Vec::new(); let mut labels = Vec::new();
if cfg.labels.contains(&MetricsLabel::Host) { if config.labels.contains(&MetricsLabel::Host) {
if let Some(host) = headers.get("host") { if let Some(host) = headers.get("host") {
let host = host.to_str()?.to_string(); let host = host.to_str()?.to_string();
labels.push(("host", host)); labels.push(("host", host));
} }
} }
if cfg.labels.contains(&MetricsLabel::UserAgent) if config.labels.contains(&MetricsLabel::UserAgent)
|| cfg.labels.contains(&MetricsLabel::UserAgentGroup) || config.labels.contains(&MetricsLabel::UserAgentGroup)
{ {
if let Some(ua) = headers.get("user-agent") { if let Some(ua) = headers.get("user-agent") {
let user_agent = ua.to_str()?.to_string(); let user_agent = ua.to_str()?.to_string();
if cfg.labels.contains(&MetricsLabel::UserAgent) { if config.labels.contains(&MetricsLabel::UserAgent) {
labels.push(("user-agent", user_agent.clone())); labels.push(("user-agent", user_agent.clone()));
} }
if cfg.labels.contains(&MetricsLabel::UserAgentGroup) { if config.labels.contains(&MetricsLabel::UserAgentGroup) {
if let Some(group) = cfg if let Some(group) = config
.agent_group .agent_group
.iter() .iter()
.find(|agent_group_config| agent_group_config.agent.is_match(&user_agent)) .find(|agent_group_config| agent_group_config.agent.is_match(&user_agent))
@ -58,6 +53,31 @@ pub async fn track_metrics(
} }
} }
Ok(labels)
}
pub fn add_garbage_metrics(
config: &MetricsConfig,
headers: &axum::http::HeaderMap,
garbage: u64,
) -> Result<(), AppError> {
let labels = build_labels(config, headers)?;
metrics::counter!("iocaine_garbage_served", &labels).increment(garbage);
Ok(())
}
pub async fn track_metrics(
State(iocaine): State<StatefulIocaine>,
req: Request,
next: Next,
) -> Result<Response<Body>, AppError> {
let headers = req.headers().clone();
let response = next.run(req).await;
let labels = build_labels(&iocaine.config.metrics, &headers)?;
metrics::counter!("iocaine_requests_total", &labels).increment(1); metrics::counter!("iocaine_requests_total", &labels).increment(1);
Ok(response) Ok(response)