annotations.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package api
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "github.com/grafana/grafana/pkg/api/dtos"
  7. "github.com/grafana/grafana/pkg/components/simplejson"
  8. "github.com/grafana/grafana/pkg/middleware"
  9. "github.com/grafana/grafana/pkg/services/annotations"
  10. )
  11. func GetAnnotations(c *middleware.Context) Response {
  12. query := &annotations.ItemQuery{
  13. From: c.QueryInt64("from") / 1000,
  14. To: c.QueryInt64("to") / 1000,
  15. OrgId: c.OrgId,
  16. AlertId: c.QueryInt64("alertId"),
  17. DashboardId: c.QueryInt64("dashboardId"),
  18. PanelId: c.QueryInt64("panelId"),
  19. Limit: c.QueryInt64("limit"),
  20. Tags: c.QueryStrings("tags"),
  21. }
  22. repo := annotations.GetRepository()
  23. items, err := repo.Find(query)
  24. if err != nil {
  25. return ApiError(500, "Failed to get annotations", err)
  26. }
  27. for _, item := range items {
  28. if item.Email != "" {
  29. item.AvatarUrl = dtos.GetGravatarUrl(item.Email)
  30. }
  31. item.Time = item.Time * 1000
  32. }
  33. return Json(200, items)
  34. }
  35. func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response {
  36. repo := annotations.GetRepository()
  37. item := annotations.Item{
  38. OrgId: c.OrgId,
  39. UserId: c.UserId,
  40. DashboardId: cmd.DashboardId,
  41. PanelId: cmd.PanelId,
  42. Epoch: cmd.Time / 1000,
  43. Text: cmd.Text,
  44. Data: cmd.Data,
  45. Tags: cmd.Tags,
  46. }
  47. if err := repo.Save(&item); err != nil {
  48. return ApiError(500, "Failed to save annotation", err)
  49. }
  50. // handle regions
  51. if cmd.IsRegion {
  52. item.RegionId = item.Id
  53. if item.Data == nil {
  54. item.Data = simplejson.New()
  55. }
  56. if err := repo.Update(&item); err != nil {
  57. return ApiError(500, "Failed set regionId on annotation", err)
  58. }
  59. item.Id = 0
  60. item.Epoch = cmd.TimeEnd / 1000
  61. if err := repo.Save(&item); err != nil {
  62. return ApiError(500, "Failed save annotation for region end time", err)
  63. }
  64. }
  65. return ApiSuccess("Annotation added")
  66. }
  67. type GraphiteAnnotationError struct {
  68. message string
  69. }
  70. func (e *GraphiteAnnotationError) Error() string {
  71. return e.message
  72. }
  73. func formatGraphiteAnnotation(what string, data string) string {
  74. return fmt.Sprintf("%s\n%s", what, data)
  75. }
  76. func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotationsCmd) Response {
  77. repo := annotations.GetRepository()
  78. if cmd.When == 0 {
  79. cmd.When = time.Now().Unix()
  80. }
  81. text := formatGraphiteAnnotation(cmd.What, cmd.Data)
  82. // Support tags in prior to Graphite 0.10.0 format (string of tags separated by space)
  83. var tagsArray []string
  84. switch tags := cmd.Tags.(type) {
  85. case string:
  86. tagsArray = strings.Split(tags, " ")
  87. case []interface{}:
  88. for _, t := range tags {
  89. if tagStr, ok := t.(string); ok {
  90. tagsArray = append(tagsArray, tagStr)
  91. } else {
  92. err := &GraphiteAnnotationError{"tag should be a string"}
  93. return ApiError(500, "Failed to save Graphite annotation", err)
  94. }
  95. }
  96. default:
  97. err := &GraphiteAnnotationError{"unsupported tags format"}
  98. return ApiError(500, "Failed to save Graphite annotation", err)
  99. }
  100. item := annotations.Item{
  101. OrgId: c.OrgId,
  102. UserId: c.UserId,
  103. Epoch: cmd.When,
  104. Text: text,
  105. Tags: tagsArray,
  106. }
  107. if err := repo.Save(&item); err != nil {
  108. return ApiError(500, "Failed to save Graphite annotation", err)
  109. }
  110. return ApiSuccess("Graphite Annotation added")
  111. }
  112. func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response {
  113. annotationId := c.ParamsInt64(":annotationId")
  114. repo := annotations.GetRepository()
  115. item := annotations.Item{
  116. OrgId: c.OrgId,
  117. UserId: c.UserId,
  118. Id: annotationId,
  119. Epoch: cmd.Time / 1000,
  120. Text: cmd.Text,
  121. Tags: cmd.Tags,
  122. }
  123. if err := repo.Update(&item); err != nil {
  124. return ApiError(500, "Failed to update annotation", err)
  125. }
  126. if cmd.IsRegion {
  127. itemRight := item
  128. itemRight.RegionId = item.Id
  129. itemRight.Epoch = cmd.TimeEnd / 1000
  130. // We don't know id of region right event, so set it to 0 and find then using query like
  131. // ... WHERE region_id = <item.RegionId> AND id != <item.RegionId> ...
  132. itemRight.Id = 0
  133. if err := repo.Update(&itemRight); err != nil {
  134. return ApiError(500, "Failed to update annotation for region end time", err)
  135. }
  136. }
  137. return ApiSuccess("Annotation updated")
  138. }
  139. func DeleteAnnotations(c *middleware.Context, cmd dtos.DeleteAnnotationsCmd) Response {
  140. repo := annotations.GetRepository()
  141. err := repo.Delete(&annotations.DeleteParams{
  142. AlertId: cmd.PanelId,
  143. DashboardId: cmd.DashboardId,
  144. PanelId: cmd.PanelId,
  145. })
  146. if err != nil {
  147. return ApiError(500, "Failed to delete annotations", err)
  148. }
  149. return ApiSuccess("Annotations deleted")
  150. }
  151. func DeleteAnnotationById(c *middleware.Context) Response {
  152. repo := annotations.GetRepository()
  153. annotationId := c.ParamsInt64(":annotationId")
  154. err := repo.Delete(&annotations.DeleteParams{
  155. Id: annotationId,
  156. })
  157. if err != nil {
  158. return ApiError(500, "Failed to delete annotation", err)
  159. }
  160. return ApiSuccess("Annotation deleted")
  161. }
  162. func DeleteAnnotationRegion(c *middleware.Context) Response {
  163. repo := annotations.GetRepository()
  164. regionId := c.ParamsInt64(":regionId")
  165. err := repo.Delete(&annotations.DeleteParams{
  166. RegionId: regionId,
  167. })
  168. if err != nil {
  169. return ApiError(500, "Failed to delete annotation region", err)
  170. }
  171. return ApiSuccess("Annotation region deleted")
  172. }