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>
84 lines
2.9 KiB
Go
84 lines
2.9 KiB
Go
package jaeger
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
|
)
|
|
|
|
func (s *Service) registerResourceRoutes() *http.ServeMux {
|
|
router := http.NewServeMux()
|
|
router.HandleFunc("GET /services", s.withDatasourceHandlerFunc(getServicesHandler))
|
|
router.HandleFunc("GET /services/{service}/operations", s.withDatasourceHandlerFunc(getOperationsHandler))
|
|
return router
|
|
}
|
|
|
|
func (s *Service) withDatasourceHandlerFunc(getHandler func(d *datasourceInfo) http.HandlerFunc) func(rw http.ResponseWriter, r *http.Request) {
|
|
return func(rw http.ResponseWriter, r *http.Request) {
|
|
client, err := s.getDSInfo(r.Context(), backend.PluginConfigFromContext(r.Context()))
|
|
if err != nil {
|
|
writeResponse(nil, errors.New("error getting data source information from context"), rw, client.JaegerClient.logger)
|
|
return
|
|
}
|
|
h := getHandler(client)
|
|
h.ServeHTTP(rw, r)
|
|
}
|
|
}
|
|
|
|
func getServicesHandler(ds *datasourceInfo) http.HandlerFunc {
|
|
return func(rw http.ResponseWriter, r *http.Request) {
|
|
cfg := backend.GrafanaConfigFromContext(r.Context())
|
|
var services []string
|
|
var err error
|
|
if cfg.FeatureToggles().IsEnabled("jaegerEnableGrpcEndpoint") {
|
|
services, err = ds.JaegerClient.GrpcServices()
|
|
} else {
|
|
services, err = ds.JaegerClient.Services()
|
|
}
|
|
writeResponse(services, err, rw, ds.JaegerClient.logger)
|
|
}
|
|
}
|
|
|
|
func getOperationsHandler(ds *datasourceInfo) http.HandlerFunc {
|
|
return func(rw http.ResponseWriter, r *http.Request) {
|
|
cfg := backend.GrafanaConfigFromContext(r.Context())
|
|
service := strings.TrimSpace(r.PathValue("service"))
|
|
var operations []string
|
|
var err error
|
|
if cfg.FeatureToggles().IsEnabled("jaegerEnableGrpcEndpoint") {
|
|
operations, err = ds.JaegerClient.GrpcOperations(service)
|
|
} else {
|
|
operations, err = ds.JaegerClient.Operations(service)
|
|
}
|
|
writeResponse(operations, err, rw, ds.JaegerClient.logger)
|
|
}
|
|
}
|
|
|
|
func writeResponse(res interface{}, err error, rw http.ResponseWriter, logger log.Logger) {
|
|
if err != nil {
|
|
// This is used for resource calls, we don't need to add actual error message, but we should log it
|
|
logger.Warn("An error occurred while doing a resource call", "error", err)
|
|
http.Error(rw, "An error occurred within the plugin", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
// Response should not be string, but just in case, handle it
|
|
if str, ok := res.(string); ok {
|
|
rw.Header().Set("Content-Type", "text/plain")
|
|
_, _ = rw.Write([]byte(str))
|
|
return
|
|
}
|
|
b, err := json.Marshal(res)
|
|
if err != nil {
|
|
// This is used for resource calls, we don't need to add actual error message, but we should log it
|
|
logger.Warn("An error occurred while processing response from resource call", "error", err)
|
|
http.Error(rw, "An error occurred within the plugin", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
_, _ = rw.Write(b)
|
|
}
|