mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-10-20 06:28:13 +00:00
Initial commit on gh-pages
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
package libpack_monitoring
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
||||
libpack_config "github.com/lukaszraczylo/graphql-monitoring-proxy/config"
|
||||
)
|
||||
|
||||
var sortedLabelKeysCache = struct {
|
||||
m sync.Map
|
||||
}{}
|
||||
|
||||
func (ms *MetricsSetup) get_metrics_name(name string, labels map[string]string) string {
|
||||
const unknownPodName = "unknown"
|
||||
var buf bytes.Buffer
|
||||
|
||||
podName := getPodName()
|
||||
if labels == nil {
|
||||
labels = defaultLabels(podName)
|
||||
} else {
|
||||
ensureDefaultLabels(&labels, podName)
|
||||
}
|
||||
|
||||
if ms.metrics_prefix != "" {
|
||||
buf.WriteString(ms.metrics_prefix)
|
||||
buf.WriteByte('_')
|
||||
}
|
||||
buf.WriteString(name)
|
||||
|
||||
if len(labels) > 0 {
|
||||
buf.WriteByte('{')
|
||||
appendSortedLabels(&buf, labels)
|
||||
buf.WriteByte('}')
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func getPodName() string {
|
||||
const unknownPodName = "unknown"
|
||||
if hn, err := os.Hostname(); err == nil {
|
||||
return hn
|
||||
}
|
||||
return unknownPodName
|
||||
}
|
||||
|
||||
func defaultLabels(podName string) map[string]string {
|
||||
return map[string]string{
|
||||
"microservice": libpack_config.PKG_NAME,
|
||||
"pod": podName,
|
||||
}
|
||||
}
|
||||
|
||||
func ensureDefaultLabels(labels *map[string]string, podName string) {
|
||||
if *labels == nil {
|
||||
*labels = make(map[string]string)
|
||||
}
|
||||
if _, exists := (*labels)["microservice"]; !exists {
|
||||
(*labels)["microservice"] = libpack_config.PKG_NAME
|
||||
}
|
||||
if _, exists := (*labels)["pod"]; !exists {
|
||||
(*labels)["pod"] = podName
|
||||
}
|
||||
}
|
||||
|
||||
func appendSortedLabels(buf *bytes.Buffer, labels map[string]string) {
|
||||
keys := getSortedKeys(labels)
|
||||
for i, k := range keys {
|
||||
if i > 0 {
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
buf.WriteString(k)
|
||||
buf.WriteString(`="`)
|
||||
buf.WriteString(labels[k])
|
||||
buf.WriteByte('"')
|
||||
}
|
||||
}
|
||||
|
||||
func getSortedKeys(labels map[string]string) []string {
|
||||
labelsKey := labelsToString(labels)
|
||||
|
||||
if keys, ok := sortedLabelKeysCache.m.Load(labelsKey); ok {
|
||||
return keys.([]string)
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(labels))
|
||||
for k := range labels {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
sortedLabelKeysCache.m.Store(labelsKey, keys)
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
func labelsToString(labels map[string]string) string {
|
||||
var sb strings.Builder
|
||||
for k, v := range labels {
|
||||
sb.WriteString(k)
|
||||
sb.WriteByte('=')
|
||||
sb.WriteString(v)
|
||||
sb.WriteByte(';')
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func validate_metrics_name(name string) error {
|
||||
cleanedName := clean_metric_name(name)
|
||||
|
||||
finalName := strings.Trim(cleanedName, "_")
|
||||
|
||||
if finalName != name {
|
||||
return fmt.Errorf("invalid metric name: %s, expected %s", name, finalName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func clean_metric_name(name string) string {
|
||||
var buf bytes.Buffer
|
||||
lastWasUnderscore := false
|
||||
|
||||
for _, r := range name {
|
||||
if is_allowed_rune(r) {
|
||||
if is_special_rune(r) {
|
||||
if lastWasUnderscore {
|
||||
continue
|
||||
}
|
||||
r = '_'
|
||||
lastWasUnderscore = true
|
||||
} else {
|
||||
lastWasUnderscore = false
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
} else if !lastWasUnderscore {
|
||||
buf.WriteByte('_')
|
||||
lastWasUnderscore = true
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Trim(buf.String(), "_")
|
||||
}
|
||||
|
||||
func is_allowed_rune(r rune) bool {
|
||||
return unicode.IsLetter(r) || unicode.IsDigit(r) || r == ' ' || r == '_'
|
||||
}
|
||||
|
||||
func is_special_rune(r rune) bool {
|
||||
return r == ' ' || r == '_'
|
||||
}
|
||||
|
||||
func compile_metrics_with_labels(name string, labels map[string]string) string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString(name)
|
||||
|
||||
keys := getSortedKeys(labels)
|
||||
|
||||
for _, k := range keys {
|
||||
buf.WriteByte('_')
|
||||
buf.WriteString(k)
|
||||
buf.WriteByte('_')
|
||||
buf.WriteString(labels[k])
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
Reference in New Issue
Block a user