-
Notifications
You must be signed in to change notification settings - Fork 12
/
utils.go
131 lines (118 loc) · 4.25 KB
/
utils.go
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package tracing
import (
"context"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/openline-ai/openline-customer-os/packages/server/customer-os-common-module/common"
"github.com/openline-ai/openline-customer-os/packages/server/customer-os-common-module/constants"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
"google.golang.org/grpc/metadata"
"net/http"
)
const (
SpanTagTenant = "tenant"
SpanTagUserId = "user-id"
SpanTagUserEmail = "user-email"
SpanTagEntityId = "entity-id"
SpanTagComponent = "component"
SpanTagExternalSystem = "external-system"
SpanTagAggregateId = "aggregateID"
)
func TracingEnhancer(ctx context.Context, endpoint string) func(c *gin.Context) {
return func(c *gin.Context) {
ctxWithSpan, span := StartHttpServerTracerSpanWithHeader(ctx, endpoint, c.Request.Header)
for k, v := range c.Request.Header {
span.LogFields(log.String("request.header.key", k), log.Object("request.header.value", v))
}
defer span.Finish()
c.Request = c.Request.WithContext(ctxWithSpan)
c.Next()
}
}
func StartHttpServerTracerSpanWithHeader(ctx context.Context, operationName string, headers http.Header) (context.Context, opentracing.Span) {
spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(headers))
if err != nil {
serverSpan := opentracing.GlobalTracer().StartSpan(operationName)
opentracing.GlobalTracer().Inject(serverSpan.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(headers))
return opentracing.ContextWithSpan(ctx, serverSpan), serverSpan
}
serverSpan := opentracing.GlobalTracer().StartSpan(operationName, ext.RPCServerOption(spanCtx))
return opentracing.ContextWithSpan(ctx, serverSpan), serverSpan
}
func InjectSpanContextIntoGrpcMetadata(ctx context.Context, span opentracing.Span) context.Context {
if span != nil {
// Inject the span context into the gRPC request metadata.
textMapCarrier := make(opentracing.TextMapCarrier)
err := span.Tracer().Inject(span.Context(), opentracing.TextMap, textMapCarrier)
if err == nil {
// Add the injected metadata to the gRPC context.
md, ok := metadata.FromOutgoingContext(ctx)
if !ok {
md = metadata.New(nil)
}
for key, val := range textMapCarrier {
md.Set(key, val)
}
ctx = metadata.NewOutgoingContext(ctx, md)
return ctx
}
}
return ctx
}
func InjectSpanContextIntoHTTPRequest(req *http.Request, span opentracing.Span) *http.Request {
if span != nil {
// Prepare to inject span context into HTTP headers
tracer := span.Tracer()
textMapCarrier := opentracing.HTTPHeadersCarrier(req.Header)
// Inject the span context into the HTTP headers
err := tracer.Inject(span.Context(), opentracing.HTTPHeaders, textMapCarrier)
if err != nil {
// Log error or handle it as per the application's error handling strategy
fmt.Println("Error injecting span context into headers:", err)
}
}
return req
}
func setDefaultSpanTags(ctx context.Context, span opentracing.Span) {
tenant := common.GetTenantFromContext(ctx)
loggedInUserId := common.GetUserIdFromContext(ctx)
loggedInUserEmail := common.GetUserEmailFromContext(ctx)
if tenant != "" {
span.SetTag(SpanTagTenant, tenant)
}
if loggedInUserId != "" {
span.SetTag(SpanTagUserId, loggedInUserId)
}
if loggedInUserEmail != "" {
span.SetTag(SpanTagUserEmail, loggedInUserEmail)
}
}
func SetDefaultServiceSpanTags(ctx context.Context, span opentracing.Span) {
setDefaultSpanTags(ctx, span)
span.SetTag(SpanTagComponent, constants.ComponentService)
}
func SetDefaultNeo4jRepositorySpanTags(ctx context.Context, span opentracing.Span) {
setDefaultSpanTags(ctx, span)
span.SetTag(SpanTagComponent, constants.ComponentNeo4jRepository)
}
func TraceErr(span opentracing.Span, err error, fields ...log.Field) {
// Log the error with the fields
if span == nil {
return
}
ext.LogError(span, err, fields...)
}
func LogObjectAsJson(span opentracing.Span, name string, object any) {
if object == nil {
span.LogFields(log.String(name, "nil"))
}
jsonObject, err := json.Marshal(object)
if err == nil {
span.LogFields(log.String(name, string(jsonObject)))
} else {
span.LogFields(log.Object(name, object))
}
}