Commit 04ea7efa by Alexander Zobnin Committed by Torkel Ödegaard

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
parent 19a57f7c
package api package api
import ( import (
"fmt"
"strings"
"time"
"github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
...@@ -78,6 +82,60 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response ...@@ -78,6 +82,60 @@ func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response
return ApiSuccess("Annotation added") 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 { func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response {
annotationId := c.ParamsInt64(":annotationId") annotationId := c.ParamsInt64(":annotationId")
......
...@@ -292,6 +292,7 @@ func (hs *HttpServer) registerRoutes() { ...@@ -292,6 +292,7 @@ func (hs *HttpServer) registerRoutes() {
annotationsRoute.Delete("/:annotationId", wrap(DeleteAnnotationById)) annotationsRoute.Delete("/:annotationId", wrap(DeleteAnnotationById))
annotationsRoute.Put("/:annotationId", bind(dtos.UpdateAnnotationsCmd{}), wrap(UpdateAnnotation)) annotationsRoute.Put("/:annotationId", bind(dtos.UpdateAnnotationsCmd{}), wrap(UpdateAnnotation))
annotationsRoute.Delete("/region/:regionId", wrap(DeleteAnnotationRegion)) annotationsRoute.Delete("/region/:regionId", wrap(DeleteAnnotationRegion))
annotationsRoute.Post("/graphite", bind(dtos.PostGraphiteAnnotationsCmd{}), wrap(PostGraphiteAnnotation))
}, reqEditorRole) }, reqEditorRole)
// error test // error test
......
...@@ -29,3 +29,10 @@ type DeleteAnnotationsCmd struct { ...@@ -29,3 +29,10 @@ type DeleteAnnotationsCmd struct {
AnnotationId int64 `json:"annotationId"` AnnotationId int64 `json:"annotationId"`
RegionId int64 `json:"regionId"` RegionId int64 `json:"regionId"`
} }
type PostGraphiteAnnotationsCmd struct {
When int64 `json:"when"`
What string `json:"what"`
Data string `json:"data"`
Tags interface{} `json:"tags"`
}
...@@ -66,7 +66,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv, ...@@ -66,7 +66,7 @@ export function annotationTooltipDirective($sanitize, dashboardSrv, contextSrv,
tooltip += '<div class="graph-annotation__body">'; tooltip += '<div class="graph-annotation__body">';
if (text) { if (text) {
tooltip += '<div>' + sanitizeString(text).replace(/\n/g, '<br>') + '</div>'; tooltip += '<div>' + sanitizeString(text.replace(/\n/g, '<br>')) + '</div>';
} }
var tags = event.tags; var tags = event.tags;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment