forked from grafana/loki
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request grafana#1219 from grafana/grpc-client-ratelimit
Add options for client-side rate limiting and backoff on all gRPC clients.
- Loading branch information
Showing
5 changed files
with
105 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,87 @@ | ||
package gcp | ||
|
||
import ( | ||
"github.com/grpc-ecosystem/go-grpc-middleware" | ||
"context" | ||
"net/http" | ||
"strconv" | ||
"time" | ||
|
||
otgrpc "github.com/opentracing-contrib/go-grpc" | ||
"github.com/opentracing/opentracing-go" | ||
opentracing "github.com/opentracing/opentracing-go" | ||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/prometheus/client_golang/prometheus/promauto" | ||
"google.golang.org/api/option" | ||
google_http "google.golang.org/api/transport/http" | ||
"google.golang.org/grpc" | ||
|
||
"github.com/cortexproject/cortex/pkg/util/middleware" | ||
) | ||
|
||
var bigtableRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ | ||
Namespace: "cortex", | ||
Name: "bigtable_request_duration_seconds", | ||
Help: "Time spent doing Bigtable requests.", | ||
|
||
// Bigtable latency seems to range from a few ms to a few hundred ms and is | ||
// important. So use 6 buckets from 1ms to 1s. | ||
Buckets: prometheus.ExponentialBuckets(0.001, 4, 6), | ||
}, []string{"operation", "status_code"}) | ||
|
||
func instrumentation() []option.ClientOption { | ||
return []option.ClientOption{ | ||
option.WithGRPCDialOption( | ||
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient( | ||
otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()), | ||
middleware.PrometheusGRPCUnaryInstrumentation(bigtableRequestDuration), | ||
)), | ||
), | ||
option.WithGRPCDialOption( | ||
grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient( | ||
otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer()), | ||
middleware.PrometheusGRPCStreamInstrumentation(bigtableRequestDuration), | ||
)), | ||
), | ||
var ( | ||
bigtableRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ | ||
Namespace: "cortex", | ||
Name: "bigtable_request_duration_seconds", | ||
Help: "Time spent doing Bigtable requests.", | ||
|
||
// Bigtable latency seems to range from a few ms to a few hundred ms and is | ||
// important. So use 6 buckets from 1ms to 1s. | ||
Buckets: prometheus.ExponentialBuckets(0.001, 4, 6), | ||
}, []string{"operation", "status_code"}) | ||
|
||
gcsRequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ | ||
Namespace: "cortex", | ||
Name: "gcs_request_duration_seconds", | ||
Help: "Time spent doing GCS requests.", | ||
|
||
// Bigtable latency seems to range from a few ms to a few hundred ms and is | ||
// important. So use 6 buckets from 1ms to 1s. | ||
Buckets: prometheus.ExponentialBuckets(0.001, 4, 6), | ||
}, []string{"operation", "status_code"}) | ||
) | ||
|
||
func bigtableInstrumentation() ([]grpc.UnaryClientInterceptor, []grpc.StreamClientInterceptor) { | ||
return []grpc.UnaryClientInterceptor{ | ||
otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer()), | ||
middleware.PrometheusGRPCUnaryInstrumentation(bigtableRequestDuration), | ||
}, | ||
[]grpc.StreamClientInterceptor{ | ||
otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer()), | ||
middleware.PrometheusGRPCStreamInstrumentation(bigtableRequestDuration), | ||
} | ||
} | ||
|
||
func gcsInstrumentation(ctx context.Context) (option.ClientOption, error) { | ||
transport, err := google_http.NewTransport(ctx, http.DefaultTransport) | ||
if err != nil { | ||
return nil, err | ||
} | ||
client := &http.Client{ | ||
Transport: instrumentedTransport{ | ||
observer: gcsRequestDuration, | ||
next: transport, | ||
}, | ||
} | ||
return option.WithHTTPClient(client), nil | ||
} | ||
|
||
func toOptions(opts []grpc.DialOption) []option.ClientOption { | ||
result := make([]option.ClientOption, 0, len(opts)) | ||
for _, opt := range opts { | ||
result = append(result, option.WithGRPCDialOption(opt)) | ||
} | ||
return result | ||
} | ||
|
||
type instrumentedTransport struct { | ||
observer prometheus.ObserverVec | ||
next http.RoundTripper | ||
} | ||
|
||
func (i instrumentedTransport) RoundTrip(req *http.Request) (*http.Response, error) { | ||
start := time.Now() | ||
resp, err := i.next.RoundTrip(req) | ||
if err == nil { | ||
i.observer.WithLabelValues(req.Method, strconv.Itoa(resp.StatusCode)).Observe(time.Since(start).Seconds()) | ||
} | ||
return resp, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters