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.ChainStreamInterceptor(
24 propagator.StreamServerPropagator(tenant.Propagator{}),
25 tenant.StreamServerInterceptor,
26 otelgrpc.StreamServerInterceptor(),
27 metrics.StreamServerInterceptor(),
28 messagesize.StreamServerInterceptor,
29 internalerrs.LoggingStreamServerInterceptor(logger),
30 ),
31 grpc.ChainUnaryInterceptor(
32 propagator.UnaryServerPropagator(tenant.Propagator{}),
33 tenant.UnaryServerInterceptor,
34 otelgrpc.UnaryServerInterceptor(),
35 metrics.UnaryServerInterceptor(),
36 messagesize.UnaryServerInterceptor,
37 internalerrs.LoggingUnaryServerInterceptor(logger),
38 ),
39 }
40
41 opts = append(opts, additionalOpts...)
42
43 // Ensure that the message size options are set last, so they override any other
44 // server-specific options that tweak the message size.
45 //
46 // The message size options are only provided if the environment variable is set. These options serve as an escape hatch, so they
47 // take precedence over everything else with a uniform size setting that's easy to reason about.
48 opts = append(opts, messagesize.MustGetServerMessageSizeFromEnv()...)
49
50 s := grpc.NewServer(opts...)
51 reflection.Register(s)
52 return s
53}
54
55// serviceMetricsOnce returns a singleton instance of the server metrics
56// that are shared across all gRPC servers that this process creates.
57//
58// This function panics if the metrics cannot be registered with the default
59// Prometheus registry.
60var serverMetricsOnce = sync.OnceValue(func() *grpcprom.ServerMetrics {
61 serverMetrics := grpcprom.NewServerMetrics(
62 grpcprom.WithServerCounterOptions(),
63 grpcprom.WithServerHandlingTimeHistogram(), // record the overall response latency for a gRPC request)
64 )
65 prometheus.DefaultRegisterer.MustRegister(serverMetrics)
66 return serverMetrics
67})