Merge branch 'master' of github.com:grafana/grafana
This commit is contained in:
@@ -184,5 +184,6 @@ func validateToValue(to string) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot parse to value %s", to)
|
||||
_, err := time.ParseDuration(to)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -93,14 +93,18 @@ func (e *Engine) executeJob(job *Job) {
|
||||
}
|
||||
|
||||
func (e *Engine) resultDispatcher() {
|
||||
for result := range e.resultQueue {
|
||||
go e.handleResponse(result)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Engine) handleResponse(result *EvalContext) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
e.log.Error("Panic in resultDispatcher", "error", err, "stack", log.Stack(1))
|
||||
}
|
||||
}()
|
||||
|
||||
for result := range e.resultQueue {
|
||||
e.log.Debug("Alert Rule Result", "ruleId", result.Rule.Id, "firing", result.Firing)
|
||||
e.resultHandler.Handle(result)
|
||||
}
|
||||
e.log.Debug("Alert Rule Result", "ruleId", result.Rule.Id, "firing", result.Firing)
|
||||
e.resultHandler.Handle(result)
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (c *EvalContext) GetNotificationTitle() string {
|
||||
return "[" + c.GetStateModel().Text + "] " + c.Rule.Name
|
||||
}
|
||||
|
||||
func (c *EvalContext) getDashboardSlug() (string, error) {
|
||||
func (c *EvalContext) GetDashboardSlug() (string, error) {
|
||||
if c.dashboardSlug != "" {
|
||||
return c.dashboardSlug, nil
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func (c *EvalContext) getDashboardSlug() (string, error) {
|
||||
}
|
||||
|
||||
func (c *EvalContext) GetRuleUrl() (string, error) {
|
||||
if slug, err := c.getDashboardSlug(); err != nil {
|
||||
if slug, err := c.GetDashboardSlug(); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
ruleUrl := fmt.Sprintf("%sdashboard/db/%s?fullscreen&edit&tab=alert&panelId=%d", setting.AppUrl, slug, c.Rule.PanelId)
|
||||
@@ -94,15 +94,6 @@ func (c *EvalContext) GetRuleUrl() (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *EvalContext) GetImageUrl() (string, error) {
|
||||
if slug, err := c.getDashboardSlug(); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
ruleUrl := fmt.Sprintf("%sdashboard-solo/db/%s?&panelId=%d", setting.AppUrl, slug, c.Rule.PanelId)
|
||||
return ruleUrl, nil
|
||||
}
|
||||
}
|
||||
|
||||
func NewEvalContext(rule *Rule) *EvalContext {
|
||||
return &EvalContext{
|
||||
StartTime: time.Now(),
|
||||
|
||||
@@ -20,7 +20,7 @@ type DefaultEvalHandler struct {
|
||||
func NewEvalHandler() *DefaultEvalHandler {
|
||||
return &DefaultEvalHandler{
|
||||
log: log.New("alerting.evalHandler"),
|
||||
alertJobTimeout: time.Second * 10,
|
||||
alertJobTimeout: time.Second * 15,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package alerting
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/imguploader"
|
||||
@@ -60,22 +61,22 @@ func (n *RootNotifier) sendNotifications(notifiers []Notifier, context *EvalCont
|
||||
}
|
||||
}
|
||||
|
||||
func (n *RootNotifier) uploadImage(context *EvalContext) error {
|
||||
func (n *RootNotifier) uploadImage(context *EvalContext) (err error) {
|
||||
uploader, _ := imguploader.NewImageUploader()
|
||||
|
||||
imageUrl, err := context.GetImageUrl()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
renderOpts := &renderer.RenderOpts{
|
||||
Url: imageUrl,
|
||||
Width: "800",
|
||||
Height: "400",
|
||||
Timeout: "30",
|
||||
OrgId: context.Rule.OrgId,
|
||||
}
|
||||
|
||||
if slug, err := context.GetDashboardSlug(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
renderOpts.Path = fmt.Sprintf("dashboard-solo/db/%s?&panelId=%d", slug, context.Rule.PanelId)
|
||||
}
|
||||
|
||||
if imagePath, err := renderer.RenderToPng(renderOpts); err != nil {
|
||||
return err
|
||||
} else {
|
||||
|
||||
@@ -52,9 +52,8 @@ func (this *WebhookNotifier) Notify(context *alerting.EvalContext) {
|
||||
bodyJSON.Set("rule_url", ruleUrl)
|
||||
}
|
||||
|
||||
imageUrl, err := context.GetImageUrl()
|
||||
if err == nil {
|
||||
bodyJSON.Set("image_url", imageUrl)
|
||||
if context.ImagePublicUrl != "" {
|
||||
bodyJSON.Set("image_url", context.ImagePublicUrl)
|
||||
}
|
||||
|
||||
body, _ := bodyJSON.MarshalJSON()
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//"I want to be a cleaner, just like you," said Mathilda
|
||||
//"Okay," replied Leon
|
||||
|
||||
package backgroundtasks
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
var (
|
||||
tlog log.Logger = log.New("ticker")
|
||||
)
|
||||
|
||||
func Init() {
|
||||
go start()
|
||||
}
|
||||
|
||||
func start() {
|
||||
go cleanup(time.Now())
|
||||
|
||||
ticker := time.NewTicker(time.Hour * 1)
|
||||
for {
|
||||
select {
|
||||
case tick := <-ticker.C:
|
||||
go cleanup(tick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cleanup(now time.Time) {
|
||||
err := bus.Publish(&models.HourCommand{Time: now})
|
||||
if err != nil {
|
||||
tlog.Error("Cleanup job failed", "error", err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package backgroundtasks
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddEventListener(CleanTmpFiles)
|
||||
}
|
||||
|
||||
func CleanTmpFiles(cmd *models.HourCommand) error {
|
||||
files, err := ioutil.ReadDir(setting.ImagesDir)
|
||||
|
||||
var toDelete []os.FileInfo
|
||||
for _, file := range files {
|
||||
if file.ModTime().AddDate(0, 0, setting.RenderedImageTTLDays).Before(cmd.Time) {
|
||||
toDelete = append(toDelete, file)
|
||||
}
|
||||
}
|
||||
|
||||
for _, file := range toDelete {
|
||||
fullPath := path.Join(setting.ImagesDir, file.Name())
|
||||
err := os.Remove(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tlog.Debug("Found old rendered image to delete", "deleted", len(toDelete), "keept", len(files))
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -13,6 +15,31 @@ func init() {
|
||||
bus.AddHandler("sql", GetDashboardSnapshot)
|
||||
bus.AddHandler("sql", DeleteDashboardSnapshot)
|
||||
bus.AddHandler("sql", SearchDashboardSnapshots)
|
||||
bus.AddEventListener(DeleteExpiredSnapshots)
|
||||
}
|
||||
|
||||
func DeleteExpiredSnapshots(cmd *m.HourCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
var expiredCount int64 = 0
|
||||
var oldCount int64 = 0
|
||||
|
||||
if setting.SnapShotRemoveExpired {
|
||||
deleteExpiredSql := "DELETE FROM dashboard_snapshot WHERE expires < ?"
|
||||
expiredResponse, err := x.Exec(deleteExpiredSql, cmd.Time)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
expiredCount, _ = expiredResponse.RowsAffected()
|
||||
}
|
||||
|
||||
oldSnapshotsSql := "DELETE FROM dashboard_snapshot WHERE created < ?"
|
||||
oldResponse, err := x.Exec(oldSnapshotsSql, cmd.Time.AddDate(0, 0, setting.SnapShotTTLDays*-1))
|
||||
oldCount, _ = oldResponse.RowsAffected()
|
||||
|
||||
log.Debug2("Deleted old/expired snaphots", "to old", oldCount, "expired", expiredCount)
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func CreateDashboardSnapshot(cmd *m.CreateDashboardSnapshotCommand) error {
|
||||
|
||||
Reference in New Issue
Block a user