Skip to content

Commit

Permalink
Use sync.OnceValue for metrics registration (#815)
Browse files Browse the repository at this point in the history
Inspired by a recent Sourcegraph refactor.
  • Loading branch information
jtibshirani authored Sep 5, 2024
1 parent c284149 commit 35dda3e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 40 deletions.
39 changes: 16 additions & 23 deletions cmd/zoekt-sourcegraph-indexserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,21 @@ var (
Help: "Counts the number of repos we stopped tracking.",
})

clientMetricsOnce sync.Once
clientMetrics *grpcprom.ClientMetrics
// clientMetricsOnce returns a singleton instance of the client metrics
// that are shared across all gRPC clients that this process creates.
//
// This function panics if the metrics cannot be registered with the default
// Prometheus registry.
clientMetricsOnce = sync.OnceValue(func() *grpcprom.ClientMetrics {
clientMetrics := grpcprom.NewClientMetrics(
grpcprom.WithClientCounterOptions(),
grpcprom.WithClientHandlingTimeHistogram(), // record the overall request latency for a gRPC request
grpcprom.WithClientStreamRecvHistogram(), // record how long it takes for a client to receive a message during a streaming RPC
grpcprom.WithClientStreamSendHistogram(), // record how long it takes for a client to send a message during a streaming RPC
)
prometheus.DefaultRegisterer.MustRegister(clientMetrics)
return clientMetrics
})
)

// 1 MB; match https://sourcegraph.sgdev.org/github.com/sourcegraph/sourcegraph/-/blob/cmd/symbols/internal/symbols/search.go#L22
Expand Down Expand Up @@ -1505,7 +1518,7 @@ func internalActorStreamInterceptor() grpc.StreamClientInterceptor {
const defaultGRPCMessageReceiveSizeBytes = 90 * 1024 * 1024 // 90 MB

func dialGRPCClient(addr string, logger sglog.Logger, additionalOpts ...grpc.DialOption) (proto.ZoektConfigurationServiceClient, error) {
metrics := mustGetClientMetrics()
metrics := clientMetricsOnce()

// If the service seems to be unavailable, this
// will retry after [1s, 2s, 4s, 8s, 16s] with a jitterFraction of .1
Expand Down Expand Up @@ -1559,26 +1572,6 @@ func dialGRPCClient(addr string, logger sglog.Logger, additionalOpts ...grpc.Dia
return client, nil
}

// mustGetClientMetrics returns a singleton instance of the client metrics
// that are shared across all gRPC clients that this process creates.
//
// This function panics if the metrics cannot be registered with the default
// Prometheus registry.
func mustGetClientMetrics() *grpcprom.ClientMetrics {
clientMetricsOnce.Do(func() {
clientMetrics = grpcprom.NewClientMetrics(
grpcprom.WithClientCounterOptions(),
grpcprom.WithClientHandlingTimeHistogram(), // record the overall request latency for a gRPC request
grpcprom.WithClientStreamRecvHistogram(), // record how long it takes for a client to receive a message during a streaming RPC
grpcprom.WithClientStreamSendHistogram(), // record how long it takes for a client to send a message during a streaming RPC
)

prometheus.DefaultRegisterer.MustRegister(clientMetrics)
})

return clientMetrics
}

// addDefaultPort adds a default port to a URL if one is not specified.
//
// If the URL scheme is "http" and no port is specified, "80" is used.
Expand Down
27 changes: 10 additions & 17 deletions cmd/zoekt-webserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func traceContext(ctx context.Context) sglog.TraceContext {
}

func newGRPCServer(logger sglog.Logger, streamer zoekt.Streamer, additionalOpts ...grpc.ServerOption) *grpc.Server {
metrics := mustGetServerMetrics()
metrics := serverMetricsOnce()

opts := []grpc.ServerOption{
grpc.ChainStreamInterceptor(
Expand Down Expand Up @@ -689,24 +689,17 @@ var (
Help: "The total number of search requests that zoekt received",
})

serverMetricsOnce sync.Once
serverMetrics *grpcprom.ServerMetrics
)

// mustGetServerMetrics returns a singleton instance of the server metrics
// that are shared across all gRPC servers that this process creates.
//
// This function panics if the metrics cannot be registered with the default
// Prometheus registry.
func mustGetServerMetrics() *grpcprom.ServerMetrics {
serverMetricsOnce.Do(func() {
serverMetrics = grpcprom.NewServerMetrics(
// serviceMetricsOnce returns a singleton instance of the server metrics
// that are shared across all gRPC servers that this process creates.
//
// This function panics if the metrics cannot be registered with the default
// Prometheus registry.
serverMetricsOnce = sync.OnceValue(func() *grpcprom.ServerMetrics {
serverMetrics := grpcprom.NewServerMetrics(
grpcprom.WithServerCounterOptions(),
grpcprom.WithServerHandlingTimeHistogram(), // record the overall response latency for a gRPC request)
)

prometheus.DefaultRegisterer.MustRegister(serverMetrics)
return serverMetrics
})

return serverMetrics
}
)

0 comments on commit 35dda3e

Please sign in to comment.