types.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 _, v := range q.Metrics {
  35. if !containsWildcardPattern.Match([]byte(v.Metric)) {
  36. alias := ""
  37. if v.Alias != "" {
  38. alias = fmt.Sprintf(" {%s}", v.Alias)
  39. }
  40. rawQuery := fmt.Sprintf(
  41. "`%s`%s%s %s from %v to %v",
  42. v.Metric,
  43. functions,
  44. alias,
  45. where,
  46. q.TimeRange.GetFromAsMsEpoch(),
  47. q.TimeRange.GetToAsMsEpoch())
  48. queriesToSend = append(queriesToSend, QueryToSend{
  49. RawQuery: rawQuery,
  50. QueryRef: q,
  51. })
  52. continue
  53. }
  54. m := strings.Replace(v.Metric, "*", ".*", -1)
  55. mp, err := regexp.Compile(m)
  56. if err != nil {
  57. log.Error2("failed to compile regex for ", "metric", m)
  58. continue
  59. }
  60. //TODO: this lookup should be cached
  61. for _, a := range availableSeries {
  62. if mp.Match([]byte(a)) {
  63. alias := ""
  64. if v.Alias != "" {
  65. alias = fmt.Sprintf(" {%s}", v.Alias)
  66. }
  67. rawQuery := fmt.Sprintf(
  68. "`%s`%s%s %s from %v to %v",
  69. a,
  70. functions,
  71. alias,
  72. where,
  73. q.TimeRange.GetFromAsMsEpoch(),
  74. q.TimeRange.GetToAsMsEpoch())
  75. queriesToSend = append(queriesToSend, QueryToSend{
  76. RawQuery: rawQuery,
  77. QueryRef: q,
  78. })
  79. }
  80. }
  81. }
  82. return queriesToSend, nil
  83. }
  84. func (q *Query) buildFunctionList() string {
  85. functions := ""
  86. for _, v := range q.FunctionList {
  87. functions = fmt.Sprintf("%s|%s", functions, v.Func)
  88. }
  89. return functions
  90. }
  91. func (q *Query) buildWhereClause() string {
  92. hasApps := len(q.Cluster) > 0
  93. hasHosts := len(q.Hosts) > 0
  94. where := ""
  95. if hasHosts || hasApps {
  96. where += "where "
  97. }
  98. if hasApps {
  99. apps := strings.Join(q.Cluster, "', '")
  100. where += fmt.Sprintf("cluster in ('%s')", apps)
  101. }
  102. if hasHosts && hasApps {
  103. where += " and "
  104. }
  105. if hasHosts {
  106. hosts := strings.Join(q.Hosts, "', '")
  107. where += fmt.Sprintf("host in ('%s')", hosts)
  108. }
  109. return where
  110. }
  111. type TokenBody struct {
  112. Metrics []string
  113. }
  114. type TokenResponse struct {
  115. Success bool
  116. Body TokenBody
  117. }