mirror of
https://github.com/prometheus/prometheus
synced 2024-12-26 08:33:06 +00: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"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"sort"
|
||||
"text/template"
|
||||
|
||||
clientmodel "github.com/prometheus/client_golang/model"
|
||||
@ -34,6 +37,23 @@ type sample struct {
|
||||
}
|
||||
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.
|
||||
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 {
|
||||
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
|
||||
|
@ -69,6 +69,26 @@ func TestTemplateExpansion(t *testing.T) {
|
||||
text: "{{ (query \"missing\").banana }}",
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user