Files
traces/cmd/tempo-query/main.go
Andreas GerstmayrandGitHub f8fcfaf0ff Fix GetTrace() in tempo-query (#5864)
* Fix GetTrace() in tempo-query

Upgrading to grpc 1.38.0 broke compatibility with gogoproto.customtype,
and the trace_id field in GetTraceRequest of storage.pb.go uses customtype.

This issue only occurs when navigating to a trace in Jaeger UI and
then hitting refresh (this triggers a GetTrace() request).
Searching traces in Jaeger UI and opening them worked fine before this
change as well, because this issued a FindTraces() request, which doesn't
use a customtype.

* add changelog entry

Signed-off-by: Andreas Gerstmayr <[email protected]>

---------

Signed-off-by: Andreas Gerstmayr <[email protected]>
2025-11-06 16:49:28 +01:00

97 lines
2.6 KiB
Go

package main
import (
"flag"
"net"
"os"
"strings"
zaplogfmt "github.com/jsternberg/zap-logfmt"
"github.com/spf13/viper"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
google_grpc "google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
"github.com/grafana/tempo/cmd/tempo-query/jaeger/storage_v1"
"github.com/grafana/tempo/cmd/tempo-query/tempo"
"github.com/grafana/tempo/pkg/gogocodec"
)
func init() {
// Required because the trace_id field in GetTraceRequest of storage.pb.go uses customtype, which doesn't work with grpc 1.38.0+.
// gogocodec provides a workaround, see pkg/gogocodec/gogocodec.go for more information.
encoding.RegisterCodec(gogocodec.NewCodec())
}
func main() {
config := zap.NewProductionEncoderConfig()
logger := zap.New(zapcore.NewCore(
zaplogfmt.NewEncoder(config),
os.Stdout,
zapcore.InfoLevel,
))
var configPath string
flag.StringVar(&configPath, "config", "", "A path to the plugin's configuration file")
flag.Parse()
v := viper.New()
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
if configPath != "" {
v.SetConfigFile(configPath)
err := v.ReadInConfig()
if err != nil {
logger.Error("failed to parse configuration file", zap.Error(err))
}
}
cfg := &tempo.Config{}
cfg.InitFromViper(v)
backend, err := tempo.New(logger, cfg)
if err != nil {
logger.Error("failed to init tracer backend", zap.Error(err))
}
grpcOpts := []google_grpc.ServerOption{
google_grpc.StatsHandler(otelgrpc.NewServerHandler()),
}
if cfg.TLSServerEnabeld {
creds, err := credentials.NewClientTLSFromFile(cfg.TLS.CertPath, cfg.TLS.ServerName)
if err != nil {
logger.Error("failed to load TLS credentials", zap.Error(err))
} else {
grpcOpts = append(grpcOpts, google_grpc.Creds(creds))
}
}
srv := google_grpc.NewServer(grpcOpts...)
storage_v1.RegisterSpanReaderPluginServer(srv, backend)
storage_v1.RegisterDependenciesReaderPluginServer(srv, backend)
storage_v1.RegisterSpanWriterPluginServer(srv, backend)
healthServer := health.NewServer()
grpc_health_v1.RegisterHealthServer(srv, healthServer)
healthServer.SetServingStatus("", grpc_health_v1.HealthCheckResponse_SERVING)
lis, err := net.Listen("tcp", cfg.Address)
if err != nil {
logger.Error("failed to listen", zap.Error(err))
}
logger.Info("Server starts serving", zap.String("address", cfg.Address))
if err := srv.Serve(lis); err != nil {
logger.Error("failed to serve", zap.Error(err))
}
}