Pyroscope: Add error source (#112645)
* set downstream errors in pyroscope * Update pkg/tsdb/grafana-pyroscope-datasource/instance.go Co-authored-by: Gareth <email@garethdawson.xyz> * Update pkg/tsdb/grafana-pyroscope-datasource/instance.go Co-authored-by: Gareth <email@garethdawson.xyz> * more error source --------- Co-authored-by: Gareth <email@garethdawson.xyz>
This commit is contained in:
@@ -93,7 +93,7 @@ func (d *PyroscopeDatasource) profileTypes(ctx context.Context, req *backend.Cal
|
||||
u, err := url.Parse(req.URL)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to parse URL", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamErrorf("URL could not be parsed: %w", err)
|
||||
}
|
||||
query := u.Query()
|
||||
|
||||
@@ -102,13 +102,13 @@ func (d *PyroscopeDatasource) profileTypes(ctx context.Context, req *backend.Cal
|
||||
start, err = strconv.ParseInt(query.Get("start"), 10, 64)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to parse start as int", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamError(fmt.Errorf("failed to parse start as int: %w", err))
|
||||
}
|
||||
|
||||
end, err = strconv.ParseInt(query.Get("end"), 10, 64)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to parse end as int", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamError(fmt.Errorf("failed to parse end as int: %w", err))
|
||||
}
|
||||
} else {
|
||||
// Make sure to pass a valid time range to the client as v2 will not work without it.
|
||||
@@ -140,7 +140,7 @@ func (d *PyroscopeDatasource) labelNames(ctx context.Context, req *backend.CallR
|
||||
u, err := url.Parse(req.URL)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to parse URL", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamError(fmt.Errorf("URL could not be parsed: %w", err))
|
||||
}
|
||||
query := u.Query()
|
||||
|
||||
@@ -150,13 +150,13 @@ func (d *PyroscopeDatasource) labelNames(ctx context.Context, req *backend.CallR
|
||||
matchers, err := parser.ParseMetricSelector(labelSelector)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Could not parse label selector", "error", err, "function", logEntrypoint())
|
||||
return fmt.Errorf("failed parsing label selector: %v", err)
|
||||
return backend.DownstreamError(fmt.Errorf("failed parsing label selector: %v", err))
|
||||
}
|
||||
|
||||
labelNames, err := d.client.LabelNames(ctx, labelSelector, start, end)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
return fmt.Errorf("error calling LabelNames: %v", err)
|
||||
return backend.DownstreamError(fmt.Errorf("error calling LabelNames: %v", err))
|
||||
}
|
||||
|
||||
finalLabels := make([]string, 0)
|
||||
@@ -194,7 +194,7 @@ func (d *PyroscopeDatasource) labelValues(ctx context.Context, req *backend.Call
|
||||
u, err := url.Parse(req.URL)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to parse URL", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamError(fmt.Errorf("URL could not be parsed: %w", err))
|
||||
}
|
||||
query := u.Query()
|
||||
|
||||
@@ -205,13 +205,13 @@ func (d *PyroscopeDatasource) labelValues(ctx context.Context, req *backend.Call
|
||||
res, err := d.client.LabelValues(ctx, label, query.Get("query"), start, end)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
return fmt.Errorf("error calling LabelValues: %v", err)
|
||||
return backend.DownstreamError(fmt.Errorf("error calling LabelValues: %v", err))
|
||||
}
|
||||
|
||||
data, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
ctxLogger.Error("Failed to marshal response", "error", err, "function", logEntrypoint())
|
||||
return err
|
||||
return backend.DownstreamErrorf("failed to marshall response: %w", err)
|
||||
}
|
||||
|
||||
err = sender.Send(&backend.CallResourceResponse{Body: data, Status: 200})
|
||||
@@ -299,8 +299,8 @@ func (d *PyroscopeDatasource) CheckHealth(ctx context.Context, _ *backend.CheckH
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SubscribeStream is called when a client wants to connect to a stream. This callback
|
||||
// allows sending the first message.
|
||||
// SubscribeStream is called when a client wants to connect to a stream.
|
||||
// This callback allows sending the first message.
|
||||
func (d *PyroscopeDatasource) SubscribeStream(_ context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
|
||||
logger.Debug("Subscribing stream called", "function", logEntrypoint())
|
||||
|
||||
@@ -314,8 +314,8 @@ func (d *PyroscopeDatasource) SubscribeStream(_ context.Context, req *backend.Su
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RunStream is called once for any open channel. Results are shared with everyone
|
||||
// subscribed to the same channel.
|
||||
// RunStream is called once for any open channel.
|
||||
// Results are shared with everyone subscribed to the same channel.
|
||||
func (d *PyroscopeDatasource) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
ctxLogger.Debug("Running stream", "path", req.Path, "function", logEntrypoint())
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1"
|
||||
|
||||
@@ -82,7 +83,7 @@ func (c *PyroscopeClient) ProfileTypes(ctx context.Context, start int64, end int
|
||||
logger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("received error from client while getting profile types: %w", err))
|
||||
}
|
||||
if res.Msg.ProfileTypes == nil {
|
||||
// Let's make sure we send at least empty array if we don't have any types
|
||||
@@ -117,7 +118,7 @@ func (c *PyroscopeClient) GetSeries(ctx context.Context, profileTypeID string, l
|
||||
logger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("received error from client while getting series: %w", err))
|
||||
}
|
||||
|
||||
series := make([]*Series, len(resp.Msg.Series))
|
||||
@@ -173,7 +174,7 @@ func (c *PyroscopeClient) GetProfile(ctx context.Context, profileTypeID, labelSe
|
||||
logger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("received error from client while getting profile: %w", err))
|
||||
}
|
||||
|
||||
if resp.Msg.Flamegraph == nil {
|
||||
@@ -181,7 +182,7 @@ func (c *PyroscopeClient) GetProfile(ctx context.Context, profileTypeID, labelSe
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return profileQuery(ctx, err, span, resp.Msg.Flamegraph, profileTypeID)
|
||||
return profileQuery(resp.Msg.Flamegraph, profileTypeID)
|
||||
}
|
||||
|
||||
func (c *PyroscopeClient) GetSpanProfile(ctx context.Context, profileTypeID, labelSelector string, spanSelector []string, start, end int64, maxNodes *int64) (*ProfileResponse, error) {
|
||||
@@ -202,7 +203,7 @@ func (c *PyroscopeClient) GetSpanProfile(ctx context.Context, profileTypeID, lab
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("received error from client while getting span profile: %w", err))
|
||||
}
|
||||
|
||||
if resp.Msg.Flamegraph == nil {
|
||||
@@ -210,10 +211,10 @@ func (c *PyroscopeClient) GetSpanProfile(ctx context.Context, profileTypeID, lab
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return profileQuery(ctx, err, span, resp.Msg.Flamegraph, profileTypeID)
|
||||
return profileQuery(resp.Msg.Flamegraph, profileTypeID)
|
||||
}
|
||||
|
||||
func profileQuery(ctx context.Context, err error, span trace.Span, flamegraph *querierv1.FlameGraph, profileTypeID string) (*ProfileResponse, error) {
|
||||
func profileQuery(flamegraph *querierv1.FlameGraph, profileTypeID string) (*ProfileResponse, error) {
|
||||
levels := make([]*Level, len(flamegraph.Levels))
|
||||
for i, level := range flamegraph.Levels {
|
||||
levels[i] = &Level{
|
||||
@@ -256,7 +257,7 @@ func (c *PyroscopeClient) LabelNames(ctx context.Context, labelSelector string,
|
||||
logger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, fmt.Errorf("error sending LabelNames request %v", err)
|
||||
return nil, backend.DownstreamError(fmt.Errorf("error sending LabelNames request %v", err))
|
||||
}
|
||||
|
||||
if resp.Msg.Names == nil {
|
||||
@@ -286,7 +287,7 @@ func (c *PyroscopeClient) LabelValues(ctx context.Context, label string, labelSe
|
||||
logger.Error("Received error from client", "error", err, "function", logEntrypoint())
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("received error from client while getting label values: %w", err))
|
||||
}
|
||||
if resp.Msg.Names == nil {
|
||||
return []string{}, nil
|
||||
|
||||
@@ -542,7 +542,7 @@ func seriesToDataFrames(resp *SeriesResponse, withAnnotations bool, stepDuration
|
||||
if len(annotations) > 0 {
|
||||
frame, err := annotation.CreateAnnotationFrame(annotations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, backend.DownstreamError(fmt.Errorf("error creating annotation frame: %w", err))
|
||||
}
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user