diff --git a/dashboards.go b/dashboards.go index 0c06e35..6445536 100644 --- a/dashboards.go +++ b/dashboards.go @@ -126,14 +126,27 @@ type Metric struct { Query string `json:"query,omitempty"` Legend string `json:"legend,omitempty"` } +type metricQuery struct { + Type string `json:"type"` + Name string `json:"-"` + HostID string `json:"-"` + ServiceName string `json:"-"` + Expression string `json:"-"` + Query string `json:"query"` + Legend string `json:"legend"` +} // MarshalJSON marshals as JSON func (m Metric) MarshalJSON() ([]byte, error) { type Alias Metric - if m.Type == "" { + switch m.Type { + case "": return []byte("null"), nil + case "query": + return json.Marshal(metricQuery(m)) + default: + return json.Marshal(Alias(m)) } - return json.Marshal(Alias(m)) } // FormatRule information @@ -155,14 +168,29 @@ type Graph struct { Query string `json:"query,omitempty"` Legend string `json:"legend,omitempty"` } +type graphQuery struct { + Type string `json:"type"` + Name string `json:"-"` + HostID string `json:"-"` + RoleFullName string `json:"-"` + IsStacked bool `json:"-"` + ServiceName string `json:"-"` + Expression string `json:"-"` + Query string `json:"query"` + Legend string `json:"legend"` +} // MarshalJSON marshals as JSON func (g Graph) MarshalJSON() ([]byte, error) { type Alias Graph - if g.Type == "" { + switch g.Type { + case "": return []byte("null"), nil + case "query": + return json.Marshal(graphQuery(g)) + default: + return json.Marshal(Alias(g)) } - return json.Marshal(Alias(g)) } // Range information diff --git a/dashboards_test.go b/dashboards_test.go index e5c2c42..584f2f9 100644 --- a/dashboards_test.go +++ b/dashboards_test.go @@ -549,3 +549,116 @@ func TestRangeMarshalJSON(t *testing.T) { } } } + +func TestMetricMarshalJSON(t *testing.T) { + tests := []struct { + m Metric + want string + }{ + { + m: Metric{ + Type: "host", + Name: "loadavg5", + HostID: "0000", + }, + want: `{"type":"host","name":"loadavg5","hostId":"0000"}`, + }, + { + m: Metric{ + Type: "service", + Name: "metric0", + ServiceName: "service0", + }, + want: `{"type":"service","name":"metric0","serviceName":"service0"}`, + }, + { + m: Metric{ + Type: "expression", + Expression: "max(role(my-service:db, loadavg5))", + }, + want: `{"type":"expression","expression":"max(role(my-service:db, loadavg5))"}`, + }, + { + m: Metric{ + Type: "query", + Query: "up{}", + Legend: "", + }, + want: `{"type":"query","query":"up{}","legend":""}`, + }, + { + m: Metric{}, + want: "null", + }, + } + for _, tt := range tests { + b, err := json.Marshal(tt.m) + if err != nil { + t.Fatal(err) + } + if s := string(b); s != tt.want { + t.Errorf("MarshalJSON(%v) = %q; want %q", tt.m, s, tt.want) + } + } +} + +func TestGraphMarshalJSON(t *testing.T) { + tests := []struct { + g Graph + want string + }{ + { + g: Graph{ + Type: "host", + Name: "loadavg5", + HostID: "0000", + }, + want: `{"type":"host","name":"loadavg5","hostId":"0000"}`, + }, + { + g: Graph{ + Type: "role", + Name: "loadavg5", + RoleFullName: "my-service:db", + IsStacked: true, + }, + want: `{"type":"role","name":"loadavg5","roleFullname":"my-service:db","isStacked":true}`, + }, + { + g: Graph{ + Type: "service", + Name: "my-metric", + ServiceName: "my-service", + }, + want: `{"type":"service","name":"my-metric","serviceName":"my-service"}`, + }, + { + g: Graph{ + Type: "expression", + Expression: "max(role(my-service:db, loadavg5))", + }, + want: `{"type":"expression","expression":"max(role(my-service:db, loadavg5))"}`, + }, + { + g: Graph{ + Type: "query", + Query: "up{}", + Legend: "{{instance}}", + }, + want: `{"type":"query","query":"up{}","legend":"{{instance}}"}`, + }, + { + g: Graph{}, + want: "null", + }, + } + for _, tt := range tests { + b, err := json.Marshal(tt.g) + if err != nil { + t.Fatal(err) + } + if s := string(b); s != tt.want { + t.Errorf("MarshalJSON(%v) = %q; want %q", tt.g, s, tt.want) + } + } +}