Skip to content

Commit

Permalink
Merge pull request #1805 from authzed/customize-histogram
Browse files Browse the repository at this point in the history
turns gRPC latency histogram into a toggleable option
  • Loading branch information
vroldanbet committed Mar 15, 2024
2 parents 768f93a + 9333f75 commit d35b109
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 22 deletions.
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ require (
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/bkielbasa/cyclop v1.2.1 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bombsimon/wsl/v3 v3.4.0 // indirect
github.com/bombsimon/wsl/v4 v4.2.1 // indirect
github.com/breml/bidichk v0.2.7 // indirect
github.com/breml/errchkjson v0.3.6 // indirect
github.com/butuzov/ireturn v0.3.0 // indirect
Expand Down Expand Up @@ -178,6 +178,7 @@ require (
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/flock v0.8.1 // indirect
Expand Down Expand Up @@ -219,6 +220,7 @@ require (
github.com/jgautheron/goconst v1.7.0 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
github.com/jjti/go-spancheck v0.5.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
Expand Down Expand Up @@ -318,6 +320,7 @@ require (
github.com/yeya24/promlinter v0.2.0 // indirect
github.com/ykadowak/zerologlint v0.1.5 // indirect
gitlab.com/bosi/decorder v0.4.1 // indirect
go-simpler.org/musttag v0.8.0 // indirect
go-simpler.org/sloglint v0.4.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.20.0 // indirect
go.opentelemetry.io/contrib/propagators/ot v1.20.0 // indirect
Expand All @@ -326,7 +329,6 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.tmz.dev/musttag v0.7.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJ
github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM=
github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo=
github.com/bombsimon/wsl/v4 v4.2.1 h1:Cxg6u+XDWff75SIFFmNsqnIOgob+Q9hG6y/ioKbRFiM=
github.com/bombsimon/wsl/v4 v4.2.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo=
github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY=
Expand Down Expand Up @@ -916,7 +915,6 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.tmz.dev/musttag v0.7.2/go.mod h1:m6q5NiiSKMnQYokefa2xGoyoXnrswCbJ0AWYzf4Zs28=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/devtools.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func NewDevtoolsCommand(programName string) *cobra.Command {
}

func runfunc(cmd *cobra.Command, _ []string) error {
grpcUnaryInterceptor, _ := server.GRPCMetrics()
grpcUnaryInterceptor, _ := server.GRPCMetrics(false)
grpcBuilder := grpcServiceBuilder()
grpcServer, err := grpcBuilder.ServerFromFlags(cmd,
grpc.ChainUnaryInterceptor(
Expand Down
30 changes: 17 additions & 13 deletions pkg/cmd/server/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ type MiddlewareOption struct {
ds datastore.Datastore
enableRequestLog bool
enableResponseLog bool
disableGRPCHistogram bool
}

// gRPCMetricsUnaryInterceptor creates the default prometheus metrics interceptor for unary gRPCs
Expand All @@ -174,9 +175,9 @@ var gRPCMetricsStreamingInterceptor grpc.StreamServerInterceptor
var serverMetricsOnce sync.Once

// GRPCMetrics returns the interceptors used for the default gRPC metrics from grpc-ecosystem/go-grpc-middleware
func GRPCMetrics() (grpc.UnaryServerInterceptor, grpc.StreamServerInterceptor) {
func GRPCMetrics(disableLatencyHistogram bool) (grpc.UnaryServerInterceptor, grpc.StreamServerInterceptor) {
serverMetricsOnce.Do(func() {
gRPCMetricsUnaryInterceptor, gRPCMetricsStreamingInterceptor = createServerMetrics()
gRPCMetricsUnaryInterceptor, gRPCMetricsStreamingInterceptor = createServerMetrics(disableLatencyHistogram)
})

return gRPCMetricsUnaryInterceptor, gRPCMetricsStreamingInterceptor
Expand All @@ -198,7 +199,7 @@ func doesNotMatchRoute(route string) func(_ context.Context, c interceptors.Call

// DefaultUnaryMiddleware generates the default middleware chain used for the public SpiceDB Unary gRPC methods
func DefaultUnaryMiddleware(opts MiddlewareOption) (*MiddlewareChain[grpc.UnaryServerInterceptor], error) {
grpcMetricsUnaryInterceptor, _ := GRPCMetrics()
grpcMetricsUnaryInterceptor, _ := GRPCMetrics(opts.disableGRPCHistogram)
chain, err := NewMiddlewareChain([]ReferenceableMiddleware[grpc.UnaryServerInterceptor]{
NewUnaryMiddleware().
WithName(DefaultMiddlewareRequestID).
Expand Down Expand Up @@ -276,7 +277,7 @@ func DefaultUnaryMiddleware(opts MiddlewareOption) (*MiddlewareChain[grpc.UnaryS

// DefaultStreamingMiddleware generates the default middleware chain used for the public SpiceDB Streaming gRPC methods
func DefaultStreamingMiddleware(opts MiddlewareOption) (*MiddlewareChain[grpc.StreamServerInterceptor], error) {
_, grpcMetricsStreamingInterceptor := GRPCMetrics()
_, grpcMetricsStreamingInterceptor := GRPCMetrics(opts.disableGRPCHistogram)
chain, err := NewMiddlewareChain([]ReferenceableMiddleware[grpc.StreamServerInterceptor]{
NewStreamMiddleware().
WithName(DefaultMiddlewareRequestID).
Expand Down Expand Up @@ -366,8 +367,10 @@ func determineEventsToLog(opts MiddlewareOption) grpclog.Option {
}

// DefaultDispatchMiddleware generates the default middleware chain used for the internal dispatch SpiceDB gRPC API
func DefaultDispatchMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, ds datastore.Datastore) ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) {
grpcMetricsUnaryInterceptor, grpcMetricsStreamingInterceptor := GRPCMetrics()
func DefaultDispatchMiddleware(logger zerolog.Logger, authFunc grpcauth.AuthFunc, ds datastore.Datastore,
disableGRPCLatencyHistogram bool,
) ([]grpc.UnaryServerInterceptor, []grpc.StreamServerInterceptor) {
grpcMetricsUnaryInterceptor, grpcMetricsStreamingInterceptor := GRPCMetrics(disableGRPCLatencyHistogram)
return []grpc.UnaryServerInterceptor{
requestid.UnaryServerInterceptor(requestid.GenerateIfMissing(true)),
logmw.UnaryServerInterceptor(logmw.ExtractMetadataField("x-request-id", "requestID")),
Expand Down Expand Up @@ -410,16 +413,17 @@ func InterceptorLogger(l zerolog.Logger) grpclog.Logger {
}

// initializes prometheus grpc interceptors with exemplar support enabled
func createServerMetrics() (grpc.UnaryServerInterceptor, grpc.StreamServerInterceptor) {
srvMetrics := grpcprom.NewServerMetrics(
grpcprom.WithServerHandlingTimeHistogram(
func createServerMetrics(disableHistogram bool) (grpc.UnaryServerInterceptor, grpc.StreamServerInterceptor) {
var opts []grpcprom.ServerMetricsOption
if !disableHistogram {
opts = append(opts, grpcprom.WithServerHandlingTimeHistogram(
grpcprom.WithHistogramBuckets([]float64{.001, .003, .006, .010, .018, .024, .032, .042, .056, .075, .100, .178, .316, .562, 1, 5}),
),
)

))
}
srvMetrics := grpcprom.NewServerMetrics(opts...)
// deliberately ignore if these metrics were already registered, so that
// custom builds of SpiceDB can register these metrics with custom labels
_ = prometheus.DefaultRegisterer.Register(srvMetrics)
_ = prometheus.Register(srvMetrics)

exemplarFromContext := func(ctx context.Context) prometheus.Labels {
if span := trace.SpanContextFromContext(ctx); span.IsSampled() {
Expand Down
8 changes: 6 additions & 2 deletions pkg/cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ type Config struct {
// Logs
EnableRequestLogs bool `debugmap:"visible"`
EnableResponseLogs bool `debugmap:"visible"`

// Metrics
DisableGRPCLatencyHistogram bool `debugmap:"visible"`
}

type closeableStack struct {
Expand Down Expand Up @@ -289,9 +292,9 @@ func (c *Config) Complete(ctx context.Context) (RunnableServer, error) {

if len(c.DispatchUnaryMiddleware) == 0 && len(c.DispatchStreamingMiddleware) == 0 {
if c.GRPCAuthFunc == nil {
c.DispatchUnaryMiddleware, c.DispatchStreamingMiddleware = DefaultDispatchMiddleware(log.Logger, auth.MustRequirePresharedKey(c.PresharedSecureKey), ds)
c.DispatchUnaryMiddleware, c.DispatchStreamingMiddleware = DefaultDispatchMiddleware(log.Logger, auth.MustRequirePresharedKey(c.PresharedSecureKey), ds, c.DisableGRPCLatencyHistogram)
} else {
c.DispatchUnaryMiddleware, c.DispatchStreamingMiddleware = DefaultDispatchMiddleware(log.Logger, c.GRPCAuthFunc, ds)
c.DispatchUnaryMiddleware, c.DispatchStreamingMiddleware = DefaultDispatchMiddleware(log.Logger, c.GRPCAuthFunc, ds, c.DisableGRPCLatencyHistogram)
}
}

Expand Down Expand Up @@ -360,6 +363,7 @@ func (c *Config) Complete(ctx context.Context) (RunnableServer, error) {
ds,
c.EnableRequestLogs,
c.EnableResponseLogs,
c.DisableGRPCLatencyHistogram,
}
defaultUnaryMiddlewareChain, err := DefaultUnaryMiddleware(opts)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func TestModifyUnaryMiddleware(t *testing.T) {
},
}}

opt := MiddlewareOption{logging.Logger, nil, false, nil, nil, false, false}
opt := MiddlewareOption{logging.Logger, nil, false, nil, nil, false, false, false}
defaultMw, err := DefaultUnaryMiddleware(opt)
require.NoError(t, err)

Expand All @@ -256,7 +256,7 @@ func TestModifyStreamingMiddleware(t *testing.T) {
},
}}

opt := MiddlewareOption{logging.Logger, nil, false, nil, nil, false, false}
opt := MiddlewareOption{logging.Logger, nil, false, nil, nil, false, false, false}
defaultMw, err := DefaultStreamingMiddleware(opt)
require.NoError(t, err)

Expand Down
9 changes: 9 additions & 0 deletions pkg/cmd/server/zz_generated.options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d35b109

Please sign in to comment.