File: rpc_api.go

package info (click to toggle)
gitlab-agent 16.1.3-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 6,324 kB
  • sloc: makefile: 175; sh: 52; ruby: 3
file content (80 lines) | stat: -rw-r--r-- 2,393 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package kasapp

import (
	"context"
	"sync"

	"github.com/getsentry/sentry-go"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v16/internal/module/modserver"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v16/internal/module/modshared"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v16/internal/tool/grpctool"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v16/internal/tool/logz"
	"go.opentelemetry.io/otel/trace"
	"go.uber.org/zap"
)

type serverRpcApi struct {
	modshared.RpcApiStub
	sentryHubRoot *sentry.Hub

	service string
	method  string
	traceID trace.TraceID

	sentryHubOnce sync.Once
	sentryHub     SentryHub
	transaction   string
}

func (a *serverRpcApi) HandleProcessingError(log *zap.Logger, agentId int64, msg string, err error) {
	handleProcessingError(a.StreamCtx, a.hub, log, agentId, msg, err)
}

func (a *serverRpcApi) HandleIoError(log *zap.Logger, msg string, err error) error {
	// The problem is almost certainly with the client's connection.
	// Still log it on Debug.
	log.Debug(msg, logz.Error(err))
	return grpctool.HandleIoError(msg, err)
}

func (a *serverRpcApi) hub() (SentryHub, string) {
	a.sentryHubOnce.Do(a.hubOnce)
	return a.sentryHub, a.transaction
}

func (a *serverRpcApi) hubOnce() {
	hub := a.sentryHubRoot.Clone()
	scope := hub.Scope()
	scope.SetTag(modserver.GrpcServiceSentryField, a.service)
	scope.SetTag(modserver.GrpcMethodSentryField, a.method)
	a.transaction = a.service + "::" + a.method                            // Like in Gitaly
	scope.SetFingerprint([]string{"{{ default }}", "grpc", a.transaction}) // use Sentry's default error hash but also split by gRPC transaction
	if a.traceID.IsValid() {
		scope.SetTag(modserver.SentryFieldTraceId, a.traceID.String())
	}
	a.sentryHub = hub
}

type serverRpcApiFactory struct {
	log       *zap.Logger
	sentryHub *sentry.Hub
}

func (f *serverRpcApiFactory) New(ctx context.Context, fullMethodName string) modserver.RpcApi {
	service, method := grpctool.SplitGrpcMethod(fullMethodName)
	traceID := trace.SpanContextFromContext(ctx).TraceID()
	return &serverRpcApi{
		RpcApiStub: modshared.RpcApiStub{
			Logger: f.log.With(
				logz.TraceId(traceID),
				logz.GrpcService(service),
				logz.GrpcMethod(method),
			),
			StreamCtx: ctx,
		},
		sentryHubRoot: f.sentryHub,
		service:       service,
		method:        method,
		traceID:       traceID,
	}
}