mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 10:20:29 -06:00
85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package cloudwatch
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/models"
|
|
)
|
|
|
|
// nonWordRegex is for spliting the expressions to just functions and ids
|
|
var nonWordRegex = regexp.MustCompile(`\W+`)
|
|
|
|
// getMetricQueryBatches separates queries into batches if necessary. Metric Insight queries cannot run together, and math expressions must be run
|
|
// with all the queries they reference.
|
|
func getMetricQueryBatches(queries []*models.CloudWatchQuery, logger log.Logger) [][]*models.CloudWatchQuery {
|
|
metricInsightIndices := []int{}
|
|
mathIndices := []int{}
|
|
for i, query := range queries {
|
|
switch query.GetGetMetricDataAPIMode() {
|
|
case models.GMDApiModeSQLExpression:
|
|
metricInsightIndices = append(metricInsightIndices, i)
|
|
case models.GMDApiModeMathExpression:
|
|
mathIndices = append(mathIndices, i)
|
|
default:
|
|
}
|
|
}
|
|
// We only need multiple batches if there are multiple metrics insight queries
|
|
if len(metricInsightIndices) <= 1 {
|
|
return [][]*models.CloudWatchQuery{queries}
|
|
}
|
|
|
|
logger.Debug("Separating queries into batches")
|
|
// Map ids to their queries
|
|
idToIndex := map[string]int{}
|
|
for i, query := range queries {
|
|
if query.Id != "" {
|
|
idToIndex[query.Id] = i
|
|
}
|
|
}
|
|
|
|
// Find and track which queries are referenced by math queries
|
|
queryReferences := make([][]int, len(queries))
|
|
isReferenced := make([]bool, len(queries))
|
|
for _, idx := range mathIndices {
|
|
tokens := nonWordRegex.Split(queries[idx].Expression, -1)
|
|
references := []int{}
|
|
for _, token := range tokens {
|
|
ref, found := idToIndex[token]
|
|
if found {
|
|
references = append(references, ref)
|
|
isReferenced[ref] = true
|
|
}
|
|
}
|
|
queryReferences[idx] = references
|
|
}
|
|
|
|
// Create a new batch for every query not used in another query
|
|
batches := [][]*models.CloudWatchQuery{}
|
|
for i, used := range isReferenced {
|
|
if !used {
|
|
batches = append(batches, getReferencedQueries(queries, queryReferences, i))
|
|
}
|
|
}
|
|
return batches
|
|
}
|
|
|
|
// getReferencedQueries gets all the queries referenced by startQuery and its referenced queries
|
|
func getReferencedQueries(queries []*models.CloudWatchQuery, queryReferences [][]int, startQuery int) []*models.CloudWatchQuery {
|
|
usedQueries := make([]bool, len(queries))
|
|
batch := []*models.CloudWatchQuery{}
|
|
|
|
queriesToAdd := []int{startQuery}
|
|
usedQueries[startQuery] = true
|
|
for i := 0; i < len(queriesToAdd); i++ {
|
|
batch = append(batch, queries[queriesToAdd[i]])
|
|
for _, queryIdx := range queryReferences[queriesToAdd[i]] {
|
|
if !usedQueries[queryIdx] {
|
|
usedQueries[queryIdx] = true
|
|
queriesToAdd = append(queriesToAdd, queryIdx)
|
|
}
|
|
}
|
|
}
|
|
return batch
|
|
}
|