Skip to content

Commit

Permalink
Merge pull request #99 from K-Phoen/graphite-support
Browse files Browse the repository at this point in the history
Graphite support
  • Loading branch information
K-Phoen authored Mar 27, 2021
2 parents e5dfec3 + 21dabd3 commit 7ae66b7
Show file tree
Hide file tree
Showing 18 changed files with 332 additions and 2 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ up:
-p 9090:9090 \
-v $(shell pwd)/testdata/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
docker run -d\
--name graphite\
--restart=always\
-p 8081:80\
-p 2003-2004:2003-2004\
-p 2023-2024:2023-2024\
-p 8125:8125/udp\
-p 8126:8126\
graphiteapp/graphite-statsd
docker run -d \
-p 3000:3000 \
--name=grabana_grafana \
Expand Down
124 changes: 124 additions & 0 deletions decoder/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestUnmarshalYAML(t *testing.T) {
tablePanel(),
graphPanelWithStackdriverTarget(),
heatmapPanel(),
graphPanelWithGraphiteTarget(),
}

for _, testCase := range testCases {
Expand Down Expand Up @@ -1165,6 +1166,129 @@ rows:
}
}

func graphPanelWithGraphiteTarget() testCase {
yaml := `title: Awesome dashboard
rows:
- name: Test row
panels:
- graph:
title: Packets received
datasource: graphite-test
targets:
- graphite:
ref: A
query: stats_counts.statsd.packets_received
`
json := `{
"slug": "",
"title": "Awesome dashboard",
"originalTitle": "",
"tags": null,
"style": "dark",
"timezone": "",
"editable": false,
"hideControls": false,
"sharedCrosshair": false,
"templating": {"list": null},
"annotations": {"list": null},
"links": null,
"panels": null,
"rows": [
{
"title": "Test row",
"collapse": false,
"editable": true,
"height": "250px",
"repeat": null,
"showTitle": true,
"panels": [
{
"type": "graph",
"datasource": "graphite-test",
"editable": false,
"error": false,
"gridPos": {},
"id": 8,
"isNew": false,
"renderer": "flot",
"span": 6,
"fill": 1,
"title": "Packets received",
"aliasColors": {},
"bars": false,
"points": false,
"stack": false,
"steppedLine": false,
"lines": true,
"linewidth": 1,
"pointradius": 5,
"percentage": false,
"nullPointMode": "null as zero",
"legend": {
"alignAsTable": false,
"avg": false,
"current": false,
"hideEmpty": true,
"hideZero": true,
"max": false,
"min": false,
"rightSide": false,
"show": true,
"total": false,
"values": false
},
"targets": [
{
"refId": "A",
"target": "stats_counts.statsd.packets_received"
}
],
"tooltip": {
"shared": true,
"value_type": "",
"sort": 2
},
"x-axis": true,
"y-axis": true,
"xaxis": {
"format": "time",
"logBase": 1,
"show": true
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": false
}
],
"transparent": false
}
]
}
],
"time": {"from": "now-3h", "to": "now"},
"timepicker": {
"refresh_intervals": ["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],
"time_options": ["5m","15m","1h","6h","12h","24h","2d","7d","30d"]
},
"schemaVersion": 0,
"version": 0
}`

return testCase{
name: "single row with single graph panel and graphite target",
yaml: yaml,
expectedGrafanaJSON: json,
}
}

func singleStatPanel() testCase {
yaml := `title: Awesome dashboard
Expand Down
3 changes: 3 additions & 0 deletions decoder/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ func (graphPanel *DashboardGraph) target(t Target) (graph.Option, error) {
if t.Prometheus != nil {
return graph.WithPrometheusTarget(t.Prometheus.Query, t.Prometheus.toOptions()...), nil
}
if t.Graphite != nil {
return graph.WithGraphiteTarget(t.Graphite.Query, t.Graphite.toOptions()...), nil
}
if t.Stackdriver != nil {
stackdriverTarget, err := t.Stackdriver.toTarget()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions decoder/heatmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ func (heatmapPanel DashboardHeatmap) target(t Target) (heatmap.Option, error) {
if t.Prometheus != nil {
return heatmap.WithPrometheusTarget(t.Prometheus.Query, t.Prometheus.toOptions()...), nil
}
if t.Graphite != nil {
return heatmap.WithGraphiteTarget(t.Graphite.Query, t.Graphite.toOptions()...), nil
}
if t.Stackdriver != nil {
stackdriverTarget, err := t.Stackdriver.toTarget()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions decoder/singlestat.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ func (singleStatPanel DashboardSingleStat) target(t Target) (singlestat.Option,
if t.Prometheus != nil {
return singlestat.WithPrometheusTarget(t.Prometheus.Query, t.Prometheus.toOptions()...), nil
}
if t.Graphite != nil {
return singlestat.WithGraphiteTarget(t.Graphite.Query, t.Graphite.toOptions()...), nil
}
if t.Stackdriver != nil {
stackdriverTarget, err := t.Stackdriver.toTarget()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions decoder/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ func (tablePanel *DashboardTable) target(t Target) (table.Option, error) {
if t.Prometheus != nil {
return table.WithPrometheusTarget(t.Prometheus.Query, t.Prometheus.toOptions()...), nil
}
if t.Graphite != nil {
return table.WithGraphiteTarget(t.Graphite.Query, t.Graphite.toOptions()...), nil
}

return nil, ErrTargetNotConfigured
}
20 changes: 20 additions & 0 deletions decoder/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package decoder
import (
"fmt"

"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/prometheus"
"github.com/K-Phoen/grabana/target/stackdriver"
)
Expand All @@ -14,6 +15,7 @@ var ErrInvalidStackdriverAlignment = fmt.Errorf("invalid stackdriver alignment m

type Target struct {
Prometheus *PrometheusTarget `yaml:",omitempty"`
Graphite *GraphiteTarget `yaml:",omitempty"`
Stackdriver *StackdriverTarget `yaml:",omitempty"`
}

Expand Down Expand Up @@ -56,6 +58,24 @@ func (t PrometheusTarget) toOptions() []prometheus.Option {
return opts
}

type GraphiteTarget struct {
Query string
Ref string `yaml:",omitempty"`
Hidden bool `yaml:",omitempty"`
}

func (t GraphiteTarget) toOptions() []graphite.Option {
opts := []graphite.Option{
graphite.Ref(t.Ref),
}

if t.Hidden {
opts = append(opts, graphite.Hide())
}

return opts
}

type StackdriverTarget struct {
Project string
Type string
Expand Down
25 changes: 23 additions & 2 deletions decoder/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package decoder
import (
"testing"

"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/prometheus"

"github.com/K-Phoen/grabana/target/stackdriver"

"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -273,3 +272,25 @@ func TestPrometheusComplexTarget(t *testing.T) {
req.Equal(1/10, target.IntervalFactor)
}
}

func TestGraphiteTarget(t *testing.T) {
req := require.New(t)

opts := GraphiteTarget{
Query: "stats_counts.statsd.packets_received",
Ref: "A",
}.toOptions()
target := graphite.New("query", opts...)

req.False(target.Builder.Hide)
req.Equal("A", target.Builder.RefID)
}

func TestGraphiteHiddenTarget(t *testing.T) {
req := require.New(t)

opts := GraphiteTarget{Hidden: true}.toOptions()
target := graphite.New("query", opts...)

req.True(target.Builder.Hide)
}
10 changes: 10 additions & 0 deletions graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package graph
import (
"github.com/K-Phoen/grabana/alert"
"github.com/K-Phoen/grabana/axis"
"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/prometheus"
"github.com/K-Phoen/grabana/target/stackdriver"
"github.com/grafana-tools/sdk"
Expand Down Expand Up @@ -128,6 +129,15 @@ func WithPrometheusTarget(query string, options ...prometheus.Option) Option {
}
}

// WithGraphiteTarget adds a Graphite target to the table.
func WithGraphiteTarget(query string, options ...graphite.Option) Option {
target := graphite.New(query, options...)

return func(graph *Graph) {
graph.Builder.AddTarget(target.Builder)
}
}

// WithStackdriverTarget adds a stackdriver query to the graph.
func WithStackdriverTarget(target *stackdriver.Stackdriver) Option {
return func(graph *Graph) {
Expand Down
8 changes: 8 additions & 0 deletions graph/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ func TestGraphPanelCanHavePrometheusTargets(t *testing.T) {
req.Len(panel.Builder.GraphPanel.Targets, 1)
}

func TestGraphPanelPanelCanHaveGraphiteTargets(t *testing.T) {
req := require.New(t)

panel := New("", WithGraphiteTarget("stats_counts.statsd.packets_received"))

req.Len(panel.Builder.GraphPanel.Targets, 1)
}

func TestGraphPanelCanHaveStackdriverTargets(t *testing.T) {
req := require.New(t)

Expand Down
10 changes: 10 additions & 0 deletions heatmap/heatmap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package heatmap

import (
"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/prometheus"
"github.com/K-Phoen/grabana/target/stackdriver"
"github.com/grafana-tools/sdk"
Expand Down Expand Up @@ -136,6 +137,15 @@ func WithPrometheusTarget(query string, options ...prometheus.Option) Option {
}
}

// WithGraphiteTarget adds a Graphite target to the table.
func WithGraphiteTarget(query string, options ...graphite.Option) Option {
target := graphite.New(query, options...)

return func(heatmap *Heatmap) {
heatmap.Builder.AddTarget(target.Builder)
}
}

// WithStackdriverTarget adds a stackdriver query to the graph.
func WithStackdriverTarget(target *stackdriver.Stackdriver) Option {
return func(heatmap *Heatmap) {
Expand Down
8 changes: 8 additions & 0 deletions heatmap/heatmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ func TestHeatmapPanelCanHavePrometheusTargets(t *testing.T) {
req.Len(panel.Builder.HeatmapPanel.Targets, 1)
}

func TestHeatmapPanelPanelCanHaveGraphiteTargets(t *testing.T) {
req := require.New(t)

panel := New("", WithGraphiteTarget("stats_counts.statsd.packets_received"))

req.Len(panel.Builder.HeatmapPanel.Targets, 1)
}

func TestHeatmapPanelCanHaveStackdriverTargets(t *testing.T) {
req := require.New(t)

Expand Down
10 changes: 10 additions & 0 deletions singlestat/singlestat.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package singlestat
import (
"strings"

"github.com/K-Phoen/grabana/target/graphite"
"github.com/K-Phoen/grabana/target/prometheus"
"github.com/K-Phoen/grabana/target/stackdriver"
"github.com/grafana-tools/sdk"
Expand Down Expand Up @@ -147,6 +148,15 @@ func WithPrometheusTarget(query string, options ...prometheus.Option) Option {
}
}

// WithGraphiteTarget adds a Graphite target to the table.
func WithGraphiteTarget(query string, options ...graphite.Option) Option {
target := graphite.New(query, options...)

return func(singleStat *SingleStat) {
singleStat.Builder.AddTarget(target.Builder)
}
}

// WithStackdriverTarget adds a stackdriver query to the graph.
func WithStackdriverTarget(target *stackdriver.Stackdriver) Option {
return func(singleStat *SingleStat) {
Expand Down
8 changes: 8 additions & 0 deletions singlestat/singlestat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ func TestSingleStatPanelCanHavePrometheusTargets(t *testing.T) {
req.Len(panel.Builder.SinglestatPanel.Targets, 1)
}

func TestSingleStatPanelPanelCanHaveGraphiteTargets(t *testing.T) {
req := require.New(t)

panel := New("", WithGraphiteTarget("stats_counts.statsd.packets_received"))

req.Len(panel.Builder.SinglestatPanel.Targets, 1)
}

func TestSingleStatPanelCanHaveStackdriverTargets(t *testing.T) {
req := require.New(t)

Expand Down
Loading

0 comments on commit 7ae66b7

Please sign in to comment.