Bladeren bron

annotations: add endpoint for writing graphite-like events (#9495)

* annotations: add endpoint for writing graphite-like events

* annotations: fix new line handling in tooltip

* annotations: support tags in prior to Graphite 0.10.0 format
Alexander Zobnin 8 jaren geleden
bovenliggende
commit
04ea7efac9
4 gewijzigde bestanden met toevoegingen van 67 en 1 verwijderingen
  1. 58 0
      pkg/api/annotations.go
  2. 1 0
      pkg/api/api.go
  3. 7 0
      pkg/api/dtos/annotations.go
  4. 1 1
      public/app/features/annotations/annotation_tooltip.ts

+ 58 - 0
pkg/api/annotations.go

@@ -1,6 +1,10 @@
 package api
 
 import (
+	"fmt"
+	"strings"
+	"time"
+
 	"github.com/grafana/grafana/pkg/api/dtos"
 	"github.com/grafana/grafana/pkg/components/simplejson"
 	"github.com/grafana/grafana/pkg/middleware"
@@ -78,6 +82,60 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response
 	return ApiSuccess("Annotation added")
 }
 
+type GraphiteAnnotationError struct {
+	message string
+}
+
+func (e *GraphiteAnnotationError) Error() string {
+	return e.message
+}
+
+func formatGraphiteAnnotation(what string, data string) string {
+	return fmt.Sprintf("%s\n%s", what, data)
+}
+
+func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotationsCmd) Response {
+	repo := annotations.GetRepository()
+
+	if cmd.When == 0 {
+		cmd.When = time.Now().Unix()
+	}
+	text := formatGraphiteAnnotation(cmd.What, cmd.Data)
+
+	// Support tags in prior to Graphite 0.10.0 format (string of tags separated by space)
+	var tagsArray []string
+	switch tags := cmd.Tags.(type) {
+	case string:
+		tagsArray = strings.Split(tags, " ")
+	case []interface{}:
+		for _, t := range tags {
+			if tagStr, ok := t.(string); ok {
+				tagsArray = append(tagsArray, tagStr)
+			} else {
+				err := &GraphiteAnnotationError{"tag should be a string"}
+				return ApiError(500, "Failed to save Graphite annotation", err)
+			}
+		}
+	default:
+		err := &GraphiteAnnotationError{"unsupported tags format"}
+		return ApiError(500, "Failed to save Graphite annotation", err)
+	}
+
+	item := annotations.Item{
+		OrgId:  c.OrgId,
+		UserId: c.UserId,
+		Epoch:  cmd.When,
+		Text:   text,
+		Tags:   tagsArray,
+	}
+
+	if err := repo.Save(&item); err != nil {
+		return ApiError(500, "Failed to save Graphite annotation", err)
+	}
+
+	return ApiSuccess("Graphite Annotation added")
+}
+
 func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response {
 	annotationId := c.ParamsInt64(":annotationId")
 

+ 1 - 0
pkg/api/api.go

@@ -292,6 +292,7 @@ func (hs *HttpServer) registerRoutes() {
 			annotationsRoute.Delete("/:annotationId", wrap(DeleteAnnotationById))
 			annotationsRoute.Put("/:annotationId", bind(dtos.UpdateAnnotationsCmd{}), wrap(UpdateAnnotation))
 			annotationsRoute.Delete("/region/:regionId", wrap(DeleteAnnotationRegion))
+			annotationsRoute.Post("/graphite", bind(dtos.PostGraphiteAnnotationsCmd{}), wrap(PostGraphiteAnnotation))
 		}, reqEditorRole)
 
 		// error test

+ 7 - 0
pkg/api/dtos/annotations.go

@@ -29,3 +29,10 @@ type DeleteAnnotationsCmd struct {
 	AnnotationId int64 `json:"annotationId"`
 	RegionId     int64 `json:"regionId"`
 }
+
+type PostGraphiteAnnotationsCmd struct {
+	When int64       `json:"when"`
+	What string      `json:"what"`
+	Data string      `json:"data"`
+	Tags interface{} `json:"tags"`
+}

+ 1 - 1
public/app/features/annotations/annotation_tooltip.ts

@@ -66,7 +66,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
       tooltip += '<div class="graph-annotation__body">';
 
       if (text) {
-        tooltip += '<div>' + sanitizeString(text).replace(/\n/g, '<br>') + '</div>';
+        tooltip += '<div>' + sanitizeString(text.replace(/\n/g, '<br>')) + '</div>';
       }
 
       var tags = event.tags;