types.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package mqe
  2. import (
  3. "fmt"
  4. "strings"
  5. "regexp"
  6. "github.com/grafana/grafana/pkg/log"
  7. "github.com/grafana/grafana/pkg/tsdb"
  8. )
  9. type Metric struct {
  10. Metric string
  11. Alias string
  12. }
  13. type Function struct {
  14. Func string
  15. }
  16. type Query struct {
  17. Metrics []Metric
  18. Hosts []string
  19. Cluster []string
  20. FunctionList []Function
  21. AddClusterToAlias bool
  22. AddHostToAlias bool
  23. TimeRange *tsdb.TimeRange
  24. UseRawQuery bool
  25. RawQuery string
  26. }
  27. var (
  28. containsWildcardPattern *regexp.Regexp = regexp.MustCompile(`\*`)
  29. )
  30. func (q *Query) Build(availableSeries []string) ([]QueryToSend, error) {
  31. var queriesToSend []QueryToSend
  32. where := q.buildWhereClause()
  33. functions := q.buildFunctionList()
  34. for _, metric := range q.Metrics {
  35. alias := ""
  36. if metric.Alias != "" {
  37. alias = fmt.Sprintf(" {%s}", metric.Alias)
  38. }
  39. if !containsWildcardPattern.Match([]byte(metric.Metric)) {
  40. rawQuery := q.renderQuerystring(metric.Metric, functions, alias, where, q.TimeRange)
  41. queriesToSend = append(queriesToSend, QueryToSend{
  42. RawQuery: rawQuery,
  43. QueryRef: q,
  44. })
  45. } else {
  46. m := strings.Replace(metric.Metric, "*", ".*", -1)
  47. mp, err := regexp.Compile(m)
  48. if err != nil {
  49. log.Error2("failed to compile regex for ", "metric", m)
  50. continue
  51. }
  52. //TODO: this lookup should be cached
  53. for _, wildcardMatch := range availableSeries {
  54. if mp.Match([]byte(wildcardMatch)) {
  55. rawQuery := q.renderQuerystring(wildcardMatch, functions, alias, where, q.TimeRange)
  56. queriesToSend = append(queriesToSend, QueryToSend{
  57. RawQuery: rawQuery,
  58. QueryRef: q,
  59. })
  60. }
  61. }
  62. }
  63. }
  64. return queriesToSend, nil
  65. }
  66. func (q *Query) renderQuerystring(path, functions, alias, where string, timerange *tsdb.TimeRange) string {
  67. return fmt.Sprintf(
  68. "`%s`%s%s %s from %v to %v",
  69. path,
  70. functions,
  71. alias,
  72. where,
  73. q.TimeRange.GetFromAsMsEpoch(),
  74. q.TimeRange.GetToAsMsEpoch())
  75. }
  76. func (q *Query) buildFunctionList() string {
  77. functions := ""
  78. for _, v := range q.FunctionList {
  79. functions = fmt.Sprintf("%s|%s", functions, v.Func)
  80. }
  81. return functions
  82. }
  83. func (q *Query) buildWhereClause() string {
  84. hasApps := len(q.Cluster) > 0
  85. hasHosts := len(q.Hosts) > 0
  86. where := ""
  87. if hasHosts || hasApps {
  88. where += "where "
  89. }
  90. if hasApps {
  91. apps := strings.Join(q.Cluster, "', '")
  92. where += fmt.Sprintf("cluster in ('%s')", apps)
  93. }
  94. if hasHosts && hasApps {
  95. where += " and "
  96. }
  97. if hasHosts {
  98. hosts := strings.Join(q.Hosts, "', '")
  99. where += fmt.Sprintf("host in ('%s')", hosts)
  100. }
  101. return where
  102. }
  103. type TokenBody struct {
  104. Metrics []string
  105. }
  106. type TokenResponse struct {
  107. Success bool
  108. Body TokenBody
  109. }