~sircmpwn/chartsrv-devel

Add label support v4 PROPOSED

Noam Preil: 3
 Add label support
 Remove undocumented legend option
 Document the label option

 5 files changed, 43 insertions(+), 12 deletions(-)
Disregard. v5 incoming.

Nov 29, 2020 21:49:48 Noam Preil <noam@pixelhero.dev>:
> ---
> README.md | 3 +++
> 1 file changed, 3 insertions(+)
> 
> diff --git a/README.md b/README.md
> index e79a46f..c4e192d 100644
> --- a/README.md
> +++ b/README.md
> @@ -35,5 +35,8 @@ set the query parameters as appropriate:
> - **width**, **height**: adjust chart dimensions in inches
> - **step**: number of seconds between data points
> - **min**, **max**: Y axis limits
> +- **label**: template for the chart legend in Go's text/template 
format. All
> +values provided by prometheus as tags are available - to label each 
matching
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/chartsrv-devel/patches/15376/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH v4 1/3] Add label support Export this patch

---
 go.mod  |  2 +-
 main.go | 40 +++++++++++++++++++++++++++++++++++++---
 todo    |  2 ++
 3 files changed, 40 insertions(+), 4 deletions(-)
 create mode 100644 todo

diff --git a/go.mod b/go.mod
index 68f1007..30832a3 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module git.sr.ht/~sircmpwn/chartsrv
go 1.15

require (
	github.com/dustin/go-humanize v1.0.0 // indirect
	github.com/dustin/go-humanize v1.0.0
	github.com/go-chi/chi v4.1.2+incompatible
	gonum.org/v1/plot v0.8.0
)
diff --git a/main.go b/main.go
index 12c5491..c1ffa77 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"image/color"
@@ -11,6 +12,7 @@ import (
	"sort"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/dustin/go-humanize"
@@ -126,6 +128,30 @@ func metricName(metric map[string]string) string {
	return out + "{" + strings.Join(inner, ",") + "}"
}

func handleLabel(p *plot.Plot, l *plotter.Line, label string, metric string) {
	raw := metric[1 : len(metric)-1]
	raw_tags := strings.Split(raw, ",")
	tags := make(map[string]string)
	for _, v := range raw_tags {
		tag := strings.Split(v, "=")
		if len(tag) != 2 {
			log.Printf("Expected tag format: 'name=value'!")
			continue
		}
		if len(tag[1]) > 2 && tag[1][0] == '"' && tag[1][len(tag[1])-1] == '"' {
			tags[tag[0]] = tag[1][1 : len(tag[1])-1]
		}
	}
	tmpl, err := template.New("label").Parse(label)
	if err != nil {
		log.Printf("Failed to parse label template: ", err)
	} else {
		var label_out bytes.Buffer
		tmpl.Execute(&label_out, tags)
		p.Legend.Add(label_out.String(), l)
	}
}

func registerExtension(router chi.Router, extension string, mime string) {
	router.Get("/chart."+extension, func(w http.ResponseWriter, r *http.Request) {
		args := r.URL.Query()
@@ -166,8 +192,14 @@ func registerExtension(router chi.Router, extension string, mime string) {
			legend = l[0]
		}

		// Label template
		var label string
		if l, ok := args["label"]; ok {
			label = l[0]
		}

		// Set step so that there's approximately 25 data points per inch
		step := int(end.Sub(start).Seconds() / (25 * float64(width / vg.Inch)))
		step := int(end.Sub(start).Seconds() / (25 * float64(width/vg.Inch)))
		if s, ok := args["step"]; ok {
			d, _ := strconv.ParseInt(s[0], 10, 32)
			step = int(d)
@@ -229,7 +261,7 @@ func registerExtension(router chi.Router, extension string, mime string) {
			}
			if stacked {
				l.FillColor = colors[nextColor]
				if i != len(data) - 1 {
				if i != len(data)-1 {
					l.Color = color.RGBA{0, 0, 0, 0}
				}
			} else {
@@ -240,7 +272,9 @@ func registerExtension(router chi.Router, extension string, mime string) {
				nextColor = 0
			}
			plotters[i] = l
			if legend != "" {
			if label != "" && len(res.Metric) > 2 && res.Metric[0] == '{' && res.Metric[len(res.Metric)-1] == '}' {
				handleLabel(p, l, label, res.Metric)
			} else if legend != "" {
				p.Legend.Add(legend, l)
			} else {
				p.Legend.Add(res.Metric, l)
diff --git a/todo b/todo
new file mode 100644
index 0000000..ff33d90
--- /dev/null
+++ b/todo
@@ -0,0 +1,2 @@
* Detect missing protocol for upstream

-- 
2.28.0

[PATCH v4 2/3] Remove undocumented legend option Export this patch

---
 main.go | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/main.go b/main.go
index c1ffa77..ab164e9 100644
--- a/main.go
+++ b/main.go
@@ -186,12 +186,6 @@ func registerExtension(router chi.Router, extension string, mime string) {
			height = vg.Length(h) * vg.Inch
		}

		// Undocumented option
		var legend string
		if l, ok := args["legend"]; ok {
			legend = l[0]
		}

		// Label template
		var label string
		if l, ok := args["label"]; ok {
@@ -274,8 +268,6 @@ func registerExtension(router chi.Router, extension string, mime string) {
			plotters[i] = l
			if label != "" && len(res.Metric) > 2 && res.Metric[0] == '{' && res.Metric[len(res.Metric)-1] == '}' {
				handleLabel(p, l, label, res.Metric)
			} else if legend != "" {
				p.Legend.Add(legend, l)
			} else {
				p.Legend.Add(res.Metric, l)
			}
-- 
2.28.0

[PATCH v4 3/3] Document the label option Export this patch

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index e79a46f..c4e192d 100644
--- a/README.md
+++ b/README.md
@@ -35,5 +35,8 @@ set the query parameters as appropriate:
- **width**, **height**: adjust chart dimensions in inches
- **step**: number of seconds between data points
- **min**, **max**: Y axis limits
- **label**: template for the chart legend in Go's text/template format. All
values provided by prometheus as tags are available - to label each matching
result by the instance, for instance, use `{{.instance}}`

[1]: https://golang.org/pkg/time/#ParseDuration
-- 
2.28.0
Disregard. v5 incoming.

Nov 29, 2020 21:49:48 Noam Preil <noam@pixelhero.dev>:
> ---
> README.md | 3 +++
> 1 file changed, 3 insertions(+)
> 
> diff --git a/README.md b/README.md
> index e79a46f..c4e192d 100644
> --- a/README.md
> +++ b/README.md
> @@ -35,5 +35,8 @@ set the query parameters as appropriate:
> - **width**, **height**: adjust chart dimensions in inches
> - **step**: number of seconds between data points
> - **min**, **max**: Y axis limits
> +- **label**: template for the chart legend in Go's text/template 
format. All
> +values provided by prometheus as tags are available - to label each 
matching