forked from RobustPerception/azure_metrics_exporter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.go
122 lines (107 loc) · 3.3 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
package main
import (
"encoding/json"
"fmt"
"log"
"reflect"
"regexp"
"strings"
"time"
)
var (
// resource component positions in a ResourceURL
resourceGroupPosition = 4
resourceNamePosition = 8
subResourceNamePosition = 10
resourceTypeSuffixPosition = 9
resourceTypePosition = 7
resourceTypePrefixPosition = 6
invalidLabelChars = regexp.MustCompile(`[^a-zA-Z0-9_]+`)
)
// PrintPrettyJSON - Prints structs nicely for debugging.
func PrintPrettyJSON(input map[string]interface{}) {
out, err := json.MarshalIndent(input, "", "\t")
if err != nil {
log.Fatalf("Error indenting JSON: %v", err)
}
fmt.Println(string(out))
}
// GetTimes - Returns the endTime and startTime used for querying Azure Metrics API
func GetTimes() (string, string) {
// Make sure we are using UTC
now := time.Now().UTC()
// Use query delay of 3 minutes when querying for latest metric data
endTime := now.Add(time.Minute * time.Duration(-3)).Format(time.RFC3339)
startTime := now.Add(time.Minute * time.Duration(-4)).Format(time.RFC3339)
return endTime, startTime
}
// CreateResourceLabels - Returns resource labels for a given resource URL.
func CreateResourceLabels(resourceURL string) map[string]string {
labels := make(map[string]string)
resource := strings.Split(resourceURL, "/")
labels["resource_group"] = resource[resourceGroupPosition]
labels["resource_name"] = resource[resourceNamePosition]
if len(resource) > 13 {
labels["sub_resource_name"] = resource[subResourceNamePosition]
}
return labels
}
// GetResourceType returns the resource type with the namespace
func GetResourceType(resourceURL string) string {
resource := strings.Split(resourceURL, "/")
var str strings.Builder
str.WriteString(resource[resourceTypePrefixPosition])
str.WriteString("/")
str.WriteString(resource[resourceTypePosition])
if len(resource) > 13 {
str.WriteString("/")
str.WriteString(resource[resourceTypeSuffixPosition])
}
return str.String()
}
func CreateAllResourceLabelsFrom(rm resourceMeta) map[string]string {
formatTag := "pretty"
labels := make(map[string]string)
for k, v := range rm.resource.Tags {
k = strings.ToLower(k)
k = "tag_" + k
k = invalidLabelChars.ReplaceAllString(k, "_")
labels[k] = v
}
// create a label for each field of the resource
val := reflect.ValueOf(rm.resource)
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
tag := reflect.TypeOf(rm.resource).Field(i).Tag.Get(formatTag)
if field.Kind() == reflect.String {
labels[tag] = field.String()
}
}
// Most labels are handled by iterating over the fields of resourceMeta.AzureResource.
// Their tag values are used as label keys.
// To keep coherence with the metric labels, we create "resource_group", "resource_name"
// and "sub_resource_name" by invoking CreateResourceLabels.
resourceLabels := CreateResourceLabels(rm.resourceURL)
for k, v := range resourceLabels {
labels[k] = v
}
return labels
}
func hasAggregation(aggregations []string, aggregation string) bool {
if len(aggregations) == 0 {
return true
}
for _, aggr := range aggregations {
if aggr == aggregation {
return true
}
}
return false
}
func filterAggregations(aggregations []string) []string {
base := []string{"Total", "Average", "Minimum", "Maximum"}
if len(aggregations) > 0 {
return aggregations
}
return base
}