97 lines
3.1 KiB
Go
97 lines
3.1 KiB
Go
|
package grpc
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
grpclogging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
|
||
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||
|
"go.opentelemetry.io/otel"
|
||
|
"go.opentelemetry.io/otel/attribute"
|
||
|
"go.opentelemetry.io/otel/codes"
|
||
|
"go.opentelemetry.io/otel/trace"
|
||
|
"google.golang.org/grpc"
|
||
|
"google.golang.org/grpc/reflection"
|
||
|
)
|
||
|
|
||
|
func (a *appGRPCServer) prepGRPCServer(spanCtx context.Context) error {
|
||
|
ctx, span := a.tracer.Start(spanCtx, "appgrpc.init.prepare")
|
||
|
defer span.End()
|
||
|
|
||
|
if len(a.opts.Services) < 1 {
|
||
|
err := errors.New("refusing to create grpc server with no services")
|
||
|
a.logger.Err(err).Send()
|
||
|
span.RecordError(err)
|
||
|
span.SetStatus(codes.Error, err.Error())
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Prepare GRPC Server Opts
|
||
|
a.prepareOTEL(ctx)
|
||
|
a.prepareLogging(ctx)
|
||
|
|
||
|
// Chain interceptors for unary RPCs
|
||
|
a.serverOpts = append(a.serverOpts,
|
||
|
grpc.ChainUnaryInterceptor(a.opts.UnaryInterceptors...))
|
||
|
span.SetAttributes(attribute.Int("numUnaryInterceptors",
|
||
|
len(a.opts.UnaryInterceptors)))
|
||
|
|
||
|
// Chain interceptors for streaming RPCs
|
||
|
a.serverOpts = append(a.serverOpts,
|
||
|
grpc.ChainStreamInterceptor(a.opts.StreamInterceptors...))
|
||
|
span.SetAttributes(attribute.Int("numStreamInterceptors",
|
||
|
len(a.opts.StreamInterceptors)))
|
||
|
|
||
|
// Prepare GRPC Server
|
||
|
a.server = grpc.NewServer(a.serverOpts...)
|
||
|
span.SetAttributes(attribute.Int("numServerOpts", len(a.serverOpts)))
|
||
|
|
||
|
// Load given services into server registry
|
||
|
for _, service := range a.opts.Services {
|
||
|
span.AddEvent(fmt.Sprintf("registered %s service", service.Name))
|
||
|
a.server.RegisterService(service.Type, service.Service)
|
||
|
}
|
||
|
span.SetAttributes(attribute.Int("numGRPCServices", len(a.opts.Services)))
|
||
|
|
||
|
// Enable reflection if desired
|
||
|
if a.opts.EnableReflection {
|
||
|
reflection.Register(a.server)
|
||
|
}
|
||
|
span.SetAttributes(attribute.Bool("reflectionEnabled", a.opts.EnableReflection))
|
||
|
|
||
|
span.SetStatus(codes.Ok, "")
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (a *appGRPCServer) prepareOTEL(spanCtx context.Context) {
|
||
|
_, span := a.tracer.Start(spanCtx, "appgrpc.init.prepare.otel", trace.WithAttributes(
|
||
|
attribute.Bool("instrumentationEnabled", a.opts.EnableInstrumentation),
|
||
|
attribute.String("logLevel", a.logger.GetLevel().String())))
|
||
|
defer span.End()
|
||
|
|
||
|
if a.opts.EnableInstrumentation {
|
||
|
a.serverOpts = append(a.serverOpts,
|
||
|
grpc.StatsHandler(
|
||
|
otelgrpc.NewServerHandler(
|
||
|
otelgrpc.WithTracerProvider(otel.GetTracerProvider()),
|
||
|
otelgrpc.WithMeterProvider(otel.GetMeterProvider()),
|
||
|
)))
|
||
|
span.SetStatus(codes.Ok, "")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (a *appGRPCServer) prepareLogging(spanCtx context.Context) {
|
||
|
_, span := a.tracer.Start(spanCtx, "appgrpc.init.prepare.logging", trace.WithAttributes(
|
||
|
attribute.Bool("instrumentationEnabled", a.opts.LogRequests)))
|
||
|
defer span.End()
|
||
|
|
||
|
if a.opts.LogRequests {
|
||
|
a.opts.UnaryInterceptors = append(a.opts.UnaryInterceptors,
|
||
|
grpclogging.UnaryServerInterceptor(NewGRPCContextLogger(a.ctx)))
|
||
|
a.opts.StreamInterceptors = append(a.opts.StreamInterceptors,
|
||
|
grpclogging.StreamServerInterceptor(NewGRPCContextLogger(a.ctx)))
|
||
|
span.SetStatus(codes.Ok, "")
|
||
|
}
|
||
|
}
|