-
Notifications
You must be signed in to change notification settings - Fork 2
/
middleware.go
88 lines (77 loc) · 2.98 KB
/
middleware.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
package main
import (
"config-service/utils/consts"
"net/http"
"strings"
"time"
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/exp/slices"
)
//////////////////////////////////////////middleware handlers//////////////////////////////////////////
// authenticate middleware for request authentication
func authenticate(c *gin.Context) {
cookieVal, err := c.Cookie(consts.CustomerGUID)
customerValues := strings.Split(cookieVal, ";")
customerGuid := customerValues[0]
if err != nil || customerGuid == "" {
customerGuid = c.Query(consts.CustomerGUID)
if customerGuid == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
}
c.Set(consts.CustomerGUID, customerGuid)
if len(customerValues) > 1 && slices.Contains(customerValues[1:], consts.AdminAccess) {
c.Set(consts.AdminAccess, true)
}
c.Next()
}
// traceAttributesNHeader middleware adds tracing header in response and request attributes in span
func traceAttributesNHeader(c *gin.Context) {
otel.GetTextMapPropagator().Inject(c.Request.Context(), propagation.HeaderCarrier(c.Writer.Header()))
if trace.SpanFromContext(c.Request.Context()).SpanContext().IsValid() {
trace.SpanFromContext(c.Request.Context()).SetAttributes(attribute.String(consts.CustomerGUID, c.GetString(consts.CustomerGUID)))
}
c.Next()
}
// requestLogger middleware adds a logger with request attributes to the context
func requestLoggerWithFields(c *gin.Context) {
fields := []zapcore.Field{
zap.String("method", c.Request.Method),
zap.String("query", c.Request.URL.RawQuery),
zap.String("path", c.Request.URL.Path),
}
fields = append(fields, telemetryLogFields(c)...)
c.Set(consts.ReqLogger, zapLogger.WithOptions(zap.Fields(fields...)))
c.Next()
}
// requestSummary middleware logs request summary after request is served
func requestSummary() func(c *gin.Context) {
return ginzap.GinzapWithConfig(zapInfoLevelLogger, &ginzap.Config{
UTC: true,
TimeFormat: time.RFC3339,
Context: telemetryLogFields,
})
}
/////////////////////////////////////helper functions/////////////////////////////////////
// telemetryLogFields returns telemetry and customer id fields for logging
func telemetryLogFields(c *gin.Context) []zapcore.Field {
fields := []zapcore.Field{}
// log request ID
if customerGUID := c.GetString(consts.CustomerGUID); customerGUID != "" {
fields = append(fields, zap.String(consts.CustomerGUID, customerGUID))
}
// log trace and span ID
if trace.SpanFromContext(c.Request.Context()).SpanContext().IsValid() {
fields = append(fields, zap.String("trace_id", trace.SpanFromContext(c.Request.Context()).SpanContext().TraceID().String()))
fields = append(fields, zap.String("span_id", trace.SpanFromContext(c.Request.Context()).SpanContext().SpanID().String()))
}
return fields
}