json_index.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package search
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "time"
  8. "github.com/grafana/grafana/pkg/log"
  9. m "github.com/grafana/grafana/pkg/models"
  10. )
  11. type JsonDashIndex struct {
  12. path string
  13. items []*JsonDashIndexItem
  14. }
  15. type JsonDashIndexItem struct {
  16. TitleLower string
  17. TagsCsv string
  18. Path string
  19. Dashboard *m.Dashboard
  20. }
  21. func NewJsonDashIndex(path string) *JsonDashIndex {
  22. log.Info("Creating json dashboard index for path: %v", path)
  23. index := JsonDashIndex{}
  24. index.path = path
  25. index.updateIndex()
  26. return &index
  27. }
  28. func (index *JsonDashIndex) updateLoop() {
  29. ticker := time.NewTicker(time.Minute)
  30. for {
  31. select {
  32. case <-ticker.C:
  33. if err := index.updateIndex(); err != nil {
  34. log.Error(3, "Failed to update dashboard json index %v", err)
  35. }
  36. }
  37. }
  38. }
  39. func (index *JsonDashIndex) Search(query *Query) ([]*Hit, error) {
  40. results := make([]*Hit, 0)
  41. for _, item := range index.items {
  42. if len(results) > query.Limit {
  43. break
  44. }
  45. // filter out results with tag filter
  46. if query.Tag != "" {
  47. if !strings.Contains(item.TagsCsv, query.Tag) {
  48. continue
  49. }
  50. }
  51. // add results with matchig title filter
  52. if strings.Contains(item.TitleLower, query.Title) {
  53. results = append(results, &Hit{
  54. Type: DashHitJson,
  55. Title: item.Dashboard.Title,
  56. Tags: item.Dashboard.GetTags(),
  57. Uri: "file/" + item.Path,
  58. })
  59. }
  60. }
  61. return results, nil
  62. }
  63. func (index *JsonDashIndex) GetDashboard(path string) *m.Dashboard {
  64. for _, item := range index.items {
  65. if item.Path == path {
  66. return item.Dashboard
  67. }
  68. }
  69. return nil
  70. }
  71. func (index *JsonDashIndex) updateIndex() error {
  72. var items = make([]*JsonDashIndexItem, 0)
  73. visitor := func(path string, f os.FileInfo, err error) error {
  74. if err != nil {
  75. return err
  76. }
  77. if f.IsDir() {
  78. return nil
  79. }
  80. if strings.HasSuffix(f.Name(), ".json") {
  81. dash, err := loadDashboardFromFile(path)
  82. if err != nil {
  83. return err
  84. }
  85. items = append(items, dash)
  86. }
  87. return nil
  88. }
  89. if err := filepath.Walk(index.path, visitor); err != nil {
  90. return err
  91. }
  92. index.items = items
  93. return nil
  94. }
  95. func loadDashboardFromFile(filename string) (*JsonDashIndexItem, error) {
  96. reader, err := os.Open(filename)
  97. if err != nil {
  98. return nil, err
  99. }
  100. defer reader.Close()
  101. jsonParser := json.NewDecoder(reader)
  102. var data map[string]interface{}
  103. if err := jsonParser.Decode(&data); err != nil {
  104. return nil, err
  105. }
  106. stat, _ := os.Stat(filename)
  107. item := &JsonDashIndexItem{}
  108. item.Dashboard = m.NewDashboardFromJson(data)
  109. item.TitleLower = strings.ToLower(item.Dashboard.Title)
  110. item.TagsCsv = strings.Join(item.Dashboard.GetTags(), ",")
  111. item.Path = stat.Name()
  112. return item, nil
  113. }