2023-02-03 01:34:00 +08:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2025-09-03 23:47:03 +08:00
|
|
|
"fmt"
|
2023-02-03 01:34:00 +08:00
|
|
|
"net/http"
|
2023-02-03 06:52:08 +08:00
|
|
|
"strings"
|
2023-02-03 01:34:00 +08:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
2025-09-03 23:47:03 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
2023-02-03 01:34:00 +08:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Historian interface {
|
2023-03-18 01:41:18 +08:00
|
|
|
Query(ctx context.Context, query models.HistoryQuery) (*data.Frame, error)
|
2023-02-03 01:34:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type HistorySrv struct {
|
|
|
|
logger log.Logger
|
|
|
|
hist Historian
|
|
|
|
}
|
|
|
|
|
2023-02-03 06:52:08 +08:00
|
|
|
const labelQueryPrefix = "labels_"
|
|
|
|
|
2023-02-03 01:34:00 +08:00
|
|
|
func (srv *HistorySrv) RouteQueryStateHistory(c *contextmodel.ReqContext) response.Response {
|
|
|
|
from := c.QueryInt64("from")
|
|
|
|
to := c.QueryInt64("to")
|
2023-06-29 02:32:28 +08:00
|
|
|
limit := c.QueryInt("limit")
|
2023-02-03 06:52:08 +08:00
|
|
|
ruleUID := c.Query("ruleUID")
|
2023-07-25 12:46:46 +08:00
|
|
|
dashUID := c.Query("dashboardUID")
|
|
|
|
panelID := c.QueryInt64("panelID")
|
2023-02-03 06:52:08 +08:00
|
|
|
|
2025-09-03 23:47:03 +08:00
|
|
|
previous := c.Query("previous")
|
|
|
|
if previous != "" {
|
|
|
|
_, err := eval.ParseStateString(previous)
|
|
|
|
if err != nil {
|
|
|
|
return ErrResp(http.StatusBadRequest, fmt.Errorf("invalid previous state filter: %w", err), "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
current := c.Query("current")
|
|
|
|
if current != "" {
|
|
|
|
_, err := eval.ParseStateString(current)
|
|
|
|
if err != nil {
|
|
|
|
return ErrResp(http.StatusBadRequest, fmt.Errorf("invalid current state filter: %w", err), "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 06:52:08 +08:00
|
|
|
labels := make(map[string]string)
|
|
|
|
for k, v := range c.Req.URL.Query() {
|
|
|
|
if strings.HasPrefix(k, labelQueryPrefix) {
|
|
|
|
labels[k[len(labelQueryPrefix):]] = v[0]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 01:34:00 +08:00
|
|
|
query := models.HistoryQuery{
|
2023-02-03 06:52:08 +08:00
|
|
|
RuleUID: ruleUID,
|
2025-04-10 20:42:23 +08:00
|
|
|
OrgID: c.GetOrgID(),
|
2023-07-25 12:46:46 +08:00
|
|
|
DashboardUID: dashUID,
|
|
|
|
PanelID: panelID,
|
2025-09-03 23:47:03 +08:00
|
|
|
Previous: previous,
|
|
|
|
Current: current,
|
2023-02-03 01:34:00 +08:00
|
|
|
SignedInUser: c.SignedInUser,
|
|
|
|
From: time.Unix(from, 0),
|
|
|
|
To: time.Unix(to, 0),
|
2023-06-29 02:32:28 +08:00
|
|
|
Limit: limit,
|
2023-02-03 06:52:08 +08:00
|
|
|
Labels: labels,
|
2023-02-03 01:34:00 +08:00
|
|
|
}
|
2023-03-18 01:41:18 +08:00
|
|
|
frame, err := srv.hist.Query(c.Req.Context(), query)
|
2023-02-03 01:34:00 +08:00
|
|
|
if err != nil {
|
|
|
|
return ErrResp(http.StatusInternalServerError, err, "")
|
|
|
|
}
|
|
|
|
return response.JSON(http.StatusOK, frame)
|
|
|
|
}
|