mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 21:24:05 -08:00
Add functions for regex replacement, sorting and humanizing.
Change-Id: I471c7a8087cd5432b51afce811b591b11583a0c3
This commit is contained in:
parent
d085de5a69
commit
9b74324d9e
|
@ -17,6 +17,9 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
clientmodel "github.com/prometheus/client_golang/model"
|
clientmodel "github.com/prometheus/client_golang/model"
|
||||||
|
@ -34,6 +37,23 @@ type sample struct {
|
||||||
}
|
}
|
||||||
type queryResult []*sample
|
type queryResult []*sample
|
||||||
|
|
||||||
|
type queryResultByLabelSorter struct {
|
||||||
|
results queryResult
|
||||||
|
by string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q queryResultByLabelSorter) Len() int {
|
||||||
|
return len(q.results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q queryResultByLabelSorter) Less(i, j int) bool {
|
||||||
|
return q.results[i].Labels[q.by] < q.results[j].Labels[q.by]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q queryResultByLabelSorter) Swap(i, j int) {
|
||||||
|
q.results[i], q.results[j] = q.results[j], q.results[i]
|
||||||
|
}
|
||||||
|
|
||||||
// Expand a template, using the given data, time and storage.
|
// Expand a template, using the given data, time and storage.
|
||||||
func Expand(text string, name string, data interface{}, timestamp clientmodel.Timestamp, storage metric.PreloadingPersistence) (result string, resultErr error) {
|
func Expand(text string, name string, data interface{}, timestamp clientmodel.Timestamp, storage metric.PreloadingPersistence) (result string, resultErr error) {
|
||||||
|
|
||||||
|
@ -68,6 +88,55 @@ func Expand(text string, name string, data interface{}, timestamp clientmodel.Ti
|
||||||
"strvalue": func(s *sample) string {
|
"strvalue": func(s *sample) string {
|
||||||
return s.Labels["__value__"]
|
return s.Labels["__value__"]
|
||||||
},
|
},
|
||||||
|
"reReplaceAll": func(pattern, repl, text string) string {
|
||||||
|
re := regexp.MustCompile(pattern)
|
||||||
|
return re.ReplaceAllString(text, repl)
|
||||||
|
},
|
||||||
|
"sortByLabel": func(label string, v queryResult) queryResult {
|
||||||
|
sorter := queryResultByLabelSorter{v[:], label}
|
||||||
|
sort.Stable(sorter)
|
||||||
|
return v
|
||||||
|
},
|
||||||
|
"humanize": func(v float64) string {
|
||||||
|
if v == 0 {
|
||||||
|
return fmt.Sprintf("%.4g ", v)
|
||||||
|
}
|
||||||
|
if math.Abs(v) >= 1 {
|
||||||
|
prefix := ""
|
||||||
|
for _, p := range []string{"k", "M", "G", "T", "P", "E", "Z", "Y"} {
|
||||||
|
if math.Abs(v) < 1000 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prefix = p
|
||||||
|
v /= 1000
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.4g %s", v, prefix)
|
||||||
|
} else {
|
||||||
|
prefix := ""
|
||||||
|
for _, p := range []string{"m", "u", "n", "p", "f", "a", "z", "y"} {
|
||||||
|
if math.Abs(v) >= 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prefix = p
|
||||||
|
v *= 1000
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.4g %s", v, prefix)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"humanize1024": func(v float64) string {
|
||||||
|
if math.Abs(v) <= 1 {
|
||||||
|
return fmt.Sprintf("%.4g ", v)
|
||||||
|
}
|
||||||
|
prefix := ""
|
||||||
|
for _, p := range []string{"ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"} {
|
||||||
|
if math.Abs(v) < 1024 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prefix = p
|
||||||
|
v /= 1024
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.4g %s", v, prefix)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
|
@ -69,6 +69,26 @@ func TestTemplateExpansion(t *testing.T) {
|
||||||
text: "{{ (query \"missing\").banana }}",
|
text: "{{ (query \"missing\").banana }}",
|
||||||
shouldFail: true,
|
shouldFail: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Regex replacement.
|
||||||
|
text: "{{ reReplaceAll \"(a)b\" \"x$1\" \"ab\" }}",
|
||||||
|
output: "xa",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Sorting.
|
||||||
|
text: "{{ range query \"metric\" | sortByLabel \"instance\" }}{{.Labels.instance}} {{end}}",
|
||||||
|
output: "a b ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Humanize.
|
||||||
|
text: "{{ 0.0 | humanize }}:{{ 1.0 | humanize }}:{{ 1234567.0 | humanize }}:{{ .12 | humanize }}",
|
||||||
|
output: "0 :1 :1.235 M:120 m",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Humanize1024.
|
||||||
|
text: "{{ 0.0 | humanize1024 }}:{{ 1.0 | humanize1024 }}:{{ 1048576.0 | humanize1024 }}:{{ .12 | humanize1024}}",
|
||||||
|
output: "0 :1 :1 Mi:0.12 ",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
time := clientmodel.Timestamp(0)
|
time := clientmodel.Timestamp(0)
|
||||||
|
|
Loading…
Reference in a new issue