fix: support __name__ matcher in label values (#5773)

This commit is contained in:
Yingwen
2025-03-28 10:18:59 +08:00
committed by GitHub
parent dbc25dd8da
commit 737558ef53
2 changed files with 36 additions and 2 deletions

View File

@@ -32,6 +32,7 @@ use datatypes::scalars::ScalarVector;
use datatypes::vectors::Float64Vector;
use futures::future::join_all;
use futures::StreamExt;
use itertools::Itertools;
use promql_parser::label::{MatchOp, Matcher, Matchers, METRIC_NAME};
use promql_parser::parser::value::ValueType;
use promql_parser::parser::{
@@ -1003,18 +1004,19 @@ pub async fn label_values_query(
for query in queries {
let promql_expr = try_call_return_response!(promql_parser::parser::parse(&query));
let PromqlExpr::VectorSelector(VectorSelector { name, matchers, .. }) = promql_expr else {
let PromqlExpr::VectorSelector(mut vector_selector) = promql_expr else {
return PrometheusJsonResponse::error(
StatusCode::InvalidArguments,
"expected vector selector",
);
};
let Some(name) = name else {
let Some(name) = take_metric_name(&mut vector_selector) else {
return PrometheusJsonResponse::error(
StatusCode::InvalidArguments,
"expected metric name",
);
};
let VectorSelector { matchers, .. } = vector_selector;
// Only use and filter matchers.
let matchers = matchers.matchers;
let result = handler
@@ -1048,6 +1050,25 @@ pub async fn label_values_query(
PrometheusJsonResponse::success(PrometheusResponse::LabelValues(label_values))
}
/// Take metric name from the [VectorSelector].
/// It takes the name in the selector or removes the name matcher.
fn take_metric_name(selector: &mut VectorSelector) -> Option<String> {
if let Some(name) = selector.name.take() {
return Some(name);
}
let (pos, matcher) = selector
.matchers
.matchers
.iter()
.find_position(|matcher| matcher.name == "__name__" && matcher.op == MatchOp::Equal)?;
let name = matcher.value.clone();
// We need to remove the name matcher to avoid using it as a filter in query.
selector.matchers.matchers.remove(pos);
Some(name)
}
async fn retrieve_field_names(
query_ctx: &QueryContext,
manager: CatalogManagerRef,

View File

@@ -682,6 +682,19 @@ pub async fn test_prom_http_api(store_type: StorageType) {
serde_json::from_value::<PrometheusResponse>(json!(["host1"])).unwrap()
);
// single match[] with __name__
let res = client
.get("/v1/prometheus/api/v1/label/host/values?match[]={__name__%3D%22demo%22}&start=0&end=300")
.send()
.await;
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<PrometheusJsonResponse>(&res.text().await).unwrap();
assert_eq!(body.status, "success");
assert_eq!(
body.data,
serde_json::from_value::<PrometheusResponse>(json!(["host1"])).unwrap()
);
// single match[]
let res = client
.get("/v1/prometheus/api/v1/label/idc/values?match[]=demo_metrics_with_nanos&start=0&end=600")