mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-09-08 22:48:58 +00:00
fix: honor default prefix for all metric columns (#8640)
* fix: honor default prefix for metric columns Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: cr issue Signed-off-by: shuiyisong <xixing.sys@gmail.com> --------- Signed-off-by: shuiyisong <xixing.sys@gmail.com>
This commit is contained in:
@@ -853,6 +853,7 @@ fn encode_summary(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use common_query::prelude::set_default_prefix;
|
||||
use otel_arrow_rust::proto::opentelemetry::common::v1::AnyValue;
|
||||
use otel_arrow_rust::proto::opentelemetry::common::v1::any_value::Value as Val;
|
||||
use otel_arrow_rust::proto::opentelemetry::metrics::v1::number_data_point::Value;
|
||||
@@ -1054,6 +1055,47 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_legacy_summary_keeps_legacy_column_names() {
|
||||
set_default_prefix(Some("custom")).unwrap();
|
||||
let mut tables = MultiTableData::default();
|
||||
let summary = Summary {
|
||||
data_points: vec![SummaryDataPoint {
|
||||
attributes: vec![keyvalue("host", "testserver")],
|
||||
time_unix_nano: 100,
|
||||
count: 25,
|
||||
quantile_values: vec![ValueAtQuantile {
|
||||
quantile: 0.90,
|
||||
value: 1000.0,
|
||||
}],
|
||||
..Default::default()
|
||||
}],
|
||||
};
|
||||
|
||||
encode_summary(
|
||||
&mut tables,
|
||||
"datamon",
|
||||
&summary,
|
||||
None,
|
||||
None,
|
||||
&OtlpMetricCtx {
|
||||
is_legacy: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let table = tables.get_or_default_table_data("datamon", 0, 0);
|
||||
assert_eq!(
|
||||
table
|
||||
.columns()
|
||||
.iter()
|
||||
.map(|column| column.column_name.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["host", "custom_timestamp", "greptime_p90", GREPTIME_COUNT,]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_histogram() {
|
||||
let mut tables = MultiTableData::default();
|
||||
|
||||
@@ -25,7 +25,7 @@ flowchart TD
|
||||
J --> K["same metric-engine flag as samples, no batcher"]
|
||||
K --> L["table: <metric>"]
|
||||
|
||||
L --> M["field: greptime_native_histogram Struct"]
|
||||
L --> M["field: configured native-histogram Struct"]
|
||||
M --> N["struct children: counts, spans, buckets, sum, schema"]
|
||||
H --> P["written headers and counters"]
|
||||
K --> P
|
||||
@@ -41,7 +41,9 @@ Native histogram rows follow the same metric-engine switch as samples. They do
|
||||
not use the pending rows batcher yet because the batcher assumes the classic
|
||||
timestamp + Float64 value + string tags shape.
|
||||
|
||||
Each histogram row stores `greptime_native_histogram` as one Struct field:
|
||||
Each histogram row stores one Struct field named
|
||||
`<default_column_prefix>_native_histogram`. The default name is
|
||||
`greptime_native_histogram`; an empty prefix produces `native_histogram`.
|
||||
|
||||
- common scalar children: `schema`, `zero_threshold`, `sum`, `reset_hint`,
|
||||
`start_timestamp`;
|
||||
|
||||
@@ -25,7 +25,7 @@ use api::v1::{ColumnSchema, ListValue, RowInsertRequest, Rows, SemanticType, Val
|
||||
use bytes::Bytes;
|
||||
use common_grpc::precision::Precision;
|
||||
use common_query::native_histogram::*;
|
||||
use common_query::prelude::{greptime_timestamp, greptime_value};
|
||||
use common_query::prelude::{greptime_native_histogram, greptime_timestamp, greptime_value};
|
||||
use pipeline::{ContextOpt, ContextReq};
|
||||
use prost::Message;
|
||||
use snafu::{OptionExt, ResultExt, ensure};
|
||||
@@ -270,7 +270,7 @@ fn native_histogram_column_schema() -> ColumnSchema {
|
||||
.into_parts();
|
||||
|
||||
ColumnSchema {
|
||||
column_name: NATIVE_HISTOGRAM_FIELD.to_string(),
|
||||
column_name: greptime_native_histogram().to_string(),
|
||||
datatype: datatype as i32,
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
datatype_extension,
|
||||
@@ -400,7 +400,7 @@ fn ensure_no_internal_histogram_labels(tags: &PromTags) -> Result<()> {
|
||||
// The histogram field column is generated from the protobuf payload.
|
||||
for (name, _) in tags {
|
||||
ensure!(
|
||||
name != NATIVE_HISTOGRAM_FIELD,
|
||||
name != greptime_native_histogram() && name != NATIVE_HISTOGRAM_FIELD,
|
||||
error::InvalidPromRemoteRequestSnafu {
|
||||
msg: format!(
|
||||
"remote write v2 label `{name}` conflicts with an internal native histogram label"
|
||||
@@ -625,7 +625,7 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use api::v1::value::ValueData;
|
||||
use common_query::prelude::{greptime_timestamp, greptime_value};
|
||||
use common_query::prelude::{greptime_timestamp, greptime_value, set_default_prefix};
|
||||
use session::context::QueryContext;
|
||||
|
||||
use super::*;
|
||||
@@ -854,7 +854,7 @@ mod tests {
|
||||
"internal histogram label on samples",
|
||||
request_with_sample(vec![
|
||||
(METRIC_NAME_LABEL, "metric"),
|
||||
(NATIVE_HISTOGRAM_FIELD, "user_value"),
|
||||
(greptime_native_histogram(), "user_value"),
|
||||
]),
|
||||
"conflicts with an internal native histogram label",
|
||||
));
|
||||
@@ -962,7 +962,7 @@ mod tests {
|
||||
.iter()
|
||||
.map(|col| col.column_name.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
vec![greptime_timestamp(), NATIVE_HISTOGRAM_FIELD]
|
||||
vec![greptime_timestamp(), greptime_native_histogram()]
|
||||
);
|
||||
assert_eq!(
|
||||
rows.rows[0].values[0].value_data,
|
||||
@@ -1005,7 +1005,7 @@ mod tests {
|
||||
let mut request = test_util::request_with_labels_and_samples(
|
||||
vec![
|
||||
(METRIC_NAME_LABEL, "metric"),
|
||||
(NATIVE_HISTOGRAM_FIELD, "user_value"),
|
||||
(greptime_native_histogram(), "user_value"),
|
||||
],
|
||||
vec![],
|
||||
);
|
||||
@@ -1021,6 +1021,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rejects_legacy_histogram_label_after_prefix_change() {
|
||||
set_default_prefix(Some("custom")).unwrap();
|
||||
assert_eq!(greptime_native_histogram(), "custom_native_histogram");
|
||||
|
||||
let err = ensure_no_internal_histogram_labels(&vec![(
|
||||
NATIVE_HISTOGRAM_FIELD.to_string(),
|
||||
"user_value".to_string(),
|
||||
)])
|
||||
.unwrap_err();
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("conflicts with an internal native histogram label")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_context_req_converts_int_and_float_histograms_to_one_schema() {
|
||||
let float_histogram = Histogram {
|
||||
@@ -1070,7 +1086,7 @@ mod tests {
|
||||
.iter()
|
||||
.map(|col| col.column_name.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
vec![greptime_timestamp(), NATIVE_HISTOGRAM_FIELD]
|
||||
vec![greptime_timestamp(), greptime_native_histogram()]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -1138,7 +1154,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn histogram_field_value(rows: &Rows, row_idx: usize, field_name: &str) -> Option<ValueData> {
|
||||
let histogram_idx = column_index(&rows.schema, NATIVE_HISTOGRAM_FIELD);
|
||||
let histogram_idx = column_index(&rows.schema, greptime_native_histogram());
|
||||
let Some(ValueData::StructValue(histogram)) =
|
||||
&rows.rows[row_idx].values[histogram_idx].value_data
|
||||
else {
|
||||
|
||||
@@ -28,8 +28,9 @@ use async_trait::async_trait;
|
||||
use axum::Router;
|
||||
use axum::http::HeaderMap;
|
||||
use common_query::Output;
|
||||
use common_query::native_histogram::NATIVE_HISTOGRAM_FIELD;
|
||||
use common_query::prelude::{GREPTIME_PHYSICAL_TABLE, greptime_timestamp, greptime_value};
|
||||
use common_query::prelude::{
|
||||
GREPTIME_PHYSICAL_TABLE, greptime_native_histogram, greptime_timestamp, greptime_value,
|
||||
};
|
||||
use common_test_util::ports;
|
||||
use datafusion_expr::LogicalPlan;
|
||||
use prost::Message;
|
||||
@@ -675,7 +676,7 @@ async fn test_prometheus_remote_write_v2_writes_histogram_only_series() {
|
||||
assert!(
|
||||
rows.schema
|
||||
.iter()
|
||||
.any(|column| column.column_name == NATIVE_HISTOGRAM_FIELD
|
||||
.any(|column| column.column_name == greptime_native_histogram()
|
||||
&& column.datatype == ColumnDataType::Struct as i32)
|
||||
);
|
||||
assert!(write_rx.try_recv().is_err());
|
||||
|
||||
@@ -18,10 +18,10 @@ use api::v1::value::ValueData;
|
||||
use api::v1::{ColumnSchema, Rows};
|
||||
use bytes::Bytes;
|
||||
use common_query::native_histogram::{
|
||||
COUNT_U64_FIELD, NATIVE_HISTOGRAM_FIELD, NATIVE_HISTOGRAM_FIELD_NAMES,
|
||||
POSITIVE_BUCKETS_F64_FIELD, POSITIVE_BUCKETS_I64_FIELD, POSITIVE_SPAN_OFFSETS_FIELD,
|
||||
SCHEMA_FIELD,
|
||||
COUNT_U64_FIELD, NATIVE_HISTOGRAM_FIELD_NAMES, POSITIVE_BUCKETS_F64_FIELD,
|
||||
POSITIVE_BUCKETS_I64_FIELD, POSITIVE_SPAN_OFFSETS_FIELD, SCHEMA_FIELD,
|
||||
};
|
||||
use common_query::prelude::greptime_native_histogram;
|
||||
use servers::prom_remote_write::v2::test_util as remote_write_v2;
|
||||
|
||||
#[test]
|
||||
@@ -126,7 +126,7 @@ fn column_index(schema: &[ColumnSchema], column_name: &str) -> usize {
|
||||
}
|
||||
|
||||
fn histogram_field_value(rows: &Rows, row_idx: usize, field_name: &str) -> Option<ValueData> {
|
||||
let histogram_idx = column_index(&rows.schema, NATIVE_HISTOGRAM_FIELD);
|
||||
let histogram_idx = column_index(&rows.schema, greptime_native_histogram());
|
||||
let Some(ValueData::StructValue(histogram)) =
|
||||
&rows.rows[row_idx].values[histogram_idx].value_data
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user