github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/chunk/client/gcp/instrumentation.go (about) 1 package gcp 2 3 import ( 4 "net/http" 5 "strconv" 6 "time" 7 8 otgrpc "github.com/opentracing-contrib/go-grpc" 9 opentracing "github.com/opentracing/opentracing-go" 10 "github.com/prometheus/client_golang/prometheus" 11 "github.com/prometheus/client_golang/prometheus/promauto" 12 "github.com/weaveworks/common/middleware" 13 "google.golang.org/api/option" 14 "google.golang.org/grpc" 15 ) 16 17 var ( 18 bigtableRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ 19 Namespace: "loki", 20 Name: "bigtable_request_duration_seconds", 21 Help: "Time spent doing Bigtable requests.", 22 23 // Bigtable latency seems to range from a few ms to a several seconds and is 24 // important. So use 9 buckets from 1ms to just over 1 minute (65s). 25 Buckets: prometheus.ExponentialBuckets(0.001, 4, 9), 26 }, []string{"operation", "status_code"}) 27 28 gcsRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ 29 Namespace: "loki", 30 Name: "gcs_request_duration_seconds", 31 Help: "Time spent doing GCS requests.", 32 33 // 6 buckets from 5ms to 20s. 34 Buckets: prometheus.ExponentialBuckets(0.005, 4, 7), 35 }, []string{"operation", "status_code"}) 36 ) 37 38 func bigtableInstrumentation() ([]grpc.UnaryClientInterceptor, []grpc.StreamClientInterceptor) { 39 return []grpc.UnaryClientInterceptor{ 40 otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()), 41 middleware.UnaryClientInstrumentInterceptor(bigtableRequestDuration), 42 }, 43 []grpc.StreamClientInterceptor{ 44 otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer()), 45 middleware.StreamClientInstrumentInterceptor(bigtableRequestDuration), 46 } 47 } 48 49 func gcsInstrumentation(transport http.RoundTripper) *http.Client { 50 client := &http.Client{ 51 Transport: instrumentedTransport{ 52 observer: gcsRequestDuration, 53 next: transport, 54 }, 55 } 56 return client 57 } 58 59 func toOptions(opts []grpc.DialOption) []option.ClientOption { 60 result := make([]option.ClientOption, 0, len(opts)) 61 for _, opt := range opts { 62 result = append(result, option.WithGRPCDialOption(opt)) 63 } 64 return result 65 } 66 67 type instrumentedTransport struct { 68 observer prometheus.ObserverVec 69 next http.RoundTripper 70 } 71 72 func (i instrumentedTransport) RoundTrip(req *http.Request) (*http.Response, error) { 73 start := time.Now() 74 resp, err := i.next.RoundTrip(req) 75 if err == nil { 76 i.observer.WithLabelValues(req.Method, strconv.Itoa(resp.StatusCode)).Observe(time.Since(start).Seconds()) 77 } 78 return resp, err 79 }