mirror of
https://github.com/grafana/grafana.git
synced 2024-11-24 09:50:29 -06:00
Alerting: Return cached alerts for prometheus/api/v1/alerts (#32654)
* Return cached alerts for prometheus/api/v1/alerts * Return not implemented for /prometheus/grafana/api/v1/rules * Set StartsAt for already alerting states * Fix tests
This commit is contained in:
parent
ec624aa1ef
commit
c0d83fc01e
@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||||
|
|
||||||
"github.com/go-macaron/binding"
|
"github.com/go-macaron/binding"
|
||||||
|
|
||||||
apimodels "github.com/grafana/alerting-api/pkg/api"
|
apimodels "github.com/grafana/alerting-api/pkg/api"
|
||||||
@ -47,6 +49,7 @@ type API struct {
|
|||||||
AlertingStore store.AlertingStore
|
AlertingStore store.AlertingStore
|
||||||
DataProxy *datasourceproxy.DatasourceProxyService
|
DataProxy *datasourceproxy.DatasourceProxyService
|
||||||
Alertmanager Alertmanager
|
Alertmanager Alertmanager
|
||||||
|
StateTracker *state.StateTracker
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterAPIEndpoints registers API handlers
|
// RegisterAPIEndpoints registers API handlers
|
||||||
@ -63,7 +66,7 @@ func (api *API) RegisterAPIEndpoints() {
|
|||||||
api.RegisterPrometheusApiEndpoints(NewForkedProm(
|
api.RegisterPrometheusApiEndpoints(NewForkedProm(
|
||||||
api.DatasourceCache,
|
api.DatasourceCache,
|
||||||
NewLotexProm(proxy, logger),
|
NewLotexProm(proxy, logger),
|
||||||
PrometheusApiMock{log: logger},
|
PrometheusSrv{log: logger, stateTracker: api.StateTracker},
|
||||||
))
|
))
|
||||||
api.RegisterRulerApiEndpoints(NewForkedRuler(
|
api.RegisterRulerApiEndpoints(NewForkedRuler(
|
||||||
api.DatasourceCache,
|
api.DatasourceCache,
|
||||||
|
44
pkg/services/ngalert/api/api_prometheus.go
Normal file
44
pkg/services/ngalert/api/api_prometheus.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
apimodels "github.com/grafana/alerting-api/pkg/api"
|
||||||
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PrometheusSrv struct {
|
||||||
|
log log.Logger
|
||||||
|
stateTracker *state.StateTracker
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv PrometheusSrv) RouteGetAlertStatuses(c *models.ReqContext) response.Response {
|
||||||
|
alertResponse := apimodels.AlertResponse{
|
||||||
|
DiscoveryBase: apimodels.DiscoveryBase{
|
||||||
|
Status: "success",
|
||||||
|
},
|
||||||
|
Data: apimodels.AlertDiscovery{
|
||||||
|
Alerts: []*apimodels.Alert{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, alertState := range srv.stateTracker.GetAll() {
|
||||||
|
startsAt := alertState.StartsAt
|
||||||
|
alertResponse.Data.Alerts = append(alertResponse.Data.Alerts, &apimodels.Alert{
|
||||||
|
Labels: map[string]string(alertState.Labels),
|
||||||
|
Annotations: map[string]string{}, //TODO: Once annotations are added to the evaluation result, set them here
|
||||||
|
State: alertState.State.String(),
|
||||||
|
ActiveAt: &startsAt,
|
||||||
|
Value: "", //TODO: once the result of the evaluation is added to the evaluation result, set it here
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return response.JSON(http.StatusOK, alertResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv PrometheusSrv) RouteGetRuleStatuses(c *models.ReqContext) response.Response {
|
||||||
|
recipient := c.Params(":Recipient")
|
||||||
|
srv.log.Info("RouteGetRuleStatuses: ", "Recipient", recipient)
|
||||||
|
return response.Error(http.StatusNotImplemented, "", nil)
|
||||||
|
}
|
@ -1,133 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
apimodels "github.com/grafana/alerting-api/pkg/api"
|
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PrometheusApiMock struct {
|
|
||||||
log log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mock PrometheusApiMock) RouteGetAlertStatuses(c *models.ReqContext) response.Response {
|
|
||||||
recipient := c.Params(":Recipient")
|
|
||||||
mock.log.Info("RouteGetAlertStatuses: ", "Recipient", recipient)
|
|
||||||
now := time.Now()
|
|
||||||
result := apimodels.AlertResponse{
|
|
||||||
Data: apimodels.AlertDiscovery{
|
|
||||||
Alerts: []*apimodels.Alert{
|
|
||||||
{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"label 1": "value 1",
|
|
||||||
"label 2": "value 2",
|
|
||||||
},
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"alert annotation 1": "value 1",
|
|
||||||
"alert annotation 2": "value 2",
|
|
||||||
},
|
|
||||||
State: "firing",
|
|
||||||
ActiveAt: &now,
|
|
||||||
Value: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"label 1-2": "value 1",
|
|
||||||
"label 2-2": "value 2",
|
|
||||||
},
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"alert annotation 1-2": "value 1",
|
|
||||||
"alert annotation 2-2": "value 2",
|
|
||||||
},
|
|
||||||
State: "inactive",
|
|
||||||
ActiveAt: &now,
|
|
||||||
Value: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return response.JSON(http.StatusOK, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mock PrometheusApiMock) RouteGetRuleStatuses(c *models.ReqContext) response.Response {
|
|
||||||
recipient := c.Params(":Recipient")
|
|
||||||
mock.log.Info("RouteGetRuleStatuses: ", "Recipient", recipient)
|
|
||||||
now := time.Now()
|
|
||||||
result := apimodels.RuleResponse{
|
|
||||||
Data: apimodels.RuleDiscovery{
|
|
||||||
RuleGroups: []*apimodels.RuleGroup{
|
|
||||||
{
|
|
||||||
Name: "group1",
|
|
||||||
Interval: 60,
|
|
||||||
LastEvaluation: now.Add(-time.Minute),
|
|
||||||
EvaluationTime: 1,
|
|
||||||
Rules: []apimodels.AlertingRule{
|
|
||||||
{
|
|
||||||
State: "firing",
|
|
||||||
Name: "rule 1-1",
|
|
||||||
Query: `{
|
|
||||||
"title": "rule 1-1",
|
|
||||||
"condition": "A",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"refId": "A",
|
|
||||||
"queryType": "",
|
|
||||||
"relativeTimeRange": {
|
|
||||||
"from": 18000,
|
|
||||||
"to": 10800
|
|
||||||
},
|
|
||||||
"model": {
|
|
||||||
"datasource": "__expr__",
|
|
||||||
"type": "math",
|
|
||||||
"expression": "2 + 2 > 1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no_data_state": "NoData",
|
|
||||||
"exec_err_state": "Alerting"
|
|
||||||
}`,
|
|
||||||
Duration: 600,
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"annotation 1": "value 1",
|
|
||||||
"annotation 2": "value 2",
|
|
||||||
},
|
|
||||||
Alerts: []*apimodels.Alert{
|
|
||||||
{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"label 1": "value 1",
|
|
||||||
"label 2": "value 2",
|
|
||||||
},
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"alert annotation 1": "value 1",
|
|
||||||
"alert annotation 2": "value 2",
|
|
||||||
},
|
|
||||||
State: "firing",
|
|
||||||
ActiveAt: &now,
|
|
||||||
Value: "",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Labels: map[string]string{
|
|
||||||
"label 1-2": "value 1",
|
|
||||||
"label 2-2": "value 2",
|
|
||||||
},
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"alert annotation 1-2": "value 1",
|
|
||||||
"alert annotation 2-2": "value 2",
|
|
||||||
},
|
|
||||||
State: "inactive",
|
|
||||||
ActiveAt: &now,
|
|
||||||
Value: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return response.JSON(http.StatusOK, result)
|
|
||||||
}
|
|
@ -85,6 +85,7 @@ func (ng *AlertNG) Init() error {
|
|||||||
RuleStore: store,
|
RuleStore: store,
|
||||||
AlertingStore: store,
|
AlertingStore: store,
|
||||||
Alertmanager: ng.Alertmanager,
|
Alertmanager: ng.Alertmanager,
|
||||||
|
StateTracker: ng.stateTracker,
|
||||||
}
|
}
|
||||||
api.RegisterAPIEndpoints()
|
api.RegisterAPIEndpoints()
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ func (st *StateTracker) getOrCreate(uid string, orgId int64, result eval.Result)
|
|||||||
State: result.State,
|
State: result.State,
|
||||||
Results: []StateEvaluation{},
|
Results: []StateEvaluation{},
|
||||||
}
|
}
|
||||||
|
if result.State == eval.Alerting {
|
||||||
|
newState.StartsAt = result.EvaluatedAt
|
||||||
|
}
|
||||||
st.stateCache.cacheMap[idString] = newState
|
st.stateCache.cacheMap[idString] = newState
|
||||||
return newState
|
return newState
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ func TestProcessEvalResults(t *testing.T) {
|
|||||||
{EvaluationTime: evaluationTime, EvaluationState: eval.Alerting},
|
{EvaluationTime: evaluationTime, EvaluationState: eval.Alerting},
|
||||||
{EvaluationTime: evaluationTime.Add(1 * time.Minute), EvaluationState: eval.Normal},
|
{EvaluationTime: evaluationTime.Add(1 * time.Minute), EvaluationState: eval.Normal},
|
||||||
},
|
},
|
||||||
StartsAt: time.Time{},
|
StartsAt: evaluationTime,
|
||||||
EndsAt: evaluationTime.Add(1 * time.Minute),
|
EndsAt: evaluationTime.Add(1 * time.Minute),
|
||||||
LastEvaluationTime: evaluationTime.Add(1 * time.Minute),
|
LastEvaluationTime: evaluationTime.Add(1 * time.Minute),
|
||||||
},
|
},
|
||||||
@ -172,7 +172,7 @@ func TestProcessEvalResults(t *testing.T) {
|
|||||||
{EvaluationTime: evaluationTime, EvaluationState: eval.Alerting},
|
{EvaluationTime: evaluationTime, EvaluationState: eval.Alerting},
|
||||||
{EvaluationTime: evaluationTime.Add(1 * time.Minute), EvaluationState: eval.Alerting},
|
{EvaluationTime: evaluationTime.Add(1 * time.Minute), EvaluationState: eval.Alerting},
|
||||||
},
|
},
|
||||||
StartsAt: time.Time{},
|
StartsAt: evaluationTime,
|
||||||
EndsAt: evaluationTime.Add(100 * time.Second),
|
EndsAt: evaluationTime.Add(100 * time.Second),
|
||||||
LastEvaluationTime: evaluationTime.Add(1 * time.Minute),
|
LastEvaluationTime: evaluationTime.Add(1 * time.Minute),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user