-
Notifications
You must be signed in to change notification settings - Fork 24
/
checkhttp-labels.go
90 lines (82 loc) · 2.91 KB
/
checkhttp-labels.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
package checkhttp
import (
"strconv"
"strings"
flowcontrolhttpv1 "github.com/fluxninja/aperture/v2/api/gen/proto/go/aperture/flowcontrol/checkhttp/v1"
flowlabel "github.com/fluxninja/aperture/v2/pkg/policies/flowcontrol/label"
)
const (
requestLabelPrefix = "http."
requestLabelHeaderPrefix = "http.request.header."
// Number of always-added request labels (this value is used only for
// capacity estimation).
numRequestLabels = 6
)
// CheckHTTPRequestToFlowLabels converts request attributes to new FlowLabels.
// It takes a flowcontrolhttpv1.CheckHTTPRequest_HttpRequest object as input and returns a flowlabel.FlowLabels object.
// The function adds several labels to the flowlabel.FlowLabels object based on the attributes of the flowcontrolhttpv1.CheckHTTPRequest_HttpRequest object.
// If the request is nil, the function returns an empty flowlabel.FlowLabels object.
func CheckHTTPRequestToFlowLabels(request *flowcontrolhttpv1.CheckHTTPRequest_HttpRequest) flowlabel.FlowLabels {
if request == nil {
return flowlabel.FlowLabels{}
}
capacity := numRequestLabels + len(request.GetHeaders())
flowLabels := make(flowlabel.FlowLabels, capacity)
flowLabels[requestLabelPrefix+"method"] = flowlabel.FlowLabelValue{
Value: request.GetMethod(),
Telemetry: true,
}
flowLabels[requestLabelPrefix+"target"] = flowlabel.FlowLabelValue{
Value: request.GetPath(),
Telemetry: true,
}
flowLabels[requestLabelPrefix+"host"] = flowlabel.FlowLabelValue{
Value: request.GetHost(),
Telemetry: true,
}
flowLabels[requestLabelPrefix+"scheme"] = flowlabel.FlowLabelValue{
Value: request.GetScheme(),
Telemetry: true,
}
flowLabels[requestLabelPrefix+"request_content_length"] = flowlabel.FlowLabelValue{
Value: strconv.FormatInt(request.GetSize(), 10),
Telemetry: false,
}
flowLabels[requestLabelPrefix+"flavor"] = flowlabel.FlowLabelValue{
Value: canonicalizeOtelHTTPFlavor(request.GetProtocol()),
Telemetry: true,
}
for k, v := range request.GetHeaders() {
if strings.HasPrefix(k, ":") {
// Headers starting with `:` are pseudoheaders, so we do not add
// them. We do not lose anything, as these values are already
// available as labels pulled from dedicated fields of
// Request.Http.
continue
}
flowLabels[requestLabelHeaderPrefix+canonicalizeOtelHeaderKey(k)] = flowlabel.FlowLabelValue{
Value: v,
Telemetry: false,
}
}
return flowLabels
}
// canonicalizeOtelHeaderKey converts header naming convention to Otel's one.
func canonicalizeOtelHeaderKey(key string) string {
return strings.ReplaceAll(strings.ToLower(key), "-", "_")
}
// canonicalizeOtelHTTPFlavor converts protocol to Otel kind of HTTP protocol.
func canonicalizeOtelHTTPFlavor(protocolName string) string {
switch protocolName {
case "HTTP/1.0":
return "1.0"
case "HTTP/1.1":
return "1.1"
case "HTTP/2":
return "2.0"
case "HTTP/3":
return "3.0"
default:
return protocolName
}
}