Skip to content

Improve cortex-tool analyse to handle more panel types and queries #231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ replace github.com/bradfitz/gomemcache => github.com/themihai/gomemcache v0.0.0-

replace github.com/hashicorp/consul => github.com/hashicorp/consul v1.8.1

replace github.com/grafana-tools/sdk => github.com/colega/grafana-tools-sdk v0.0.0-20220323154849-711bca56d13f
replace github.com/grafana-tools/sdk => github.com/colega/grafana-tools-sdk v0.0.0-20220401112130-163cd43fb5e4
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/colega/grafana-tools-sdk v0.0.0-20220323154849-711bca56d13f h1:Mc/WpMhT0pzDD5zGjhge7PiO7nkrMME4GuGS1y4HGwk=
github.com/colega/grafana-tools-sdk v0.0.0-20220323154849-711bca56d13f/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4=
github.com/colega/grafana-tools-sdk v0.0.0-20220401112130-163cd43fb5e4 h1:u75LBGHfI1jW4gY3gM5h0WFizp7Yues4go+z6ope6vk=
github.com/colega/grafana-tools-sdk v0.0.0-20220401112130-163cd43fb5e4/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
Expand Down
55 changes: 52 additions & 3 deletions pkg/analyse/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package analyse

import (
"fmt"
"reflect"
"regexp"
"sort"
"strings"
Expand Down Expand Up @@ -83,10 +84,24 @@ func metricsFromTemplating(templating sdk.Templating, metrics map[string]struct{
if templateVar.Type != "query" {
continue
}
if query, ok := templateVar.Query.(string); ok {

query, ok := templateVar.Query.(string)
if !ok {
iter := reflect.ValueOf(templateVar.Query).MapRange() // A query struct
for iter.Next() {
key := iter.Key().Interface()
value := iter.Value().Interface()
if key == "query" {
query = value.(string)
break
}
}
}

if query != "" {
// label_values
if strings.Contains(query, "label_values") {
re := regexp.MustCompile(`label_values\(([a-zA-Z0-9_]+)`)
re := regexp.MustCompile(`label_values\(\s*([a-zA-Z0-9_]+)`)
sm := re.FindStringSubmatch(query)
// In case of really gross queries, like - https://github.com/grafana/jsonnet-libs/blob/e97ab17f67ab40d5fe3af7e59151dd43be03f631/hass-mixin/dashboard.libsonnet#L93
if len(sm) > 0 {
Expand All @@ -113,10 +128,23 @@ func metricsFromTemplating(templating sdk.Templating, metrics map[string]struct{
}
return parseErrors
}

func metricsFromPanel(panel sdk.Panel, metrics map[string]struct{}) []error {
var parseErrors []error

switch panel.CommonPanel.Type {
case
"row",
"welcome",
"dashlist",
"news",
"annolist",
"alertlist",
"pluginlist",
"grafana-clock-panel",
"text":
return parseErrors // Let's not throw parse errors...these don't contain queries!
}

targets := panel.GetTargets()
if targets == nil {
parseErrors = append(parseErrors, fmt.Errorf("unsupported panel type: %q", panel.CommonPanel.Type))
Expand All @@ -141,20 +169,41 @@ func metricsFromPanel(panel sdk.Panel, metrics map[string]struct{}) []error {
}

func parseQuery(query string, metrics map[string]struct{}) error {
re := regexp.MustCompile(`\[\s*\$(\w+|{\w+})\]`) // variable rate interval
query = re.ReplaceAllString(query, "[1s]")

re1 := regexp.MustCompile(`offset\s+\$(\w+|{\w+})`) // variable offset
query = re1.ReplaceAllString(query, "offset 1s")

re2 := regexp.MustCompile(`(by\s*\()\$((\w+|{\w+}))`) // variable by clause
query = re2.ReplaceAllString(query, "$1$2")

query = strings.ReplaceAll(query, `$__interval`, "5m")
query = strings.ReplaceAll(query, `$interval`, "5m")
query = strings.ReplaceAll(query, `$resolution`, "5s")
query = strings.ReplaceAll(query, "$__rate_interval", "15s")
query = strings.ReplaceAll(query, "$__range", "1d")
query = strings.ReplaceAll(query, "${__range_s:glob}", "30")
query = strings.ReplaceAll(query, "${__range_s}", "30")

re3 := regexp.MustCompile(`\$(__(to|from):date:\w+\b|{__(to|from):date:\w+})`)
query = re3.ReplaceAllString(query, "12") // Replace dates

// Replace *all* variables. Magic number 79197919 is used as it's unlikely to appear in a query. Some queries have
// variable metric names. There is a check a few lines below for this edge case.
re4 := regexp.MustCompile(`\$(\w+|{\w+})`)
query = re4.ReplaceAllString(query, "79197919")

expr, err := parser.ParseExpr(query)
if err != nil {
return err
}

parser.Inspect(expr, func(node parser.Node, path []parser.Node) error {
if n, ok := node.(*parser.VectorSelector); ok {
if strings.Contains(n.Name, "79197919") { // Check for the magic number in the metric name..drop it
return errors.New("Query contains a variable in the metric name")
}
metrics[n.Name] = struct{}{}
}

Expand Down
148 changes: 78 additions & 70 deletions vendor/github.com/grafana-tools/sdk/panel.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ github.com/googleapis/gax-go/v2/apierror/internal/proto
github.com/gorilla/mux
# github.com/gosimple/slug v1.1.1
github.com/gosimple/slug
# github.com/grafana-tools/sdk v0.0.0-20220203092117-edae16afa87b => github.com/colega/grafana-tools-sdk v0.0.0-20220323154849-711bca56d13f
# github.com/grafana-tools/sdk v0.0.0-20220203092117-edae16afa87b => github.com/colega/grafana-tools-sdk v0.0.0-20220401112130-163cd43fb5e4
## explicit
github.com/grafana-tools/sdk
# github.com/grafana/dskit v0.0.0-20211103155626-4e784973d341
Expand Down Expand Up @@ -1169,4 +1169,4 @@ rsc.io/binaryregexp/syntax
# github.com/gocql/gocql => github.com/grafana/gocql v0.0.0-20200605141915-ba5dc39ece85
# github.com/bradfitz/gomemcache => github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab
# github.com/hashicorp/consul => github.com/hashicorp/consul v1.8.1
# github.com/grafana-tools/sdk => github.com/colega/grafana-tools-sdk v0.0.0-20220323154849-711bca56d13f
# github.com/grafana-tools/sdk => github.com/colega/grafana-tools-sdk v0.0.0-20220401112130-163cd43fb5e4