Added spans to parca datasource

This commit is contained in:
André Pereira
2023-10-11 14:59:51 +01:00
parent 873f0af6e3
commit ac4edd8850
4 changed files with 54 additions and 6 deletions
+9 -1
View File
@@ -9,6 +9,9 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/tracing"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// Make sure ParcaDatasource implements required interfaces. This is important to do
@@ -29,10 +32,11 @@ var (
// ParcaDatasource is a datasource for querying application performance profiles.
type ParcaDatasource struct {
client queryv1alpha1connect.QueryServiceClient
tracer tracing.Tracer
}
// NewParcaDatasource creates a new datasource instance.
func NewParcaDatasource(httpClientProvider httpclient.Provider, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
func NewParcaDatasource(httpClientProvider httpclient.Provider, settings backend.DataSourceInstanceSettings, tracer tracing.Tracer) (instancemgmt.Instance, error) {
opt, err := settings.HTTPClientOptions()
if err != nil {
return nil, err
@@ -44,6 +48,7 @@ func NewParcaDatasource(httpClientProvider httpclient.Provider, settings backend
return &ParcaDatasource{
client: queryv1alpha1connect.NewQueryServiceClient(httpClient, settings.URL, connect.WithGRPCWeb()),
tracer: tracer,
}, nil
}
@@ -56,6 +61,9 @@ func (d *ParcaDatasource) Dispose() {
func (d *ParcaDatasource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
logger.Debug("CallResource", "Path", req.Path, "Method", req.Method, "Body", req.Body)
ctx, span := d.tracer.Start(ctx, "datasource.parca.CallResource", trace.WithAttributes(attribute.String("path", req.Path), attribute.String("method", req.Method)))
defer span.End()
if req.Path == "profileTypes" {
return d.callProfileTypes(ctx, req, sender)
}
+12
View File
@@ -12,6 +12,9 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/tsdb/parca/kinds/dataquery"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -27,12 +30,17 @@ const (
// query processes single Parca query transforming the response to data.Frame packaged in DataResponse
func (d *ParcaDatasource) query(ctx context.Context, pCtx backend.PluginContext, query backend.DataQuery) backend.DataResponse {
ctx, span := d.tracer.Start(ctx, "datasource.parca.query", trace.WithAttributes(attribute.String("query_type", query.QueryType)))
defer span.End()
var qm queryModel
response := backend.DataResponse{}
err := json.Unmarshal(query.JSON, &qm)
if err != nil {
response.Error = err
span.RecordError(response.Error)
span.SetStatus(codes.Error, response.Error.Error())
return response
}
@@ -40,6 +48,8 @@ func (d *ParcaDatasource) query(ctx context.Context, pCtx backend.PluginContext,
seriesResp, err := d.client.QueryRange(ctx, makeMetricRequest(qm, query))
if err != nil {
response.Error = err
span.RecordError(response.Error)
span.SetStatus(codes.Error, response.Error.Error())
return response
}
response.Frames = append(response.Frames, seriesToDataFrame(seriesResp, qm.ProfileTypeId)...)
@@ -50,6 +60,8 @@ func (d *ParcaDatasource) query(ctx context.Context, pCtx backend.PluginContext,
resp, err := d.client.Query(ctx, makeProfileRequest(qm, query))
if err != nil {
response.Error = err
span.RecordError(response.Error)
span.SetStatus(codes.Error, response.Error.Error())
return response
}
frame := responseToDataFrames(resp)
+25
View File
@@ -9,6 +9,7 @@ import (
v1alpha1 "buf.build/gen/go/parca-dev/parca/protocolbuffers/go/parca/query/v1alpha1"
"github.com/bufbuild/connect-go"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"go.opentelemetry.io/otel/codes"
)
type ProfileType struct {
@@ -23,6 +24,8 @@ type ProfileType struct {
}
func (d *ParcaDatasource) callProfileTypes(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctx, span := d.tracer.Start(ctx, "datasource.parca.callProfileTypes")
defer span.End()
res, err := d.client.ProfileTypes(ctx, connect.NewRequest(&v1alpha1.ProfileTypesRequest{}))
if err != nil {
return err
@@ -50,35 +53,51 @@ func (d *ParcaDatasource) callProfileTypes(ctx context.Context, req *backend.Cal
data, err := json.Marshal(types)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
return nil
}
func (d *ParcaDatasource) callLabelNames(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctx, span := d.tracer.Start(ctx, "datasource.parca.callLabelNames")
defer span.End()
res, err := d.client.Labels(ctx, connect.NewRequest(&v1alpha1.LabelsRequest{}))
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
data, err := json.Marshal(res.Msg.LabelNames)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
return nil
}
func (d *ParcaDatasource) callLabelValues(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
ctx, span := d.tracer.Start(ctx, "datasource.parca.callLabelValues")
defer span.End()
parsedUrl, err := url.Parse(req.URL)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
label, ok := parsedUrl.Query()["label"]
@@ -87,14 +106,20 @@ func (d *ParcaDatasource) callLabelValues(ctx context.Context, req *backend.Call
}
res, err := d.client.Values(ctx, connect.NewRequest(&v1alpha1.ValuesRequest{LabelName: label[0]}))
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
data, err := json.Marshal(res.Msg.LabelValues)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
err = sender.Send(&backend.CallResourceResponse{Body: data, Headers: req.Headers, Status: 200})
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
return nil
+8 -5
View File
@@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
)
// Make sure ParcaDatasource implements required interfaces. This is important to do
@@ -28,7 +29,8 @@ var (
var logger = log.New("tsdb.parca")
type Service struct {
im instancemgmt.InstanceManager
im instancemgmt.InstanceManager
tracer tracing.Tracer
}
func (s *Service) getInstance(ctx context.Context, pluginCtx backend.PluginContext) (*ParcaDatasource, error) {
@@ -40,15 +42,16 @@ func (s *Service) getInstance(ctx context.Context, pluginCtx backend.PluginConte
return in, nil
}
func ProvideService(httpClientProvider httpclient.Provider) *Service {
func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service {
return &Service{
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)),
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider, tracer)),
tracer: tracer,
}
}
func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc {
func newInstanceSettings(httpClientProvider httpclient.Provider, tracer tracing.Tracer) datasource.InstanceFactoryFunc {
return func(_ context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
return NewParcaDatasource(httpClientProvider, settings)
return NewParcaDatasource(httpClientProvider, settings, tracer)
}
}