d0ea82633f
* Jaeger: Migrate Services and Operations to the gRPC Jaeger endpoint (#112384) * add grpc feature toggle * move types into types.go * creates grpc client functions for services and operations * Call grpc services function when feature flag is enabled for health check * remove unnecessary double encoding * check for successful status code before decoding response and return nil in case of successful response * remove duplicate code * use variable * fix error type in testsz * Jaeger: Migrate search and Trace Search calls to use gRPC endpoint (#112610) * move all types into types package except for JagerClient * move all helper functions into utils package * change return type of search function to be frames and add grpc search functionality * fix tests * fix types and the way we check error response from grpc * change trace name and duration unit conversion * fix types and add tests * support queryAttributes * quick limit implementation in post processing * add todo for attributes / tags * make trace functionality ready to support grpc flow * add functions to process search response for a specific trace and create the Trace frame * tests for helper funtions * remove grpc querying for now! * change logic to be able to process and support multiple resource spans * remove logic for gRPC from grpc_client.go * add equivalent fields for logs and references * add tests for grpcTraceResponse function * fix types after merge with main * fix status code checks and return nil for error on successful responses * enable reading through config flag for trace search * create sigle key value type since they are similar for OTLP and non OTLP based formats * reference right type * convert events and links into references and logs * add status code, status message and kind to data frame * fix tests to accomodate new format * remove unused function and add more tests * remove edit flag for jsonc golden test files * add clarifying comment * fix tests and linting * fix golden files for testing * fix typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add clarifying comment Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * remove unnecessary logging statement * fix downstream errors --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use downstreamerrorf where applicable and add missing downstream eror sources. * tests --------- Co-authored-by: ismail simsek <ismailsimsek09@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
127 lines
3.5 KiB
Go
127 lines
3.5 KiB
Go
package jaeger
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
|
)
|
|
|
|
var logger = backend.NewLoggerWith("logger", "tsdb.jaeger")
|
|
|
|
type Service struct {
|
|
im instancemgmt.InstanceManager
|
|
}
|
|
|
|
func ProvideService(httpClientProvider *httpclient.Provider) *Service {
|
|
return &Service{
|
|
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)),
|
|
}
|
|
}
|
|
|
|
type datasourceInfo struct {
|
|
JaegerClient JaegerClient
|
|
}
|
|
|
|
type datasourceJSONData struct {
|
|
TraceIdTimeParams struct {
|
|
Enabled bool `json:"enabled"`
|
|
} `json:"traceIdTimeParams"`
|
|
}
|
|
|
|
func newInstanceSettings(httpClientProvider *httpclient.Provider) datasource.InstanceFactoryFunc {
|
|
return func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
|
httpClientOptions, err := settings.HTTPClientOptions(ctx)
|
|
if err != nil {
|
|
return nil, backend.DownstreamError(fmt.Errorf("error reading settings: %w", err))
|
|
}
|
|
|
|
httpClient, err := httpClientProvider.New(httpClientOptions)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error creating http client: %w", err)
|
|
}
|
|
|
|
if settings.URL == "" {
|
|
return nil, backend.DownstreamError(errors.New("error reading settings: url is empty"))
|
|
}
|
|
|
|
var jsonData datasourceJSONData
|
|
err = json.Unmarshal(settings.JSONData, &jsonData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error reading settings: %w", err)
|
|
}
|
|
|
|
logger := logger.FromContext(ctx)
|
|
jaegerClient, err := New(httpClient, logger, settings)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error creating jaeger client: %w", err)
|
|
}
|
|
|
|
return &datasourceInfo{JaegerClient: jaegerClient}, err
|
|
}
|
|
}
|
|
|
|
func (s *Service) getDSInfo(ctx context.Context, pluginCtx backend.PluginContext) (*datasourceInfo, error) {
|
|
i, err := s.im.Get(ctx, pluginCtx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
instance, ok := i.(*datasourceInfo)
|
|
if !ok {
|
|
return nil, errors.New("failed to cast datasource info")
|
|
}
|
|
|
|
return instance, nil
|
|
}
|
|
|
|
func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
|
client, err := s.getDSInfo(ctx, backend.PluginConfigFromContext(ctx))
|
|
cfg := backend.GrafanaConfigFromContext(ctx)
|
|
if err != nil {
|
|
return &backend.CheckHealthResult{
|
|
Status: backend.HealthStatusError,
|
|
Message: err.Error(),
|
|
}, nil
|
|
}
|
|
|
|
var servicesErr error
|
|
if cfg.FeatureToggles().IsEnabled("jaegerEnableGrpcEndpoint") {
|
|
_, servicesErr = client.JaegerClient.GrpcServices()
|
|
} else {
|
|
_, servicesErr = client.JaegerClient.Services()
|
|
}
|
|
|
|
if servicesErr != nil {
|
|
return &backend.CheckHealthResult{
|
|
Status: backend.HealthStatusError,
|
|
Message: servicesErr.Error(),
|
|
}, nil
|
|
}
|
|
|
|
return &backend.CheckHealthResult{
|
|
Status: backend.HealthStatusOk,
|
|
Message: "Data source is working",
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
|
handler := httpadapter.New(s.registerResourceRoutes())
|
|
return handler.CallResource(ctx, req, sender)
|
|
}
|
|
|
|
func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
|
dsInfo, err := s.getDSInfo(ctx, req.PluginContext)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return queryData(ctx, dsInfo, req)
|
|
}
|