Unify param declarations: metrics reference params by name (ticket 037)

Collapse the Params-panel ParamDeclaration and the metric-embedded
RegexToMetricPrimitiveMatcher into a single ParamDeclaration type
(name, regex/capture-group-or-json-field-path, kind). MetricDeclaration
now references params by name via label_params: Vec<String> and
value_param: Option<String> instead of embedding its own extractor per
param, so a param declared once in the Params panel can be reused as a
label or value by any number of metrics. Declaring a metric that
references an undeclared param name is now rejected at declare-time.

Backend:
- src/data_value.rs: unified ParamDeclaration struct; MetricDeclaration
  data value now carries label_params/value_param instead of a Vec of
  inline matchers.
- src/engine.rs: DeclareParamRequest is now an alias for
  ParamDeclaration; DeclareMetricRequest carries label_params/
  value_param; validate_metric_request checks referenced param names
  against the declared-param store; apply_metric_to_log resolves
  label_params/value_param against a per-ingest resolved-param map
  instead of reading an inline matcher list.
- src/profile.rs: MetricDeclarationRecord carries label_params/
  value_param plus a private, serialize-skipped legacy_params field
  that only ever gets populated by deserializing a pre-037 profile
  file's old "params" key. ProfileStore::load migrates any such legacy
  metric into the unified shape (reusing an existing same-shaped bare
  param by name, or creating one implicitly named
  "<metric_name>.<param_name>"), then persists the migrated store so
  the on-disk file only carries the legacy shape once. Migration is
  idempotent (deterministic naming) and covered by dedicated tests.
- src/api.rs / src/dto.rs: MetricDeclarationDto and the declare/update
  metric response bodies updated to the new shape.

Frontend:
- webapp/src/lib/api.ts: MetricDeclaration type now has label_params/
  value_param; MetricParamMatcher/ParamRole types removed.
- webapp/src/components/Metrics.tsx: the declaration form now fetches
  declared params and lets you check off label params / pick a value
  param from that list, instead of re-entering a regex/capture-group/
  kind per metric param.

Leaves ticket 038 (duration as a derived param kind) and 039 (param
query resolving declared params) untouched, as scoped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-05 22:41:14 +01:00
co-authored by Claude Sonnet 5
parent 85fb145be7
commit e397f9fbdb
7 changed files with 755 additions and 594 deletions
+6 -3
View File
@@ -1,5 +1,5 @@
use crate::alerts::AlertCondition;
use crate::data_value::{MetricPrimitiveKind, RegexToMetricPrimitiveMatcher};
use crate::data_value::MetricPrimitiveKind;
use crate::metric_primitive::MetricPrimitive;
use crate::profile::{ChartType, Dashboard, Panel, Profile};
use crate::settings::{ColorScheme, CssEntry, Settings};
@@ -20,7 +20,7 @@ pub struct ParamDeclarationDto {
pub name: String,
pub message_match_regex: String,
pub capture_group: String,
/// See `crate::data_value::RegexToMetricPrimitiveMatcher::json_field_path`.
/// See `crate::data_value::ParamDeclaration::json_field_path`.
pub json_field_path: Option<String>,
pub kind: MetricPrimitiveKind,
}
@@ -29,7 +29,10 @@ pub struct ParamDeclarationDto {
pub struct MetricDeclarationDto {
pub name: String,
pub message_match_regex: String,
pub params: Vec<RegexToMetricPrimitiveMatcher>,
/// Names of standalone `ParamDeclaration`s used as this metric's bucket labels.
pub label_params: Vec<String>,
/// Name of the standalone `ParamDeclaration` (if any) whose primitive becomes this metric's per-event bucket value instead of a label.
pub value_param: Option<String>,
/// See `crate::engine::DeclareMetricRequest::matched_labels`.
pub matched_labels: Option<BTreeMap<String, String>>,
/// See `crate::engine::DeclareMetricRequest::unmatched_labels`.