Merge branch 'master' into alerting_opentsdb

This commit is contained in:
bergquist
2016-10-19 13:15:22 +02:00
41 changed files with 1029 additions and 829 deletions
+1 -1
View File
@@ -252,7 +252,7 @@ func NotificationTest(c *middleware.Context, dto dtos.NotificationTestCommand) R
return ApiSuccess("Test notification sent")
}
//POST /api/:alertId/pause
//POST /api/alerts/:alertId/pause
func PauseAlert(c *middleware.Context, dto dtos.PauseAlertCommand) Response {
cmd := models.PauseAlertCommand{
OrgId: c.OrgId,
+16
View File
@@ -44,3 +44,19 @@ func GetAnnotations(c *middleware.Context) Response {
return Json(200, result)
}
func DeleteAnnotations(c *middleware.Context, cmd dtos.DeleteAnnotationsCmd) Response {
repo := annotations.GetRepository()
err := repo.Delete(&annotations.DeleteParams{
AlertId: cmd.PanelId,
DashboardId: cmd.DashboardId,
PanelId: cmd.PanelId,
})
if err != nil {
return ApiError(500, "Failed to delete annotations", err)
}
return ApiSuccess("Annotations deleted")
}
+3 -2
View File
@@ -252,7 +252,7 @@ func Register(r *macaron.Macaron) {
r.Group("/alerts", func() {
r.Post("/test", bind(dtos.AlertTestCommand{}), wrap(AlertTest))
r.Post("/:alertId/pause", ValidateOrgAlert, bind(dtos.PauseAlertCommand{}), wrap(PauseAlert))
r.Post("/:alertId/pause", bind(dtos.PauseAlertCommand{}), wrap(PauseAlert), reqEditorRole)
r.Get("/:alertId", ValidateOrgAlert, wrap(GetAlert))
r.Get("/", wrap(GetAlerts))
r.Get("/states-for-dashboard", wrap(GetAlertStatesForDashboard))
@@ -266,9 +266,10 @@ func Register(r *macaron.Macaron) {
r.Put("/:notificationId", bind(m.UpdateAlertNotificationCommand{}), wrap(UpdateAlertNotification))
r.Get("/:notificationId", wrap(GetAlertNotificationById))
r.Delete("/:notificationId", wrap(DeleteAlertNotification))
}, reqOrgAdmin)
}, reqEditorRole)
r.Get("/annotations", wrap(GetAnnotations))
r.Post("/annotations/mass-delete", reqOrgAdmin, bind(dtos.DeleteAnnotationsCmd{}), wrap(DeleteAnnotations))
// error test
r.Get("/metrics/error", wrap(GenerateError))
+6
View File
@@ -15,3 +15,9 @@ type Annotation struct {
Data *simplejson.Json `json:"data"`
}
type DeleteAnnotationsCmd struct {
AlertId int64 `json:"alertId"`
DashboardId int64 `json:"dashboardId"`
PanelId int64 `json:"panelId"`
}
+2
View File
@@ -103,8 +103,10 @@ func writePIDFile() {
func listenToSystemSignals(server models.GrafanaServer) {
signalChan := make(chan os.Signal, 1)
ignoreChan := make(chan os.Signal, 1)
code := 0
signal.Notify(ignoreChan, syscall.SIGHUP)
signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGTERM)
select {
+10 -8
View File
@@ -17,17 +17,19 @@ type SendEmailCommandSync struct {
}
type SendWebhook struct {
Url string
User string
Password string
Body string
Url string
User string
Password string
Body string
HttpMethod string
}
type SendWebhookSync struct {
Url string
User string
Password string
Body string
Url string
User string
Password string
Body string
HttpMethod string
}
type SendResetPasswordEmailCommand struct {
+11 -8
View File
@@ -24,16 +24,18 @@ func NewWebHookNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
Url: url,
User: model.Settings.Get("user").MustString(),
Password: model.Settings.Get("password").MustString(),
HttpMethod: model.Settings.Get("httpMethod").MustString("POST"),
log: log.New("alerting.notifier.webhook"),
}, nil
}
type WebhookNotifier struct {
NotifierBase
Url string
User string
Password string
log log.Logger
Url string
User string
Password string
HttpMethod string
log log.Logger
}
func (this *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error {
@@ -59,10 +61,11 @@ func (this *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error {
body, _ := bodyJSON.MarshalJSON()
cmd := &m.SendWebhookSync{
Url: this.Url,
User: this.User,
Password: this.Password,
Body: string(body),
Url: this.Url,
User: this.User,
Password: this.Password,
Body: string(body),
HttpMethod: this.HttpMethod,
}
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
+7
View File
@@ -5,6 +5,7 @@ import "github.com/grafana/grafana/pkg/components/simplejson"
type Repository interface {
Save(item *Item) error
Find(query *ItemQuery) ([]*Item, error)
Delete(params *DeleteParams) error
}
type ItemQuery struct {
@@ -20,6 +21,12 @@ type ItemQuery struct {
Limit int64 `json:"alertId"`
}
type DeleteParams struct {
AlertId int64 `json:"alertId"`
DashboardId int64 `json:"dashboardId"`
PanelId int64 `json:"panelId"`
}
var repositoryInstance Repository
func GetRepository() Repository {
+10 -8
View File
@@ -61,19 +61,21 @@ func Init() error {
func SendWebhookSync(ctx context.Context, cmd *m.SendWebhookSync) error {
return sendWebRequestSync(ctx, &Webhook{
Url: cmd.Url,
User: cmd.User,
Password: cmd.Password,
Body: cmd.Body,
Url: cmd.Url,
User: cmd.User,
Password: cmd.Password,
Body: cmd.Body,
HttpMethod: cmd.HttpMethod,
})
}
func sendWebhook(cmd *m.SendWebhook) error {
addToWebhookQueue(&Webhook{
Url: cmd.Url,
User: cmd.User,
Password: cmd.Password,
Body: cmd.Body,
Url: cmd.Url,
User: cmd.User,
Password: cmd.Password,
Body: cmd.Body,
HttpMethod: cmd.HttpMethod,
})
return nil
+11 -6
View File
@@ -15,10 +15,11 @@ import (
)
type Webhook struct {
Url string
User string
Password string
Body string
Url string
User string
Password string
Body string
HttpMethod string
}
var webhookQueue chan *Webhook
@@ -44,13 +45,17 @@ func processWebhookQueue() {
}
func sendWebRequestSync(ctx context.Context, webhook *Webhook) error {
webhookLog.Debug("Sending webhook", "url", webhook.Url)
webhookLog.Debug("Sending webhook", "url", webhook.Url, "http method", webhook.HttpMethod)
client := &http.Client{
Timeout: time.Duration(10 * time.Second),
}
request, err := http.NewRequest(http.MethodPost, webhook.Url, bytes.NewReader([]byte(webhook.Body)))
if webhook.HttpMethod == "" {
webhook.HttpMethod = http.MethodPost
}
request, err := http.NewRequest(webhook.HttpMethod, webhook.Url, bytes.NewReader([]byte(webhook.Body)))
if webhook.User != "" && webhook.Password != "" {
request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password))
}
+20 -18
View File
@@ -46,13 +46,23 @@ func GetAllAlertQueryHandler(query *m.GetAllAlertsQuery) error {
return nil
}
func deleteAlertByIdInternal(alertId int64, reason string, sess *xorm.Session) error {
sqlog.Debug("Deleting alert", "id", alertId, "reason", reason)
if _, err := sess.Exec("DELETE FROM alert WHERE id = ?", alertId); err != nil {
return err
}
if _, err := sess.Exec("DELETE FROM annotation WHERE alert_id = ?", alertId); err != nil {
return err
}
return nil
}
func DeleteAlertById(cmd *m.DeleteAlertCommand) error {
return inTransaction(func(sess *xorm.Session) error {
if _, err := sess.Exec("DELETE FROM alert WHERE id = ?", cmd.AlertId); err != nil {
return err
}
return nil
return deleteAlertByIdInternal(cmd.AlertId, "DeleteAlertCommand", sess)
})
}
@@ -110,12 +120,7 @@ func DeleteAlertDefinition(dashboardId int64, sess *xorm.Session) error {
sess.Where("dashboard_id = ?", dashboardId).Find(&alerts)
for _, alert := range alerts {
_, err := sess.Exec("DELETE FROM alert WHERE id = ? ", alert.Id)
if err != nil {
return err
}
sqlog.Debug("Alert deleted (due to dashboard deletion)", "name", alert.Name, "id", alert.Id)
deleteAlertByIdInternal(alert.Id, "Dashboard deleted", sess)
}
return nil
@@ -195,12 +200,7 @@ func deleteMissingAlerts(alerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *xorm
}
if missing {
_, err := sess.Exec("DELETE FROM alert WHERE id = ?", missingAlert.Id)
if err != nil {
return err
}
sqlog.Debug("Alert deleted", "name", missingAlert.Name, "id", missingAlert.Id)
deleteAlertByIdInternal(missingAlert.Id, "Removed from dashboard", sess)
}
}
@@ -248,7 +248,9 @@ func PauseAlertRule(cmd *m.PauseAlertCommand) error {
return inTransaction(func(sess *xorm.Session) error {
alert := m.Alert{}
if has, err := sess.Id(cmd.AlertId).Get(&alert); err != nil {
has, err := x.Where("id = ? AND org_id=?", cmd.AlertId, cmd.OrgId).Get(&alert)
if err != nil {
return err
} else if !has {
return fmt.Errorf("Could not find alert")
+14
View File
@@ -84,3 +84,17 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I
return items, nil
}
func (r *SqlAnnotationRepo) Delete(params *annotations.DeleteParams) error {
return inTransaction(func(sess *xorm.Session) error {
sql := "DELETE FROM annotation WHERE dashboard_id = ? AND panel_id = ?"
_, err := sess.Exec(sql, params.DashboardId, params.PanelId)
if err != nil {
return err
}
return nil
})
}
+1
View File
@@ -46,5 +46,6 @@ func (s *SocialGoogle) UserInfo(client *http.Client) (*BasicUserInfo, error) {
return &BasicUserInfo{
Name: data.Name,
Email: data.Email,
Login: data.Email,
}, nil
}
+5
View File
@@ -124,10 +124,15 @@ func (e *InfluxDBExecutor) createRequest(query string) (*http.Request, error) {
req.URL.RawQuery = params.Encode()
req.Header.Set("User-Agent", "Grafana")
if e.BasicAuth {
req.SetBasicAuth(e.BasicAuthUser, e.BasicAuthPassword)
}
if e.User != "" {
req.SetBasicAuth(e.User, e.Password)
}
glog.Debug("Influxdb request", "url", req.URL.String())
return req, nil
}
+4 -2
View File
@@ -84,8 +84,10 @@ func formatLegend(metric pmodel.Metric, query *PrometheusQuery) string {
reg, _ := regexp.Compile(`\{\{\s*(.+?)\s*\}\}`)
result := reg.ReplaceAllFunc([]byte(query.LegendFormat), func(in []byte) []byte {
ind := strings.Replace(strings.Replace(string(in), "{{", "", 1), "}}", "", 1)
if val, exists := metric[pmodel.LabelName(ind)]; exists {
labelName := strings.Replace(string(in), "{{", "", 1)
labelName = strings.Replace(labelName, "}}", "", 1)
labelName = strings.TrimSpace(labelName)
if val, exists := metric[pmodel.LabelName(labelName)]; exists {
return []byte(val)
}
+1 -1
View File
@@ -17,7 +17,7 @@ func TestPrometheus(t *testing.T) {
}
query := &PrometheusQuery{
LegendFormat: "legend {{app}} {{device}} {{broken}}",
LegendFormat: "legend {{app}} {{ device }} {{broken}}",
}
So(formatLegend(metric, query), ShouldEqual, "legend backend mobile {{broken}}")