Files
grafana/pkg/registry/apps/alerting/historian/handlers.go
Steve Simpson eafc8ab1cd Alerting: Foundations of historian app. (#114463)
We have two historians in alerting - alert state and notification. The intention
of this app is to provide query capabilities for both.

In this initial commit, the existing /history API is simply cloned to the new
app. It is identical except that it will send Kubernetes-style error responses
instead of Grafana-style.

This approach was taken to implement the new app more iteratively - ideally we
would define a new API, but this requires quite a significant overhaul of the
backend code.
2025-11-28 11:51:56 +01:00

61 lines
1.6 KiB
Go

package historian
import (
"context"
"encoding/json"
"net/http"
"github.com/grafana/grafana-app-sdk/app"
"github.com/grafana/grafana-plugin-sdk-go/data"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/ngalert/api"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
type Historian interface {
Query(ctx context.Context, query models.HistoryQuery) (*data.Frame, error)
}
type handlers struct {
historian Historian
}
func (h handlers) GetAlertStateHistoryHandler(ctx context.Context, writer app.CustomRouteResponseWriter, request *app.CustomRouteRequest) error {
user, err := identity.GetRequester(ctx)
if err != nil {
return &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusUnauthorized,
Message: "authentication required",
}}
}
query, err := api.ParseHistoryQuery(user.GetOrgID(), user, request.URL.Query())
if err != nil {
return &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusBadRequest,
Message: err.Error(),
}}
}
frame, err := h.historian.Query(ctx, query)
if err != nil {
return &apierrors.StatusError{
ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusInternalServerError,
Message: err.Error(),
}}
}
writer.Header().Add("Content-Type", "application/json")
writer.WriteHeader(http.StatusOK)
return json.NewEncoder(writer).Encode(frame)
}