Adopt rustfmt and clean up clippy warnings
Formats the whole backend to rustfmt defaults and fixes all 23 outstanding clippy warnings (collapsible ifs, clone-to-slice-ref, type-complexity, single-arm match, unnecessary is_none check), then wires cargo fmt --check and -D warnings into make lint so both stay enforced going forward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TeyhRfMYjMditek6geDRoQ
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2cc8ac8138
commit
c3108677ce
+297
-92
@@ -1,7 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::hash::{Hash, Hasher};
|
||||
@@ -11,10 +11,10 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::config::Settings;
|
||||
use crate::consts::{DEFAULT_PROFILE_NAME, SEEDED_METRIC_LABEL, SEEDED_METRIC_NAME};
|
||||
use crate::engine::data_value::MetricPrimitiveKind;
|
||||
use crate::engine::{DeclareMetricRequest, DeclareParamRequest, EngineHandle, EngineMessage};
|
||||
use crate::config::Settings;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -167,8 +167,11 @@ impl Profile {
|
||||
let mut label_params = Vec::new();
|
||||
let mut value_param = None;
|
||||
for matcher in &legacy {
|
||||
let param_name =
|
||||
self.resolve_or_create_legacy_param(&metric_name, &message_match_regex, matcher);
|
||||
let param_name = self.resolve_or_create_legacy_param(
|
||||
&metric_name,
|
||||
&message_match_regex,
|
||||
matcher,
|
||||
);
|
||||
match matcher.role {
|
||||
LegacyParamRole::Label => label_params.push(param_name),
|
||||
LegacyParamRole::Value => value_param = Some(param_name),
|
||||
@@ -187,14 +190,13 @@ impl Profile {
|
||||
message_match_regex: &str,
|
||||
matcher: &LegacyMetricParamRecord,
|
||||
) -> String {
|
||||
if let Some(existing) = self.params.iter().find(|p| p.name == matcher.param_name) {
|
||||
if existing.message_match_regex == message_match_regex
|
||||
&& existing.capture_group == matcher.capture_group
|
||||
&& existing.json_field_path == matcher.json_field_path
|
||||
&& existing.kind == matcher.kind
|
||||
{
|
||||
return existing.name.clone();
|
||||
}
|
||||
if let Some(existing) = self.params.iter().find(|p| p.name == matcher.param_name)
|
||||
&& existing.message_match_regex == message_match_regex
|
||||
&& existing.capture_group == matcher.capture_group
|
||||
&& existing.json_field_path == matcher.json_field_path
|
||||
&& existing.kind == matcher.kind
|
||||
{
|
||||
return existing.name.clone();
|
||||
}
|
||||
|
||||
let implicit_name = format!("{metric_name}.{}", matcher.param_name);
|
||||
@@ -213,8 +215,11 @@ impl Profile {
|
||||
}
|
||||
|
||||
fn migrate_duration_value_params(&mut self) -> bool {
|
||||
let value_param_names: std::collections::HashSet<&str> =
|
||||
self.metrics.iter().filter_map(|metric| metric.value_param.as_deref()).collect();
|
||||
let value_param_names: std::collections::HashSet<&str> = self
|
||||
.metrics
|
||||
.iter()
|
||||
.filter_map(|metric| metric.value_param.as_deref())
|
||||
.collect();
|
||||
let mut migrated = false;
|
||||
for param in &mut self.params {
|
||||
if !param.elapsed_since_last
|
||||
@@ -267,7 +272,11 @@ fn generate_id(seed: &str) -> String {
|
||||
impl Dashboard {
|
||||
pub fn new(name: String) -> Dashboard {
|
||||
let id = generate_id(&name);
|
||||
Dashboard { id, name, panels: Vec::new() }
|
||||
Dashboard {
|
||||
id,
|
||||
name,
|
||||
panels: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,8 +287,14 @@ impl MetricDeclarationRecord {
|
||||
message_match_regex: r"(?i)error".to_string(),
|
||||
label_params: Vec::new(),
|
||||
value_param: None,
|
||||
matched_labels: Some(BTreeMap::from([(SEEDED_METRIC_LABEL.to_string(), "error".to_string())])),
|
||||
unmatched_labels: Some(BTreeMap::from([(SEEDED_METRIC_LABEL.to_string(), "other".to_string())])),
|
||||
matched_labels: Some(BTreeMap::from([(
|
||||
SEEDED_METRIC_LABEL.to_string(),
|
||||
"error".to_string(),
|
||||
)])),
|
||||
unmatched_labels: Some(BTreeMap::from([(
|
||||
SEEDED_METRIC_LABEL.to_string(),
|
||||
"other".to_string(),
|
||||
)])),
|
||||
legacy_params: Vec::new(),
|
||||
}
|
||||
}
|
||||
@@ -336,11 +351,17 @@ impl Profile {
|
||||
let name = request.name.clone();
|
||||
if engine
|
||||
.tx
|
||||
.send(EngineMessage::DeclareParam { request, respond_to })
|
||||
.send(EngineMessage::DeclareParam {
|
||||
request,
|
||||
respond_to,
|
||||
})
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
eprintln!("warning: engine unavailable while loading profile '{}'", self.name);
|
||||
eprintln!(
|
||||
"warning: engine unavailable while loading profile '{}'",
|
||||
self.name
|
||||
);
|
||||
return;
|
||||
}
|
||||
match response.await {
|
||||
@@ -362,11 +383,17 @@ impl Profile {
|
||||
let name = request.name.clone();
|
||||
if engine
|
||||
.tx
|
||||
.send(EngineMessage::DeclareMetric { request, respond_to })
|
||||
.send(EngineMessage::DeclareMetric {
|
||||
request,
|
||||
respond_to,
|
||||
})
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
eprintln!("warning: engine unavailable while loading profile '{}'", self.name);
|
||||
eprintln!(
|
||||
"warning: engine unavailable while loading profile '{}'",
|
||||
self.name
|
||||
);
|
||||
return;
|
||||
}
|
||||
match response.await {
|
||||
@@ -444,7 +471,11 @@ impl Settings {
|
||||
self.profiles.iter().find(|p| p.name == name)
|
||||
}
|
||||
|
||||
pub fn create_profile(&mut self, settings_path: &Path, name: String) -> Result<(), ProfileError> {
|
||||
pub fn create_profile(
|
||||
&mut self,
|
||||
settings_path: &Path,
|
||||
name: String,
|
||||
) -> Result<(), ProfileError> {
|
||||
if self.profile(&name).is_some() {
|
||||
return Err(ProfileError::DuplicateName);
|
||||
}
|
||||
@@ -463,7 +494,11 @@ impl Settings {
|
||||
if name == DEFAULT_PROFILE_NAME {
|
||||
return Err(ProfileError::CannotDeleteDefault);
|
||||
}
|
||||
let index = self.profiles.iter().position(|p| p.name == name).ok_or(ProfileError::NotFound)?;
|
||||
let index = self
|
||||
.profiles
|
||||
.iter()
|
||||
.position(|p| p.name == name)
|
||||
.ok_or(ProfileError::NotFound)?;
|
||||
self.profiles.remove(index);
|
||||
if self.active_profile.as_deref() == Some(name) {
|
||||
self.active_profile = None;
|
||||
@@ -475,7 +510,9 @@ impl Settings {
|
||||
pub fn ensure_default_profile(&mut self, settings_path: &Path) -> Result<(), ProfileError> {
|
||||
if self.profile(DEFAULT_PROFILE_NAME).is_none() {
|
||||
let mut profile = Profile::new(DEFAULT_PROFILE_NAME.to_string());
|
||||
profile.metrics.push(MetricDeclarationRecord::seeded_error_split());
|
||||
profile
|
||||
.metrics
|
||||
.push(MetricDeclarationRecord::seeded_error_split());
|
||||
profile.dashboards.push(Dashboard::seeded_default());
|
||||
self.profiles.push(profile);
|
||||
}
|
||||
@@ -491,10 +528,10 @@ impl Settings {
|
||||
settings_path: &Path,
|
||||
name: Option<String>,
|
||||
) -> Result<(), ProfileError> {
|
||||
if let Some(name) = &name {
|
||||
if self.profile(name).is_none() {
|
||||
return Err(ProfileError::NotFound);
|
||||
}
|
||||
if let Some(name) = &name
|
||||
&& self.profile(name).is_none()
|
||||
{
|
||||
return Err(ProfileError::NotFound);
|
||||
}
|
||||
self.active_profile = name;
|
||||
self.save(settings_path)?;
|
||||
@@ -678,10 +715,10 @@ impl Settings {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::engine::data_value::MetricPrimitiveKind;
|
||||
use crate::api::dto::LogsParams;
|
||||
use crate::engine::{EngineMessage, EngineQuery, EngineResponse, IngestedLine};
|
||||
use crate::engine::data_value::MetricPrimitiveKind;
|
||||
use crate::engine::timestamp::Timestamp;
|
||||
use crate::engine::{EngineMessage, EngineQuery, EngineResponse, IngestedLine};
|
||||
|
||||
fn param_request(name: &str, pattern: &str, capture_group: &str) -> DeclareParamRequest {
|
||||
DeclareParamRequest {
|
||||
@@ -719,8 +756,12 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings.create_profile(&settings_path, "worker".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "worker".to_string())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(settings.profiles.len(), 2);
|
||||
assert!(settings.profile("web").is_some());
|
||||
@@ -750,13 +791,27 @@ mod tests {
|
||||
settings.ensure_default_profile(&settings_path).unwrap();
|
||||
|
||||
assert!(settings.profile(DEFAULT_PROFILE_NAME).is_some());
|
||||
assert_eq!(settings.active_profile, Some(DEFAULT_PROFILE_NAME.to_string()));
|
||||
assert_eq!(
|
||||
settings.active_profile,
|
||||
Some(DEFAULT_PROFILE_NAME.to_string())
|
||||
);
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings.set_active_profile(&settings_path, Some("web".to_string())).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("web".to_string()))
|
||||
.unwrap();
|
||||
settings.ensure_default_profile(&settings_path).unwrap();
|
||||
|
||||
assert_eq!(settings.profiles.iter().filter(|p| p.name == DEFAULT_PROFILE_NAME).count(), 1);
|
||||
assert_eq!(
|
||||
settings
|
||||
.profiles
|
||||
.iter()
|
||||
.filter(|p| p.name == DEFAULT_PROFILE_NAME)
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
assert_eq!(settings.active_profile, Some("web".to_string()));
|
||||
}
|
||||
|
||||
@@ -773,20 +828,33 @@ mod tests {
|
||||
assert_eq!(default_profile.metrics[0].name, SEEDED_METRIC_NAME);
|
||||
assert_eq!(
|
||||
default_profile.metrics[0].matched_labels,
|
||||
Some(BTreeMap::from([(SEEDED_METRIC_LABEL.to_string(), "error".to_string())]))
|
||||
Some(BTreeMap::from([(
|
||||
SEEDED_METRIC_LABEL.to_string(),
|
||||
"error".to_string()
|
||||
)]))
|
||||
);
|
||||
assert_eq!(
|
||||
default_profile.metrics[0].unmatched_labels,
|
||||
Some(BTreeMap::from([(SEEDED_METRIC_LABEL.to_string(), "other".to_string())]))
|
||||
Some(BTreeMap::from([(
|
||||
SEEDED_METRIC_LABEL.to_string(),
|
||||
"other".to_string()
|
||||
)]))
|
||||
);
|
||||
assert_eq!(default_profile.dashboards.len(), 1);
|
||||
let dashboard = &default_profile.dashboards[0];
|
||||
assert_eq!(dashboard.panels.len(), 2);
|
||||
assert!(dashboard
|
||||
.panels
|
||||
.iter()
|
||||
.any(|p| p.chart_type == ChartType::Line && p.promql.contains(SEEDED_METRIC_NAME)));
|
||||
assert!(dashboard.panels.iter().any(|p| p.chart_type == ChartType::Pie && p.promql == SEEDED_METRIC_NAME));
|
||||
assert!(
|
||||
dashboard
|
||||
.panels
|
||||
.iter()
|
||||
.any(|p| p.chart_type == ChartType::Line && p.promql.contains(SEEDED_METRIC_NAME))
|
||||
);
|
||||
assert!(
|
||||
dashboard
|
||||
.panels
|
||||
.iter()
|
||||
.any(|p| p.chart_type == ChartType::Pie && p.promql == SEEDED_METRIC_NAME)
|
||||
);
|
||||
|
||||
let mut reloaded = Settings::load(&settings_path);
|
||||
reloaded.ensure_default_profile(&settings_path).unwrap();
|
||||
@@ -797,8 +865,8 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn seeded_metric_renders_real_error_vs_other_data() {
|
||||
use crate::engine::{self, EngineMessage, EngineQuery, EngineResponse, IngestedLine};
|
||||
use crate::engine::timestamp::Timestamp;
|
||||
use crate::engine::{self, EngineMessage, EngineQuery, EngineResponse, IngestedLine};
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
@@ -810,7 +878,11 @@ mod tests {
|
||||
let engine_tx = engine::spawn(settings_handle, 128);
|
||||
default_profile.load_into_engine(&engine_tx).await;
|
||||
|
||||
for (sequence, text) in [(0u64, "all good"), (1, "an ERROR happened"), (2, "fine again")] {
|
||||
for (sequence, text) in [
|
||||
(0u64, "all good"),
|
||||
(1, "an ERROR happened"),
|
||||
(2, "fine again"),
|
||||
] {
|
||||
engine_tx
|
||||
.tx
|
||||
.send(EngineMessage::Ingest(IngestedLine {
|
||||
@@ -825,18 +897,38 @@ mod tests {
|
||||
|
||||
let response = ask(
|
||||
&engine_tx,
|
||||
EngineQuery::Promql { query: SEEDED_METRIC_NAME.to_string(), start_ms: None, end_ms: None },
|
||||
EngineQuery::Promql {
|
||||
query: SEEDED_METRIC_NAME.to_string(),
|
||||
start_ms: None,
|
||||
end_ms: None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let EngineResponse::Promql(Ok(mut series)) = response else {
|
||||
panic!("expected a successful Promql response");
|
||||
};
|
||||
series.sort_by(|a, b| a.labels.get(SEEDED_METRIC_LABEL).cmp(&b.labels.get(SEEDED_METRIC_LABEL)));
|
||||
series.sort_by(|a, b| {
|
||||
a.labels
|
||||
.get(SEEDED_METRIC_LABEL)
|
||||
.cmp(&b.labels.get(SEEDED_METRIC_LABEL))
|
||||
});
|
||||
|
||||
assert_eq!(series.len(), 2);
|
||||
assert_eq!(series[0].labels.get(SEEDED_METRIC_LABEL).map(String::as_str), Some("error"));
|
||||
assert_eq!(
|
||||
series[0]
|
||||
.labels
|
||||
.get(SEEDED_METRIC_LABEL)
|
||||
.map(String::as_str),
|
||||
Some("error")
|
||||
);
|
||||
assert_eq!(series[0].points.len(), 1);
|
||||
assert_eq!(series[1].labels.get(SEEDED_METRIC_LABEL).map(String::as_str), Some("other"));
|
||||
assert_eq!(
|
||||
series[1]
|
||||
.labels
|
||||
.get(SEEDED_METRIC_LABEL)
|
||||
.map(String::as_str),
|
||||
Some("other")
|
||||
);
|
||||
assert_eq!(series[1].points.len(), 2);
|
||||
}
|
||||
|
||||
@@ -859,19 +951,31 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
let param_req = param_request("level", r"level=(?P<level>\w+)", "level");
|
||||
settings.record_param_declaration(&settings_path, "web", ¶m_req).unwrap();
|
||||
settings.create_dashboard(&settings_path, "web", "Overview".to_string()).unwrap();
|
||||
settings.set_active_profile(&settings_path, Some("web".to_string())).unwrap();
|
||||
settings
|
||||
.record_param_declaration(&settings_path, "web", ¶m_req)
|
||||
.unwrap();
|
||||
settings
|
||||
.create_dashboard(&settings_path, "web", "Overview".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("web".to_string()))
|
||||
.unwrap();
|
||||
|
||||
settings.create_profile(&settings_path, "web-copy".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web-copy".to_string())
|
||||
.unwrap();
|
||||
let copy = settings.profile("web-copy").unwrap().clone();
|
||||
assert_eq!(copy.params, settings.profile("web").unwrap().params);
|
||||
assert_eq!(copy.dashboards, settings.profile("web").unwrap().dashboards);
|
||||
|
||||
settings.set_active_profile(&settings_path, None).unwrap();
|
||||
settings.create_profile(&settings_path, "blank".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "blank".to_string())
|
||||
.unwrap();
|
||||
let blank = settings.profile("blank").unwrap();
|
||||
assert!(blank.params.is_empty());
|
||||
assert!(blank.dashboards.is_empty());
|
||||
@@ -883,13 +987,21 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings.create_profile(&settings_path, "worker".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "worker".to_string())
|
||||
.unwrap();
|
||||
|
||||
settings.set_active_profile(&settings_path, Some("web".to_string())).unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("web".to_string()))
|
||||
.unwrap();
|
||||
assert_eq!(settings.active_profile, Some("web".to_string()));
|
||||
|
||||
settings.set_active_profile(&settings_path, Some("worker".to_string())).unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("worker".to_string()))
|
||||
.unwrap();
|
||||
let reloaded = Settings::load(&settings_path);
|
||||
assert_eq!(reloaded.active_profile, Some("worker".to_string()));
|
||||
|
||||
@@ -907,13 +1019,19 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
|
||||
let param_req = param_request("level", r"level=(?P<level>\w+)", "level");
|
||||
settings.record_param_declaration(&settings_path, "web", ¶m_req).unwrap();
|
||||
settings
|
||||
.record_param_declaration(&settings_path, "web", ¶m_req)
|
||||
.unwrap();
|
||||
|
||||
let metric_req = metric_request("requests", r"duration=(?P<duration>\d+)", "duration");
|
||||
settings.record_metric_declaration(&settings_path, "web", &metric_req, &[]).unwrap();
|
||||
settings
|
||||
.record_metric_declaration(&settings_path, "web", &metric_req, &[])
|
||||
.unwrap();
|
||||
|
||||
let profile = settings.profile("web").unwrap();
|
||||
assert_eq!(profile.params.len(), 1);
|
||||
@@ -922,7 +1040,9 @@ mod tests {
|
||||
assert_eq!(profile.metrics[0].name, "requests");
|
||||
|
||||
let param_req_v2 = param_request("level", r"lvl=(?P<level>\w+)", "level");
|
||||
settings.record_param_declaration(&settings_path, "web", ¶m_req_v2).unwrap();
|
||||
settings
|
||||
.record_param_declaration(&settings_path, "web", ¶m_req_v2)
|
||||
.unwrap();
|
||||
let profile = settings.profile("web").unwrap();
|
||||
assert_eq!(profile.params.len(), 1);
|
||||
assert_eq!(profile.params[0].message_match_regex, r"lvl=(?P<level>\w+)");
|
||||
@@ -939,15 +1059,23 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
let metric_req = metric_request("requests", r"duration=(?P<duration>\d+)", "duration");
|
||||
settings.record_metric_declaration(&settings_path, "web", &metric_req, &[]).unwrap();
|
||||
settings
|
||||
.record_metric_declaration(&settings_path, "web", &metric_req, &[])
|
||||
.unwrap();
|
||||
assert_eq!(settings.profile("web").unwrap().metrics.len(), 1);
|
||||
|
||||
settings.remove_metric_declaration(&settings_path, "web", "requests").unwrap();
|
||||
settings
|
||||
.remove_metric_declaration(&settings_path, "web", "requests")
|
||||
.unwrap();
|
||||
assert!(settings.profile("web").unwrap().metrics.is_empty());
|
||||
|
||||
settings.remove_metric_declaration(&settings_path, "web", "never-declared").unwrap();
|
||||
settings
|
||||
.remove_metric_declaration(&settings_path, "web", "never-declared")
|
||||
.unwrap();
|
||||
|
||||
let reloaded = Settings::load(&settings_path);
|
||||
assert!(reloaded.profile("web").unwrap().metrics.is_empty());
|
||||
@@ -959,7 +1087,9 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.record_param_declaration(
|
||||
&settings_path,
|
||||
@@ -971,18 +1101,28 @@ mod tests {
|
||||
.record_param_declaration(
|
||||
&settings_path,
|
||||
"web",
|
||||
¶m_request("duration", r"request duration=(?P<duration>\d+)", "duration"),
|
||||
¶m_request(
|
||||
"duration",
|
||||
r"request duration=(?P<duration>\d+)",
|
||||
"duration",
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
settings
|
||||
.record_metric_declaration(
|
||||
&settings_path,
|
||||
"web",
|
||||
&metric_request("requests", r"request duration=(?P<duration>\d+)", "duration"),
|
||||
&metric_request(
|
||||
"requests",
|
||||
r"request duration=(?P<duration>\d+)",
|
||||
"duration",
|
||||
),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
settings.set_active_profile(&settings_path, Some("web".to_string())).unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("web".to_string()))
|
||||
.unwrap();
|
||||
|
||||
drop(settings);
|
||||
let settings = Settings::load(&settings_path);
|
||||
@@ -1020,7 +1160,10 @@ mod tests {
|
||||
};
|
||||
assert_eq!(metrics.len(), 1);
|
||||
assert_eq!(metrics[0].name, "requests");
|
||||
assert_eq!(metrics[0].message_match_regex, r"request duration=(?P<duration>\d+)");
|
||||
assert_eq!(
|
||||
metrics[0].message_match_regex,
|
||||
r"request duration=(?P<duration>\d+)"
|
||||
);
|
||||
assert_eq!(metrics[0].label_params, vec!["duration".to_string()]);
|
||||
|
||||
let logs = match ask(
|
||||
@@ -1050,9 +1193,13 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
|
||||
let dashboard = settings.create_dashboard(&settings_path, "web", "Overview".to_string()).unwrap();
|
||||
let dashboard = settings
|
||||
.create_dashboard(&settings_path, "web", "Overview".to_string())
|
||||
.unwrap();
|
||||
assert_eq!(dashboard.name, "Overview");
|
||||
assert!(dashboard.panels.is_empty());
|
||||
|
||||
@@ -1077,7 +1224,9 @@ mod tests {
|
||||
assert_eq!(dashboards[0].panels.len(), 1);
|
||||
assert_eq!(dashboards[0].panels[0].promql, r#"requests{path="/a"}"#);
|
||||
|
||||
reloaded.delete_dashboard(&settings_path, "web", &dashboard.id).unwrap();
|
||||
reloaded
|
||||
.delete_dashboard(&settings_path, "web", &dashboard.id)
|
||||
.unwrap();
|
||||
assert!(reloaded.list_dashboards("web").unwrap().is_empty());
|
||||
let reloaded_again = Settings::load(&settings_path);
|
||||
assert!(reloaded_again.list_dashboards("web").unwrap().is_empty());
|
||||
@@ -1125,16 +1274,39 @@ mod tests {
|
||||
let profile = settings.profile("legacy").unwrap();
|
||||
|
||||
assert_eq!(profile.params.len(), 2);
|
||||
let path_param = profile.params.iter().find(|p| p.name == "requests.path").unwrap();
|
||||
assert_eq!(path_param.message_match_regex, profile.metrics[0].message_match_regex);
|
||||
let path_param = profile
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| p.name == "requests.path")
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
path_param.message_match_regex,
|
||||
profile.metrics[0].message_match_regex
|
||||
);
|
||||
assert_eq!(path_param.capture_group, "path");
|
||||
assert!(matches!(path_param.kind, ProfileMetricPrimitiveKind::String));
|
||||
let duration_param = profile.params.iter().find(|p| p.name == "requests.duration").unwrap();
|
||||
assert!(matches!(duration_param.kind, ProfileMetricPrimitiveKind::Number));
|
||||
assert!(matches!(
|
||||
path_param.kind,
|
||||
ProfileMetricPrimitiveKind::String
|
||||
));
|
||||
let duration_param = profile
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| p.name == "requests.duration")
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
duration_param.kind,
|
||||
ProfileMetricPrimitiveKind::Number
|
||||
));
|
||||
|
||||
assert_eq!(profile.metrics.len(), 1);
|
||||
assert_eq!(profile.metrics[0].label_params, vec!["requests.path".to_string()]);
|
||||
assert_eq!(profile.metrics[0].value_param, Some("requests.duration".to_string()));
|
||||
assert_eq!(
|
||||
profile.metrics[0].label_params,
|
||||
vec!["requests.path".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
profile.metrics[0].value_param,
|
||||
Some("requests.duration".to_string())
|
||||
);
|
||||
|
||||
let reloaded_raw = fs::read_to_string(&settings_path).unwrap();
|
||||
assert!(!reloaded_raw.contains("param_name"));
|
||||
@@ -1192,10 +1364,20 @@ mod tests {
|
||||
let settings = Settings::load(&settings_path);
|
||||
let profile = settings.profile("legacy").unwrap();
|
||||
|
||||
let gap_param = profile.params.iter().find(|p| p.name == "login_gap.gap").unwrap();
|
||||
assert!(matches!(gap_param.kind, ProfileMetricPrimitiveKind::Duration));
|
||||
let gap_param = profile
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| p.name == "login_gap.gap")
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
gap_param.kind,
|
||||
ProfileMetricPrimitiveKind::Duration
|
||||
));
|
||||
assert!(gap_param.elapsed_since_last);
|
||||
assert_eq!(profile.metrics[0].value_param, Some("login_gap.gap".to_string()));
|
||||
assert_eq!(
|
||||
profile.metrics[0].value_param,
|
||||
Some("login_gap.gap".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1229,7 +1411,14 @@ mod tests {
|
||||
|
||||
let gap_param = profile.params.iter().find(|p| p.name == "gap").unwrap();
|
||||
assert!(gap_param.elapsed_since_last);
|
||||
assert!(!profile.params.iter().find(|p| p.name == "user").unwrap().elapsed_since_last);
|
||||
assert!(
|
||||
!profile
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| p.name == "user")
|
||||
.unwrap()
|
||||
.elapsed_since_last
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1271,7 +1460,9 @@ mod tests {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.record_param_declaration(
|
||||
&settings_path,
|
||||
@@ -1280,7 +1471,12 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
settings
|
||||
.record_metric_declaration(&settings_path, "web", &metric_request("requests", r"path=(?P<path>\S+)", "path"), &[])
|
||||
.record_metric_declaration(
|
||||
&settings_path,
|
||||
"web",
|
||||
&metric_request("requests", r"path=(?P<path>\S+)", "path"),
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let before = settings.profile("web").unwrap().clone();
|
||||
@@ -1295,8 +1491,12 @@ mod tests {
|
||||
let settings_path = dir.path().join("settings.json");
|
||||
let mut settings = Settings::default();
|
||||
|
||||
settings.create_profile(&settings_path, "web".to_string()).unwrap();
|
||||
settings.set_active_profile(&settings_path, Some("web".to_string())).unwrap();
|
||||
settings
|
||||
.create_profile(&settings_path, "web".to_string())
|
||||
.unwrap();
|
||||
settings
|
||||
.set_active_profile(&settings_path, Some("web".to_string()))
|
||||
.unwrap();
|
||||
|
||||
let settings_handle = std::sync::Arc::new(std::sync::Mutex::new(settings.clone()));
|
||||
let engine_tx = crate::engine::spawn(settings_handle, 16);
|
||||
@@ -1314,7 +1514,10 @@ mod tests {
|
||||
let (respond_to, response) = oneshot::channel();
|
||||
engine_tx
|
||||
.tx
|
||||
.send(EngineMessage::DeclareMetric { request: metric_req.clone(), respond_to })
|
||||
.send(EngineMessage::DeclareMetric {
|
||||
request: metric_req.clone(),
|
||||
respond_to,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
response.await.unwrap().unwrap();
|
||||
@@ -1334,7 +1537,9 @@ mod tests {
|
||||
kind: dx.kind.into(),
|
||||
elapsed_since_last: dx.elapsed_since_last,
|
||||
};
|
||||
settings.record_metric_declaration(&settings_path, "web", &metric_req, &[promoted]).unwrap();
|
||||
settings
|
||||
.record_metric_declaration(&settings_path, "web", &metric_req, &[promoted])
|
||||
.unwrap();
|
||||
|
||||
drop(settings);
|
||||
let reloaded_settings = Settings::load(&settings_path);
|
||||
|
||||
Reference in New Issue
Block a user