Use target as name for aliased queries
This commit is contained in:
@@ -200,8 +200,11 @@ func (s *Service) toDataFrames(response *http.Response, refId string, fromAlert
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aliasRegex := regexp.MustCompile(`(alias\(|aliasByMetric|aliasByNode|aliasByTags|aliasQuery|aliasSub)`)
|
||||||
|
|
||||||
frames = data.Frames{}
|
frames = data.Frames{}
|
||||||
for _, series := range responseData {
|
for _, series := range responseData {
|
||||||
|
aliasMatch := aliasRegex.MatchString(series.Target)
|
||||||
timeVector := make([]time.Time, 0, len(series.DataPoints))
|
timeVector := make([]time.Time, 0, len(series.DataPoints))
|
||||||
values := make([]*float64, 0, len(series.DataPoints))
|
values := make([]*float64, 0, len(series.DataPoints))
|
||||||
|
|
||||||
@@ -217,7 +220,9 @@ func (s *Service) toDataFrames(response *http.Response, refId string, fromAlert
|
|||||||
tags := make(map[string]string)
|
tags := make(map[string]string)
|
||||||
for name, value := range series.Tags {
|
for name, value := range series.Tags {
|
||||||
if name == "name" {
|
if name == "name" {
|
||||||
if fromAlert {
|
// Queries with aliases should use the target as the name
|
||||||
|
// to ensure multi-dimensional queries are distinguishable from each other
|
||||||
|
if fromAlert || aliasMatch {
|
||||||
value = series.Target
|
value = series.Target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -738,6 +738,119 @@ Error: Target not found
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAliasMatching(t *testing.T) {
|
||||||
|
service := &Service{
|
||||||
|
logger: backend.Logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
target string
|
||||||
|
tagsName string
|
||||||
|
fromAlert bool
|
||||||
|
expectedLabelName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "alias() function sets name tag to target",
|
||||||
|
target: "alias(stats.counters.web.hits, 'Web Hits')",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "alias(stats.counters.web.hits, 'Web Hits')",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliasByNode() function sets name tag to target",
|
||||||
|
target: "aliasByNode(stats.counters.web.hits, 2)",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "aliasByNode(stats.counters.web.hits, 2)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliasByMetric() function sets name tag to target",
|
||||||
|
target: "aliasByMetric(stats.counters.web.hits)",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "aliasByMetric(stats.counters.web.hits)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliasByTags() function sets name tag to target",
|
||||||
|
target: "aliasByTags(stats.counters.web.hits, 'host')",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "aliasByTags(stats.counters.web.hits, 'host')",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliasSub() function sets name tag to target",
|
||||||
|
target: "aliasSub(stats.counters.web.hits, 'stats', 'metrics')",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "aliasSub(stats.counters.web.hits, 'stats', 'metrics')",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliasQuery() function sets name tag to target",
|
||||||
|
target: "aliasQuery(stats.counters.web.hits, 'SELECT name FROM hosts')",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "aliasQuery(stats.counters.web.hits, 'SELECT name FROM hosts')",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no alias function keeps original name tag",
|
||||||
|
target: "stats.counters.web.hits",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "stats.counters.web.hits",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fromAlert overrides name tag even without alias",
|
||||||
|
target: "stats.counters.web.hits",
|
||||||
|
tagsName: "original.name",
|
||||||
|
fromAlert: true,
|
||||||
|
expectedLabelName: "stats.counters.web.hits",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nested alias function matches",
|
||||||
|
target: "sumSeries(alias(stats.counters.*.hits, 'Hits'))",
|
||||||
|
tagsName: "stats.counters.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "sumSeries(alias(stats.counters.*.hits, 'Hits'))",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "alias in metric path should not match",
|
||||||
|
target: "stats.alias.web.hits",
|
||||||
|
tagsName: "stats.alias.web.hits",
|
||||||
|
fromAlert: false,
|
||||||
|
expectedLabelName: "stats.alias.web.hits",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
body := fmt.Sprintf(`[
|
||||||
|
{
|
||||||
|
"target": %q,
|
||||||
|
"tags": { "name": %q, "host": "server1" },
|
||||||
|
"datapoints": [[100, 1609459200]]
|
||||||
|
}
|
||||||
|
]`, tc.target, tc.tagsName)
|
||||||
|
|
||||||
|
httpResponse := &http.Response{StatusCode: 200, Body: io.NopCloser(strings.NewReader(body))}
|
||||||
|
dataFrames, err := service.toDataFrames(httpResponse, "A", tc.fromAlert)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, dataFrames, 1)
|
||||||
|
|
||||||
|
frame := dataFrames[0]
|
||||||
|
require.GreaterOrEqual(t, len(frame.Fields), 2)
|
||||||
|
|
||||||
|
valueField := frame.Fields[1]
|
||||||
|
require.NotNil(t, valueField.Labels)
|
||||||
|
|
||||||
|
actualName, ok := valueField.Labels["name"]
|
||||||
|
require.True(t, ok, "name label should exist")
|
||||||
|
assert.Equal(t, tc.expectedLabelName, actualName, "name label should match expected value")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseGraphiteError(t *testing.T) {
|
func TestParseGraphiteError(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
Reference in New Issue
Block a user