diff --git a/pkg/tsdb/stackdriver/metric_descriptors_query.go b/pkg/tsdb/stackdriver/metric_descriptors_query.go index da2e5f5d9e0..6c005d2966b 100644 --- a/pkg/tsdb/stackdriver/metric_descriptors_query.go +++ b/pkg/tsdb/stackdriver/metric_descriptors_query.go @@ -2,8 +2,11 @@ package stackdriver import ( "context" + "encoding/json" "fmt" "io/ioutil" + "net/http" + "strings" "github.com/grafana/grafana/pkg/cmd/grafana-cli/logger" "github.com/grafana/grafana/pkg/components/simplejson" @@ -29,19 +32,56 @@ func (e *StackdriverExecutor) executeMetricDescriptors(ctx context.Context, tsdb logger.Info("error2", err) return nil, err } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - logger.Info("error3", err) - return nil, err - } - defer res.Body.Close() + + data, err := e.unmarshalMetricDescriptors(res) if err != nil { return nil, err } - queryResult.Meta.Set("test", string(body)) - logger.Info("string(body)", "string(body)", string(body)) + parts := strings.Split(req.URL.Path, "/") + defaultProject := parts[3] + + table := transformMetricDescriptorResponseToTable(data) + queryResult.Tables = append(queryResult.Tables, table) result.Results[tsdbQuery.Queries[0].RefId] = queryResult + result.Results[tsdbQuery.Queries[0].RefId].Meta.Set("defaultProject", defaultProject) return result, nil } + +func transformMetricDescriptorResponseToTable(data MetricDescriptorsResponse) *tsdb.Table { + table := &tsdb.Table{ + Columns: make([]tsdb.TableColumn, 1), + Rows: make([]tsdb.RowValues, 0), + } + table.Columns[0].Text = "metricDescriptor" + + for _, r := range data.MetricDescriptors { + values := make([]interface{}, 1) + values[0] = r + table.Rows = append(table.Rows, values) + } + return table +} + +func (e *StackdriverExecutor) unmarshalMetricDescriptors(res *http.Response) (MetricDescriptorsResponse, error) { + body, err := ioutil.ReadAll(res.Body) + defer res.Body.Close() + if err != nil { + return MetricDescriptorsResponse{}, err + } + + if res.StatusCode/100 != 2 { + slog.Error("Request failed", "status", res.Status, "body", string(body)) + return MetricDescriptorsResponse{}, fmt.Errorf(string(body)) + } + + var data MetricDescriptorsResponse + err = json.Unmarshal(body, &data) + if err != nil { + slog.Error("Failed to unmarshal MetricDescriptorResponse", "error", err, "status", res.Status, "body", string(body)) + return MetricDescriptorsResponse{}, err + } + + return data, nil +} diff --git a/pkg/tsdb/stackdriver/types.go b/pkg/tsdb/stackdriver/types.go index 3821ce7ceda..de6daa5dc06 100644 --- a/pkg/tsdb/stackdriver/types.go +++ b/pkg/tsdb/stackdriver/types.go @@ -73,3 +73,24 @@ type StackdriverResponse struct { } `json:"points"` } `json:"timeSeries"` } + +type MetricDescriptorsResponse struct { + MetricDescriptors []struct { + Name string `json:"name"` + Labels []struct { + Key string `json:"key"` + Description string `json:"description"` + } `json:"labels,omitempty"` + MetricKind string `json:"metricKind"` + ValueType string `json:"valueType"` + Unit string `json:"unit,omitempty"` + Description string `json:"description"` + DisplayName string `json:"displayName"` + Type string `json:"type"` + Metadata struct { + LaunchStage string `json:"launchStage"` + SamplePeriod string `json:"samplePeriod"` + IngestDelay string `json:"ingestDelay"` + } `json:"metadata"` + } `json:"metricDescriptors"` +} diff --git a/public/app/plugins/datasource/stackdriver/datasource.ts b/public/app/plugins/datasource/stackdriver/datasource.ts index b77abdbdab3..dae9a55bea1 100644 --- a/public/app/plugins/datasource/stackdriver/datasource.ts +++ b/public/app/plugins/datasource/stackdriver/datasource.ts @@ -173,38 +173,53 @@ export default class StackdriverDatasource { throw new Error('Template variables support is not yet imlemented'); } - testDatasource() { - const path = `v3/projects/${this.projectName}/metricDescriptors`; - return this.doRequest(`${this.baseUrl}${path}`) - .then(response => { - if (response.status === 200) { - return { - status: 'success', - message: 'Successfully queried the Stackdriver API.', - title: 'Success', - }; - } + async testDatasource() { + const { data } = await this.backendSrv.datasourceRequest({ + url: '/api/tsdb/query', + method: 'POST', + data: { + queries: [ + { + refId: 'metricDescriptors', + datasourceId: this.id, + type: 'metricDescriptors', + }, + ], + }, + }); + console.log(data); + return data; + // const path = `v3/projects/${this.projectName}/metricDescriptors`; + // return this.doRequest(`${this.baseUrl}${path}`) + // .then(response => { + // if (response.status === 200) { + // return { + // status: 'success', + // message: 'Successfully queried the Stackdriver API.', + // title: 'Success', + // }; + // } - return { - status: 'error', - message: 'Returned http status code ' + response.status, - }; - }) - .catch(error => { - let message = 'Stackdriver: '; - message += error.statusText ? error.statusText + ': ' : ''; + // return { + // status: 'error', + // message: 'Returned http status code ' + response.status, + // }; + // }) + // .catch(error => { + // let message = 'Stackdriver: '; + // message += error.statusText ? error.statusText + ': ' : ''; - if (error.data && error.data.error && error.data.error.code) { - // 400, 401 - message += error.data.error.code + '. ' + error.data.error.message; - } else { - message += 'Cannot connect to Stackdriver API'; - } - return { - status: 'error', - message: message, - }; - }); + // if (error.data && error.data.error && error.data.error.code) { + // // 400, 401 + // message += error.data.error.code + '. ' + error.data.error.message; + // } else { + // message += 'Cannot connect to Stackdriver API'; + // } + // return { + // status: 'error', + // message: message, + // }; + // }); } async getProjects() {