Commit
+38 -4 +/-2 browse
1 | diff --git a/go.mod b/go.mod |
2 | index 68f1007..30832a3 100644 |
3 | --- a/go.mod |
4 | +++ b/go.mod |
5 | @@ -3,7 +3,7 @@ module git.sr.ht/~sircmpwn/chartsrv |
6 | go 1.15 |
7 | |
8 | require ( |
9 | - github.com/dustin/go-humanize v1.0.0 // indirect |
10 | + github.com/dustin/go-humanize v1.0.0 |
11 | github.com/go-chi/chi v4.1.2+incompatible |
12 | gonum.org/v1/plot v0.8.0 |
13 | ) |
14 | diff --git a/main.go b/main.go |
15 | index 12c5491..c1ffa77 100644 |
16 | --- a/main.go |
17 | +++ b/main.go |
18 | @@ -1,6 +1,7 @@ |
19 | package main |
20 | |
21 | import ( |
22 | + "bytes" |
23 | "encoding/json" |
24 | "fmt" |
25 | "image/color" |
26 | @@ -11,6 +12,7 @@ import ( |
27 | "sort" |
28 | "strconv" |
29 | "strings" |
30 | + "text/template" |
31 | "time" |
32 | |
33 | "github.com/dustin/go-humanize" |
34 | @@ -126,6 +128,30 @@ func metricName(metric map[string]string) string { |
35 | return out + "{" + strings.Join(inner, ",") + "}" |
36 | } |
37 | |
38 | + func handleLabel(p *plot.Plot, l *plotter.Line, label string, metric string) { |
39 | + raw := metric[1 : len(metric)-1] |
40 | + raw_tags := strings.Split(raw, ",") |
41 | + tags := make(map[string]string) |
42 | + for _, v := range raw_tags { |
43 | + tag := strings.Split(v, "=") |
44 | + if len(tag) != 2 { |
45 | + log.Printf("Expected tag format: 'name=value'!") |
46 | + continue |
47 | + } |
48 | + if len(tag[1]) > 2 && tag[1][0] == '"' && tag[1][len(tag[1])-1] == '"' { |
49 | + tags[tag[0]] = tag[1][1 : len(tag[1])-1] |
50 | + } |
51 | + } |
52 | + tmpl, err := template.New("label").Parse(label) |
53 | + if err != nil { |
54 | + log.Printf("Failed to parse label template: ", err) |
55 | + } else { |
56 | + var label_out bytes.Buffer |
57 | + tmpl.Execute(&label_out, tags) |
58 | + p.Legend.Add(label_out.String(), l) |
59 | + } |
60 | + } |
61 | + |
62 | func registerExtension(router chi.Router, extension string, mime string) { |
63 | router.Get("/chart."+extension, func(w http.ResponseWriter, r *http.Request) { |
64 | args := r.URL.Query() |
65 | @@ -166,8 +192,14 @@ func registerExtension(router chi.Router, extension string, mime string) { |
66 | legend = l[0] |
67 | } |
68 | |
69 | + // Label template |
70 | + var label string |
71 | + if l, ok := args["label"]; ok { |
72 | + label = l[0] |
73 | + } |
74 | + |
75 | // Set step so that there's approximately 25 data points per inch |
76 | - step := int(end.Sub(start).Seconds() / (25 * float64(width / vg.Inch))) |
77 | + step := int(end.Sub(start).Seconds() / (25 * float64(width/vg.Inch))) |
78 | if s, ok := args["step"]; ok { |
79 | d, _ := strconv.ParseInt(s[0], 10, 32) |
80 | step = int(d) |
81 | @@ -229,7 +261,7 @@ func registerExtension(router chi.Router, extension string, mime string) { |
82 | } |
83 | if stacked { |
84 | l.FillColor = colors[nextColor] |
85 | - if i != len(data) - 1 { |
86 | + if i != len(data)-1 { |
87 | l.Color = color.RGBA{0, 0, 0, 0} |
88 | } |
89 | } else { |
90 | @@ -240,7 +272,9 @@ func registerExtension(router chi.Router, extension string, mime string) { |
91 | nextColor = 0 |
92 | } |
93 | plotters[i] = l |
94 | - if legend != "" { |
95 | + if label != "" && len(res.Metric) > 2 && res.Metric[0] == '{' && res.Metric[len(res.Metric)-1] == '}' { |
96 | + handleLabel(p, l, label, res.Metric) |
97 | + } else if legend != "" { |
98 | p.Legend.Add(legend, l) |
99 | } else { |
100 | p.Legend.Add(res.Metric, l) |