fork of https://github.com/sourcegraph/zoekt
1package defaults
2
3import (
4 "sync"
5
6 grpcprom "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
7 "github.com/prometheus/client_golang/prometheus"
8 sglog "github.com/sourcegraph/log"
9 "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
10 "google.golang.org/grpc"
11 "google.golang.org/grpc/reflection"
12
13 "github.com/sourcegraph/zoekt/grpc/internalerrs"
14 "github.com/sourcegraph/zoekt/grpc/messagesize"
15 "github.com/sourcegraph/zoekt/grpc/propagator"
16 "github.com/sourcegraph/zoekt/internal/tenant"
17)
18
19func NewServer(logger sglog.Logger, additionalOpts ...grpc.ServerOption) *grpc.Server {
20 metrics := serverMetricsOnce()
21
22 opts := []grpc.ServerOption{
23 grpc.StatsHandler(otelgrpc.NewServerHandler()),
24 grpc.ChainStreamInterceptor(
25 propagator.StreamServerPropagator(tenant.Propagator{}),
26 tenant.StreamServerInterceptor,
27 metrics.StreamServerInterceptor(),
28 messagesize.StreamServerInterceptor,
29 internalerrs.LoggingStreamServerInterceptor(logger),
30 ),
31 grpc.ChainUnaryInterceptor(
32 propagator.UnaryServerPropagator(tenant.Propagator{}),
33 tenant.UnaryServerInterceptor,
34 metrics.UnaryServerInterceptor(),
35 messagesize.UnaryServerInterceptor,
36 internalerrs.LoggingUnaryServerInterceptor(logger),
37 ),
38 }
39
40 opts = append(opts, additionalOpts...)
41
42 // Ensure that the message size options are set last, so they override any other
43 // server-specific options that tweak the message size.
44 //
45 // The message size options are only provided if the environment variable is set. These options serve as an escape hatch, so they
46 // take precedence over everything else with a uniform size setting that's easy to reason about.
47 opts = append(opts, messagesize.MustGetServerMessageSizeFromEnv()...)
48
49 s := grpc.NewServer(opts...)
50 reflection.Register(s)
51 return s
52}
53
54// serviceMetricsOnce returns a singleton instance of the server metrics
55// that are shared across all gRPC servers that this process creates.
56//
57// This function panics if the metrics cannot be registered with the default
58// Prometheus registry.
59var serverMetricsOnce = sync.OnceValue(func() *grpcprom.ServerMetrics {
60 serverMetrics := grpcprom.NewServerMetrics(
61 grpcprom.WithServerCounterOptions(),
62 grpcprom.WithServerHandlingTimeHistogram(), // record the overall response latency for a gRPC request)
63 )
64 prometheus.DefaultRegisterer.MustRegister(serverMetrics)
65 return serverMetrics
66})