go-datadog-api
go-datadog-api copied to clipboard
GetDashboard Fails Fatal When Scatterplot Exists in Dashboard
When a Dashboard in Datadog contains a scatterplot, the resulting API response from GetDashboard cannot be parsed.
Error:
2019/11/01 01:32:13 GetDashboard fatal: json: cannot unmarshal object into Go struct field GraphDefinition.requests of type []datadog.GraphDefinitionRequest
Related code: https://github.com/zorkian/go-datadog-api/blob/master/dashboards.go#L163
Requests []GraphDefinitionRequest `json:"requests,omitempty"`
A scatterplot in the API response looks like the following, note the viz type of scatterplot:
{
"definition": {
"yaxis": {
"scale": "linear",
"min": "auto",
"max": "auto",
"label": "",
"includeZero": true
},
"color_by_groups": [],
"xaxis": {
"scale": "log",
"includeZero": false
},
"viz": "scatterplot",
"requests": {
"y": {
"q": "max:example.stat{*} by {example_tag}",
"aggregator": "max"
},
"x": {
"q": "max:example.stat{*} by {example_tag}",
"aggregator": "max"
}
}
}
}
As you can see "requests" is no longer a slice, causing deserialization issues.
Unfortunately I can't come up with a backwards compatible way to support scatterplots. Although I'm working on parsing this in a fork with a custom unmarshaler.
Here's the functioning change I've come up with thus far.
type GraphDefinition struct {
...
RequestsRawMessage json.RawMessage `json:"requests,omitempty"`
Requests []GraphDefinitionRequest `json:"-"`
ScatterplotRequests struct {
Y struct {
Q string `json:"q"`
Aggregator string `json:"aggregator"`
} `json:"y"`
X struct {
Q string `json:"q"`
Aggregator string `json:"aggregator"`
} `json:"x"`
} `json:"-"`
...
}
Further below I added a custom unmarshaler for GraphDefinition data:
func (gd *GraphDefinition) UnmarshalJSON(data []byte) error {
type Alias GraphDefinition
alias := &struct {
*Alias
}{
Alias: (*Alias)(gd),
}
json.Unmarshal(data, &alias)
if len(alias.RequestsRawMessage) != 0 {
if *alias.Viz == "scatterplot" {
err := json.Unmarshal(alias.RequestsRawMessage, &alias.ScatterplotRequests)
if err != nil {
panic(err)
}
} else {
err := json.Unmarshal(alias.RequestsRawMessage, &alias.Requests)
if err != nil {
panic(err)
}
}
}
return nil
}
I am also having this problem, and an additional problem with GetDashboard
the following similar output:
cannot unmarshal string into Go struct field GraphDefinition.dash.graphs.definition.group of type []string
I think that using the custom unmarshaller is a reasonable way to go forward in this issue - I'd accept a PR that implements that.
However, there is another way - using the /api/v1/dashboard
API and the related *Board
(GetBoard
, ...) methods that seem to be handling this case fine. Would that be an option for you?
@bkabrda please double check me, but when I used /api/v1/dashboard
the result was not equivalent. I'll see if I can get specific details on that again.
Am I missing something /api/v1/dashboard
isn't supported yet by this lib? I added my own functionality in a fork.