| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | package sqlstore | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-05-16 21:39:09 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-25 22:18:28 +08:00
										 |  |  | 	"github.com/go-xorm/xorm" | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							|  |  |  | 	m "github.com/grafana/grafana/pkg/models" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							|  |  |  | 	bus.AddHandler("sql", SaveAlerts) | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 	bus.AddHandler("sql", HandleAlertsQuery) | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | 	bus.AddHandler("sql", GetAlertById) | 
					
						
							| 
									
										
										
										
											2016-05-02 22:07:19 +08:00
										 |  |  | 	bus.AddHandler("sql", DeleteAlertById) | 
					
						
							| 
									
										
										
										
											2016-06-03 21:24:53 +08:00
										 |  |  | 	bus.AddHandler("sql", GetAllAlertQueryHandler) | 
					
						
							| 
									
										
										
										
											2016-07-22 19:14:09 +08:00
										 |  |  | 	bus.AddHandler("sql", SetAlertState) | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 14:23:50 +08:00
										 |  |  | func GetAlertById(query *m.GetAlertByIdQuery) error { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | 	alert := m.Alert{} | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | 	has, err := x.Id(query.Id).Get(&alert) | 
					
						
							|  |  |  | 	if !has { | 
					
						
							|  |  |  | 		return fmt.Errorf("could not find alert") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-28 16:59:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-06 19:50:47 +08:00
										 |  |  | 	query.Result = &alert | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 21:24:53 +08:00
										 |  |  | func GetAllAlertQueryHandler(query *m.GetAllAlertsQuery) error { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | 	var alerts []*m.Alert | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 	err := x.Sql("select * from alert").Find(&alerts) | 
					
						
							| 
									
										
										
										
											2016-06-03 21:24:53 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	query.Result = alerts | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-02 22:07:19 +08:00
										 |  |  | func DeleteAlertById(cmd *m.DeleteAlertCommand) error { | 
					
						
							|  |  |  | 	return inTransaction(func(sess *xorm.Session) error { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 		if _, err := sess.Exec("DELETE FROM alert WHERE id = ?", cmd.AlertId); err != nil { | 
					
						
							| 
									
										
										
										
											2016-05-02 22:07:19 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | func HandleAlertsQuery(query *m.GetAlertsQuery) error { | 
					
						
							|  |  |  | 	var sql bytes.Buffer | 
					
						
							|  |  |  | 	params := make([]interface{}, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sql.WriteString(`SELECT * | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 						from alert | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 						`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sql.WriteString(`WHERE org_id = ?`) | 
					
						
							|  |  |  | 	params = append(params, query.OrgId) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-10 15:45:56 +08:00
										 |  |  | 	if query.DashboardId != 0 { | 
					
						
							|  |  |  | 		sql.WriteString(` AND dashboard_id = ?`) | 
					
						
							|  |  |  | 		params = append(params, query.DashboardId) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if query.PanelId != 0 { | 
					
						
							|  |  |  | 		sql.WriteString(` AND panel_id = ?`) | 
					
						
							|  |  |  | 		params = append(params, query.PanelId) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 17:00:00 +08:00
										 |  |  | 	if len(query.State) > 0 && query.State[0] != "ALL" { | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 		sql.WriteString(` AND (`) | 
					
						
							|  |  |  | 		for i, v := range query.State { | 
					
						
							|  |  |  | 			if i > 0 { | 
					
						
							|  |  |  | 				sql.WriteString(" OR ") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			sql.WriteString("state = ? ") | 
					
						
							| 
									
										
										
										
											2016-08-17 17:00:00 +08:00
										 |  |  | 			params = append(params, v) | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		sql.WriteString(")") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-14 14:36:44 +08:00
										 |  |  | 	if query.Limit != 0 { | 
					
						
							|  |  |  | 		sql.WriteString(" LIMIT ?") | 
					
						
							|  |  |  | 		params = append(params, query.Limit) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 14:07:14 +08:00
										 |  |  | 	sql.WriteString(" ORDER BY name ASC") | 
					
						
							| 
									
										
										
										
											2016-09-14 20:51:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | 	alerts := make([]*m.Alert, 0) | 
					
						
							| 
									
										
										
										
											2016-05-09 20:30:28 +08:00
										 |  |  | 	if err := x.Sql(sql.String(), params...).Find(&alerts); err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-26 23:36:50 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	query.Result = alerts | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | func DeleteAlertDefinition(dashboardId int64, sess *xorm.Session) error { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 	alerts := make([]*m.Alert, 0) | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	sess.Where("dashboard_id = ?", dashboardId).Find(&alerts) | 
					
						
							| 
									
										
										
										
											2016-04-25 22:18:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	for _, alert := range alerts { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 		_, err := sess.Exec("DELETE FROM alert WHERE id = ? ", alert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-25 22:18:28 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 		sqlog.Debug("Alert deleted (due to dashboard deletion)", "name", alert.Name, "id", alert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | func SaveAlerts(cmd *m.SaveAlertsCommand) error { | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	return inTransaction(func(sess *xorm.Session) error { | 
					
						
							| 
									
										
										
										
											2016-07-14 19:32:16 +08:00
										 |  |  | 		existingAlerts, err := GetAlertsByDashboardId2(cmd.DashboardId, sess) | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-22 22:51:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-14 19:32:16 +08:00
										 |  |  | 		if err := upsertAlerts(existingAlerts, cmd, sess); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if err := deleteMissingAlerts(existingAlerts, cmd, sess); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-22 22:51:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-14 19:32:16 +08:00
										 |  |  | func upsertAlerts(existingAlerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *xorm.Session) error { | 
					
						
							| 
									
										
										
										
											2016-06-29 05:40:58 +08:00
										 |  |  | 	for _, alert := range cmd.Alerts { | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 		update := false | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | 		var alertToUpdate *m.Alert | 
					
						
							| 
									
										
										
										
											2016-04-25 22:18:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-14 19:32:16 +08:00
										 |  |  | 		for _, k := range existingAlerts { | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			if alert.PanelId == k.PanelId { | 
					
						
							|  |  |  | 				update = true | 
					
						
							|  |  |  | 				alert.Id = k.Id | 
					
						
							|  |  |  | 				alertToUpdate = k | 
					
						
							| 
									
										
										
										
											2016-06-11 20:08:55 +08:00
										 |  |  | 				break | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 		if update { | 
					
						
							| 
									
										
										
										
											2016-06-10 04:21:28 +08:00
										 |  |  | 			if alertToUpdate.ContainsUpdates(alert) { | 
					
						
							| 
									
										
										
										
											2016-05-16 21:39:09 +08:00
										 |  |  | 				alert.Updated = time.Now() | 
					
						
							| 
									
										
										
										
											2016-04-28 14:42:51 +08:00
										 |  |  | 				alert.State = alertToUpdate.State | 
					
						
							| 
									
										
										
										
											2016-06-06 19:50:47 +08:00
										 |  |  | 				_, err := sess.Id(alert.Id).Update(alert) | 
					
						
							| 
									
										
										
										
											2016-04-25 22:18:28 +08:00
										 |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return err | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 				sqlog.Debug("Alert updated", "name", alert.Name, "id", alert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-05-16 21:39:09 +08:00
										 |  |  | 			alert.Updated = time.Now() | 
					
						
							|  |  |  | 			alert.Created = time.Now() | 
					
						
							| 
									
										
										
										
											2016-09-13 21:09:55 +08:00
										 |  |  | 			alert.State = m.AlertStateNoData | 
					
						
							| 
									
										
										
										
											2016-08-16 22:50:36 +08:00
										 |  |  | 			alert.NewStateDate = time.Now() | 
					
						
							| 
									
										
										
										
											2016-07-14 19:32:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-06 19:50:47 +08:00
										 |  |  | 			_, err := sess.Insert(alert) | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							| 
									
										
										
										
											2016-04-22 22:51:24 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			sqlog.Debug("Alert inserted", "name", alert.Name, "id", alert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 05:40:58 +08:00
										 |  |  | func deleteMissingAlerts(alerts []*m.Alert, cmd *m.SaveAlertsCommand, sess *xorm.Session) error { | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 	for _, missingAlert := range alerts { | 
					
						
							|  |  |  | 		missing := true | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-29 05:40:58 +08:00
										 |  |  | 		for _, k := range cmd.Alerts { | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			if missingAlert.PanelId == k.PanelId { | 
					
						
							|  |  |  | 				missing = false | 
					
						
							| 
									
										
										
										
											2016-06-11 20:08:55 +08:00
										 |  |  | 				break | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 		if missing { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 			_, err := sess.Exec("DELETE FROM alert WHERE id = ?", missingAlert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 16:54:24 +08:00
										 |  |  | 			sqlog.Debug("Alert deleted", "name", missingAlert.Name, "id", missingAlert.Id) | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 22:31:13 +08:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | func GetAlertsByDashboardId2(dashboardId int64, sess *xorm.Session) ([]*m.Alert, error) { | 
					
						
							|  |  |  | 	alerts := make([]*m.Alert, 0) | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	err := sess.Where("dashboard_id = ?", dashboardId).Find(&alerts) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-06-11 16:26:48 +08:00
										 |  |  | 		return []*m.Alert{}, err | 
					
						
							| 
									
										
										
										
											2016-04-22 23:49:50 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 21:48:29 +08:00
										 |  |  | 	return alerts, nil | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-22 19:14:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func SetAlertState(cmd *m.SetAlertStateCommand) error { | 
					
						
							|  |  |  | 	return inTransaction(func(sess *xorm.Session) error { | 
					
						
							|  |  |  | 		alert := m.Alert{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if has, err := sess.Id(cmd.AlertId).Get(&alert); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} else if !has { | 
					
						
							|  |  |  | 			return fmt.Errorf("Could not find alert") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		alert.State = cmd.State | 
					
						
							| 
									
										
										
										
											2016-08-16 15:52:45 +08:00
										 |  |  | 		alert.StateChanges += 1 | 
					
						
							|  |  |  | 		alert.NewStateDate = time.Now() | 
					
						
							| 
									
										
										
										
											2016-09-14 20:35:05 +08:00
										 |  |  | 		alert.EvalData = cmd.EvalData | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-18 23:25:32 +08:00
										 |  |  | 		if cmd.Error == "" { | 
					
						
							|  |  |  | 			alert.ExecutionError = " " //without this space, xorm skips updating this field
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			alert.ExecutionError = cmd.Error | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-22 19:14:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-16 15:52:45 +08:00
										 |  |  | 		sess.Id(alert.Id).Update(&alert) | 
					
						
							| 
									
										
										
										
											2016-07-22 19:14:09 +08:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } |