github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/ingester/client/client.go (about) 1 package client 2 3 import ( 4 "flag" 5 "io" 6 "time" 7 8 "github.com/grafana/dskit/grpcclient" 9 "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" 10 "github.com/opentracing/opentracing-go" 11 "github.com/prometheus/client_golang/prometheus" 12 "github.com/prometheus/client_golang/prometheus/promauto" 13 "github.com/weaveworks/common/middleware" 14 "google.golang.org/grpc" 15 "google.golang.org/grpc/health/grpc_health_v1" 16 17 "github.com/grafana/loki/pkg/distributor/clientpool" 18 "github.com/grafana/loki/pkg/logproto" 19 ) 20 21 var ingesterClientRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ 22 Name: "loki_ingester_client_request_duration_seconds", 23 Help: "Time spent doing Ingester requests.", 24 Buckets: prometheus.ExponentialBuckets(0.001, 4, 6), 25 }, []string{"operation", "status_code"}) 26 27 type HealthAndIngesterClient interface { 28 logproto.IngesterClient 29 grpc_health_v1.HealthClient 30 Close() error 31 } 32 33 type ClosableHealthAndIngesterClient struct { 34 logproto.PusherClient 35 logproto.QuerierClient 36 logproto.IngesterClient 37 grpc_health_v1.HealthClient 38 io.Closer 39 } 40 41 // Config for an ingester client. 42 type Config struct { 43 PoolConfig clientpool.PoolConfig `yaml:"pool_config,omitempty"` 44 RemoteTimeout time.Duration `yaml:"remote_timeout,omitempty"` 45 GRPCClientConfig grpcclient.Config `yaml:"grpc_client_config"` 46 GRPCUnaryClientInterceptors []grpc.UnaryClientInterceptor `yaml:"-"` 47 GRCPStreamClientInterceptors []grpc.StreamClientInterceptor `yaml:"-"` 48 } 49 50 // RegisterFlags registers flags. 51 func (cfg *Config) RegisterFlags(f *flag.FlagSet) { 52 cfg.GRPCClientConfig.RegisterFlagsWithPrefix("ingester.client", f) 53 cfg.PoolConfig.RegisterFlags(f) 54 55 f.DurationVar(&cfg.PoolConfig.RemoteTimeout, "ingester.client.healthcheck-timeout", 1*time.Second, "Timeout for healthcheck rpcs.") 56 f.DurationVar(&cfg.RemoteTimeout, "ingester.client.timeout", 5*time.Second, "Timeout for ingester client RPCs.") 57 } 58 59 // New returns a new ingester client. 60 func New(cfg Config, addr string) (HealthAndIngesterClient, error) { 61 opts := []grpc.DialOption{ 62 grpc.WithDefaultCallOptions(cfg.GRPCClientConfig.CallOptions()...), 63 } 64 65 dialOpts, err := cfg.GRPCClientConfig.DialOption(instrumentation(&cfg)) 66 if err != nil { 67 return nil, err 68 } 69 70 opts = append(opts, dialOpts...) 71 conn, err := grpc.Dial(addr, opts...) 72 if err != nil { 73 return nil, err 74 } 75 return ClosableHealthAndIngesterClient{ 76 PusherClient: logproto.NewPusherClient(conn), 77 QuerierClient: logproto.NewQuerierClient(conn), 78 IngesterClient: logproto.NewIngesterClient(conn), 79 HealthClient: grpc_health_v1.NewHealthClient(conn), 80 Closer: conn, 81 }, nil 82 } 83 84 func instrumentation(cfg *Config) ([]grpc.UnaryClientInterceptor, []grpc.StreamClientInterceptor) { 85 var unaryInterceptors []grpc.UnaryClientInterceptor 86 unaryInterceptors = append(unaryInterceptors, cfg.GRPCUnaryClientInterceptors...) 87 unaryInterceptors = append(unaryInterceptors, 88 otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()), 89 middleware.ClientUserHeaderInterceptor, 90 middleware.UnaryClientInstrumentInterceptor(ingesterClientRequestDuration), 91 ) 92 var streamInterceptors []grpc.StreamClientInterceptor 93 streamInterceptors = append(streamInterceptors, cfg.GRCPStreamClientInterceptors...) 94 streamInterceptors = append(streamInterceptors, 95 otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer()), 96 middleware.StreamClientUserHeaderInterceptor, 97 middleware.StreamClientInstrumentInterceptor(ingesterClientRequestDuration), 98 ) 99 100 return unaryInterceptors, streamInterceptors 101 }