Prometheus: Refactor error handling logic (#62254)

* Refactor error handling logic
- Enable query inspector to show error information
- Update naming

* Change fetch method return signature

* update the snapshot

* Revert "update the snapshot"

This reverts commit 28b26ce426.
pull/56097/head
ismail simsek 2 years ago committed by GitHub
parent 4186871390
commit 49258b135a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 55
      pkg/tsdb/prometheus/querydata/request.go
  2. 15
      pkg/tsdb/prometheus/querydata/response.go

@ -97,10 +97,7 @@ func (s *QueryData) Execute(ctx context.Context, req *backend.QueryDataRequest)
if err != nil { if err != nil {
return &result, err return &result, err
} }
r, err := s.fetch(ctx, s.client, query, req.Headers) r := s.fetch(ctx, s.client, query, req.Headers)
if err != nil {
return &result, err
}
if r == nil { if r == nil {
s.log.FromContext(ctx).Debug("Received nilresponse from runQuery", "query", query.Expr) s.log.FromContext(ctx).Debug("Received nilresponse from runQuery", "query", query.Expr)
continue continue
@ -111,69 +108,75 @@ func (s *QueryData) Execute(ctx context.Context, req *backend.QueryDataRequest)
return &result, nil return &result, nil
} }
func (s *QueryData) fetch(ctx context.Context, client *client.Client, q *models.Query, headers map[string]string) (*backend.DataResponse, error) { func (s *QueryData) fetch(ctx context.Context, client *client.Client, q *models.Query, headers map[string]string) *backend.DataResponse {
traceCtx, end := s.trace(ctx, q) traceCtx, end := s.trace(ctx, q)
defer end() defer end()
logger := s.log.FromContext(traceCtx) logger := s.log.FromContext(traceCtx)
logger.Debug("Sending query", "start", q.Start, "end", q.End, "step", q.Step, "query", q.Expr) logger.Debug("Sending query", "start", q.Start, "end", q.End, "step", q.Step, "query", q.Expr)
response := &backend.DataResponse{ dr := &backend.DataResponse{
Frames: data.Frames{}, Frames: data.Frames{},
Error: nil, Error: nil,
} }
if q.InstantQuery { if q.InstantQuery {
res, err := s.instantQuery(traceCtx, client, q, headers) res := s.instantQuery(traceCtx, client, q, headers)
response.Error = err dr.Error = res.Error
response.Frames = res.Frames dr.Frames = res.Frames
} }
if q.RangeQuery { if q.RangeQuery {
res, err := s.rangeQuery(traceCtx, client, q, headers) res := s.rangeQuery(traceCtx, client, q, headers)
if err != nil { if res.Error != nil {
if response.Error == nil { if dr.Error == nil {
response.Error = err dr.Error = res.Error
} else { } else {
response.Error = fmt.Errorf("%v %w", response.Error, err) dr.Error = fmt.Errorf("%v %w", dr.Error, res.Error)
} }
} }
response.Frames = append(response.Frames, res.Frames...) dr.Frames = append(dr.Frames, res.Frames...)
} }
if q.ExemplarQuery { if q.ExemplarQuery {
res, err := s.exemplarQuery(traceCtx, client, q, headers) res := s.exemplarQuery(traceCtx, client, q, headers)
if err != nil { if res.Error != nil {
// If exemplar query returns error, we want to only log it and // If exemplar query returns error, we want to only log it and
// continue with other results processing // continue with other results processing
logger.Error("Exemplar query failed", "query", q.Expr, "err", err) logger.Error("Exemplar query failed", "query", q.Expr, "err", res.Error)
} }
response.Frames = append(response.Frames, res.Frames...) dr.Frames = append(dr.Frames, res.Frames...)
} }
return response, nil return dr
} }
func (s *QueryData) rangeQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) { func (s *QueryData) rangeQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
res, err := c.QueryRange(ctx, q) res, err := c.QueryRange(ctx, q)
if err != nil { if err != nil {
return backend.DataResponse{}, err return backend.DataResponse{
Error: err,
}
} }
return s.parseResponse(ctx, q, res) return s.parseResponse(ctx, q, res)
} }
func (s *QueryData) instantQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) { func (s *QueryData) instantQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
res, err := c.QueryInstant(ctx, q) res, err := c.QueryInstant(ctx, q)
if err != nil { if err != nil {
return backend.DataResponse{}, err return backend.DataResponse{
Error: err,
}
} }
return s.parseResponse(ctx, q, res) return s.parseResponse(ctx, q, res)
} }
func (s *QueryData) exemplarQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) { func (s *QueryData) exemplarQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
res, err := c.QueryExemplars(ctx, q) res, err := c.QueryExemplars(ctx, q)
if err != nil { if err != nil {
return backend.DataResponse{}, err return backend.DataResponse{
Error: err,
}
} }
return s.parseResponse(ctx, q, res) return s.parseResponse(ctx, q, res)
} }

@ -17,7 +17,7 @@ import (
"github.com/grafana/grafana/pkg/util/converter" "github.com/grafana/grafana/pkg/util/converter"
) )
func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *http.Response) (backend.DataResponse, error) { func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *http.Response) backend.DataResponse {
defer func() { defer func() {
if err := res.Body.Close(); err != nil { if err := res.Body.Close(); err != nil {
s.log.FromContext(ctx).Error("Failed to close response body", "err", err) s.log.FromContext(ctx).Error("Failed to close response body", "err", err)
@ -30,6 +30,12 @@ func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *htt
VectorWideSeries: s.enableWideSeries, VectorWideSeries: s.enableWideSeries,
}) })
// Add frame to attach metadata
if len(r.Frames) == 0 && !q.ExemplarQuery {
r.Frames = append(r.Frames, data.NewFrame(""))
}
// The ExecutedQueryString can be viewed in QueryInspector in UI
for _, frame := range r.Frames { for _, frame := range r.Frames {
if s.enableWideSeries { if s.enableWideSeries {
addMetadataToWideFrame(q, frame) addMetadataToWideFrame(q, frame)
@ -38,12 +44,11 @@ func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *htt
} }
} }
if r.Error != nil { if r.Error == nil {
return r, r.Error r = s.processExemplars(q, r)
} }
r = s.processExemplars(q, r) return r
return r, nil
} }
func (s *QueryData) processExemplars(q *models.Query, dr backend.DataResponse) backend.DataResponse { func (s *QueryData) processExemplars(q *models.Query, dr backend.DataResponse) backend.DataResponse {

Loading…
Cancel
Save