Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
2683699a
Commit
2683699a
authored
Sep 11, 2018
by
Daniel Lee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stackdriver: tests for parsing api response
parent
54f16d55
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
266 additions
and
24 deletions
+266
-24
pkg/tsdb/stackdriver/stackdriver.go
+16
-9
pkg/tsdb/stackdriver/stackdriver_test.go
+50
-1
pkg/tsdb/stackdriver/test-data/1-series-response-agg-one-metric.json
+46
-0
pkg/tsdb/stackdriver/test-data/2-series-response-no-agg.json
+145
-0
pkg/tsdb/stackdriver/types.go
+4
-10
public/app/plugins/datasource/stackdriver/datasource.ts
+5
-4
No files found.
pkg/tsdb/stackdriver/stackdriver.go
View file @
2683699a
...
...
@@ -15,7 +15,6 @@ import (
"golang.org/x/net/context/ctxhttp"
"github.com/grafana/grafana/pkg/api/pluginproxy"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
...
...
@@ -25,10 +24,14 @@ import (
"github.com/opentracing/opentracing-go"
)
var
slog
log
.
Logger
// StackdriverExecutor executes queries for the Stackdriver datasource
type
StackdriverExecutor
struct
{
HTTPClient
*
http
.
Client
}
// NewStackdriverExecutor initializes a http client
func
NewStackdriverExecutor
(
dsInfo
*
models
.
DataSource
)
(
tsdb
.
TsdbQueryEndpoint
,
error
)
{
httpClient
,
err
:=
dsInfo
.
GetHttpClient
()
if
err
!=
nil
{
...
...
@@ -40,9 +43,8 @@ func NewStackdriverExecutor(dsInfo *models.DataSource) (tsdb.TsdbQueryEndpoint,
},
nil
}
var
glog
=
log
.
New
(
"tsdb.stackdriver"
)
func
init
()
{
slog
=
log
.
New
(
"tsdb.stackdriver"
)
tsdb
.
RegisterTsdbQueryEndpoint
(
"stackdriver"
,
NewStackdriverExecutor
)
}
...
...
@@ -66,7 +68,7 @@ func (e *StackdriverExecutor) Query(ctx context.Context, dsInfo *models.DataSour
}
req
.
URL
.
RawQuery
=
query
.
Params
.
Encode
()
logger
.
Info
(
"tsdbQuery"
,
"req.URL.RawQuery"
,
req
.
URL
.
RawQuery
)
slog
.
Info
(
"tsdbQuery"
,
"req.URL.RawQuery"
,
req
.
URL
.
RawQuery
)
httpClient
,
err
:=
dsInfo
.
GetHttpClient
()
if
err
!=
nil
{
...
...
@@ -138,7 +140,7 @@ func (e *StackdriverExecutor) parseQueries(tsdbQuery *tsdb.TsdbQuery) ([]*Stackd
params
.
Add
(
"filter"
,
metricType
)
if
setting
.
Env
==
setting
.
DEV
{
g
log
.
Debug
(
"Stackdriver request"
,
"params"
,
params
)
s
log
.
Debug
(
"Stackdriver request"
,
"params"
,
params
)
}
stackdriverQueries
=
append
(
stackdriverQueries
,
&
StackdriverQuery
{
...
...
@@ -159,14 +161,14 @@ func (e *StackdriverExecutor) unmarshalResponse(res *http.Response) (StackDriver
}
if
res
.
StatusCode
/
100
!=
2
{
g
log
.
Info
(
"Request failed"
,
"status"
,
res
.
Status
,
"body"
,
string
(
body
))
s
log
.
Info
(
"Request failed"
,
"status"
,
res
.
Status
,
"body"
,
string
(
body
))
return
StackDriverResponse
{},
fmt
.
Errorf
(
"Request failed status: %v"
,
res
.
Status
)
}
var
data
StackDriverResponse
err
=
json
.
Unmarshal
(
body
,
&
data
)
if
err
!=
nil
{
g
log
.
Info
(
"Failed to unmarshal Stackdriver response"
,
"error"
,
err
,
"status"
,
res
.
Status
,
"body"
,
string
(
body
))
s
log
.
Info
(
"Failed to unmarshal Stackdriver response"
,
"error"
,
err
,
"status"
,
res
.
Status
,
"body"
,
string
(
body
))
return
StackDriverResponse
{},
err
}
...
...
@@ -182,8 +184,13 @@ func (e *StackdriverExecutor) parseResponse(data StackDriverResponse, queryRefID
for
_
,
point
:=
range
series
.
Points
{
points
=
append
(
points
,
tsdb
.
NewTimePoint
(
null
.
FloatFrom
(
point
.
Value
.
DoubleValue
),
float64
((
point
.
Interval
.
EndTime
)
.
Unix
())
*
1000
))
}
metricName
:=
series
.
Metric
.
Type
for
_
,
value
:=
range
series
.
Metric
.
Labels
{
metricName
+=
" "
+
value
}
queryRes
.
Series
=
append
(
queryRes
.
Series
,
&
tsdb
.
TimeSeries
{
Name
:
series
.
Metric
.
Typ
e
,
Name
:
metricNam
e
,
Points
:
points
,
})
}
...
...
@@ -197,7 +204,7 @@ func (e *StackdriverExecutor) createRequest(ctx context.Context, dsInfo *models.
req
,
err
:=
http
.
NewRequest
(
http
.
MethodGet
,
"https://monitoring.googleapis.com/"
,
nil
)
if
err
!=
nil
{
g
log
.
Info
(
"Failed to create request"
,
"error"
,
err
)
s
log
.
Info
(
"Failed to create request"
,
"error"
,
err
)
return
nil
,
fmt
.
Errorf
(
"Failed to create request. error: %v"
,
err
)
}
...
...
pkg/tsdb/stackdriver/stackdriver_test.go
View file @
2683699a
package
stackdriver
import
(
"encoding/json"
"fmt"
"io/ioutil"
"testing"
"time"
...
...
@@ -13,8 +15,9 @@ import (
func
TestStackdriver
(
t
*
testing
.
T
)
{
Convey
(
"Stackdriver"
,
t
,
func
()
{
executor
:=
&
StackdriverExecutor
{}
Convey
(
"Parse query from frontend"
,
func
()
{
executor
:=
&
StackdriverExecutor
{}
fromStart
:=
time
.
Date
(
2018
,
3
,
15
,
13
,
0
,
0
,
0
,
time
.
UTC
)
.
In
(
time
.
Local
)
tsdbQuery
:=
&
tsdb
.
TsdbQuery
{
TimeRange
:
&
tsdb
.
TimeRange
{
...
...
@@ -43,5 +46,51 @@ func TestStackdriver(t *testing.T) {
So
(
queries
[
0
]
.
Params
[
"aggregation.perSeriesAligner"
][
0
],
ShouldEqual
,
"ALIGN_NONE"
)
So
(
queries
[
0
]
.
Params
[
"filter"
][
0
],
ShouldEqual
,
"time_series"
)
})
Convey
(
"Parse stackdriver response for data aggregated to one time series"
,
func
()
{
var
data
StackDriverResponse
jsonBody
,
err
:=
ioutil
.
ReadFile
(
"./test-data/1-series-response-agg-one-metric.json"
)
So
(
err
,
ShouldBeNil
)
err
=
json
.
Unmarshal
(
jsonBody
,
&
data
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
data
.
TimeSeries
),
ShouldEqual
,
1
)
res
,
err
:=
executor
.
parseResponse
(
data
,
"A"
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
res
.
Series
),
ShouldEqual
,
1
)
So
(
res
.
Series
[
0
]
.
Name
,
ShouldEqual
,
"serviceruntime.googleapis.com/api/request_count"
)
So
(
len
(
res
.
Series
[
0
]
.
Points
),
ShouldEqual
,
3
)
So
(
res
.
Series
[
0
]
.
Points
[
0
][
0
]
.
Float64
,
ShouldEqual
,
1.0666666666667
)
So
(
res
.
Series
[
0
]
.
Points
[
1
][
0
]
.
Float64
,
ShouldEqual
,
1.05
)
So
(
res
.
Series
[
0
]
.
Points
[
2
][
0
]
.
Float64
,
ShouldEqual
,
0.05
)
})
Convey
(
"Parse stackdriver response for data with no aggregation"
,
func
()
{
var
data
StackDriverResponse
jsonBody
,
err
:=
ioutil
.
ReadFile
(
"./test-data/2-series-response-no-agg.json"
)
So
(
err
,
ShouldBeNil
)
err
=
json
.
Unmarshal
(
jsonBody
,
&
data
)
So
(
err
,
ShouldBeNil
)
So
(
len
(
data
.
TimeSeries
),
ShouldEqual
,
3
)
res
,
err
:=
executor
.
parseResponse
(
data
,
"A"
)
So
(
err
,
ShouldBeNil
)
Convey
(
"Should add labels to metric name"
,
func
()
{
So
(
len
(
res
.
Series
),
ShouldEqual
,
3
)
So
(
res
.
Series
[
0
]
.
Name
,
ShouldEqual
,
"compute.googleapis.com/instance/cpu/usage_time collector-asia-east-1"
)
So
(
res
.
Series
[
1
]
.
Name
,
ShouldEqual
,
"compute.googleapis.com/instance/cpu/usage_time collector-europe-west-1"
)
So
(
res
.
Series
[
2
]
.
Name
,
ShouldEqual
,
"compute.googleapis.com/instance/cpu/usage_time collector-us-east-1"
)
So
(
len
(
res
.
Series
[
0
]
.
Points
),
ShouldEqual
,
3
)
So
(
res
.
Series
[
0
]
.
Points
[
0
][
0
]
.
Float64
,
ShouldEqual
,
9.7730520330369
)
So
(
res
.
Series
[
0
]
.
Points
[
1
][
0
]
.
Float64
,
ShouldEqual
,
9.7323568146676
)
So
(
res
.
Series
[
0
]
.
Points
[
2
][
0
]
.
Float64
,
ShouldEqual
,
9.8566497180145
)
})
})
})
}
pkg/tsdb/stackdriver/test-data/1-series-response-agg-one-metric.json
0 → 100644
View file @
2683699a
{
"timeSeries"
:
[
{
"metric"
:
{
"type"
:
"serviceruntime.googleapis.com
\/
api
\/
request_count"
},
"resource"
:
{
"type"
:
"consumed_api"
,
"labels"
:
{
"project_id"
:
"grafana-prod"
}
},
"metricKind"
:
"GAUGE"
,
"valueType"
:
"DOUBLE"
,
"points"
:
[
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:51:00Z"
,
"endTime"
:
"2018-09-11T12:51:00Z"
},
"value"
:
{
"doubleValue"
:
1.0666666666667
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:48:00Z"
,
"endTime"
:
"2018-09-11T12:48:00Z"
},
"value"
:
{
"doubleValue"
:
1.05
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:47:00Z"
,
"endTime"
:
"2018-09-11T12:47:00Z"
},
"value"
:
{
"doubleValue"
:
0.05
}
}
]
}
]
}
pkg/tsdb/stackdriver/test-data/2-series-response-no-agg.json
0 → 100644
View file @
2683699a
{
"timeSeries"
:
[
{
"metric"
:
{
"labels"
:
{
"instance_name"
:
"collector-asia-east-1"
},
"type"
:
"compute.googleapis.com
\/
instance
\/
cpu
\/
usage_time"
},
"resource"
:
{
"type"
:
"gce_instance"
,
"labels"
:
{
"instance_id"
:
"1119268429530133111"
,
"zone"
:
"asia-east1-a"
,
"project_id"
:
"grafana-prod"
}
},
"metricKind"
:
"DELTA"
,
"valueType"
:
"DOUBLE"
,
"points"
:
[
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:30:00Z"
,
"endTime"
:
"2018-09-11T12:31:00Z"
},
"value"
:
{
"doubleValue"
:
9.7730520330369
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:29:00Z"
,
"endTime"
:
"2018-09-11T12:30:00Z"
},
"value"
:
{
"doubleValue"
:
9.7323568146676
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:28:00Z"
,
"endTime"
:
"2018-09-11T12:29:00Z"
},
"value"
:
{
"doubleValue"
:
9.8566497180145
}
}
]
},
{
"metric"
:
{
"labels"
:
{
"instance_name"
:
"collector-europe-west-1"
},
"type"
:
"compute.googleapis.com
\/
instance
\/
cpu
\/
usage_time"
},
"resource"
:
{
"type"
:
"gce_instance"
,
"labels"
:
{
"instance_id"
:
"22241654114540837222"
,
"zone"
:
"europe-west1-b"
,
"project_id"
:
"grafana-prod"
}
},
"metricKind"
:
"DELTA"
,
"valueType"
:
"DOUBLE"
,
"points"
:
[
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:30:00Z"
,
"endTime"
:
"2018-09-11T12:31:00Z"
},
"value"
:
{
"doubleValue"
:
8.8210971239023
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:29:00Z"
,
"endTime"
:
"2018-09-11T12:30:00Z"
},
"value"
:
{
"doubleValue"
:
8.9689492364414
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:28:00Z"
,
"endTime"
:
"2018-09-11T12:29:00Z"
},
"value"
:
{
"doubleValue"
:
9.0238475054502
}
}
]
},
{
"metric"
:
{
"labels"
:
{
"instance_name"
:
"collector-us-east-1"
},
"type"
:
"compute.googleapis.com
\/
instance
\/
cpu
\/
usage_time"
},
"resource"
:
{
"type"
:
"gce_instance"
,
"labels"
:
{
"instance_id"
:
"3332264424035095333"
,
"zone"
:
"us-east1-b"
,
"project_id"
:
"grafana-prod"
}
},
"metricKind"
:
"DELTA"
,
"valueType"
:
"DOUBLE"
,
"points"
:
[
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:30:00Z"
,
"endTime"
:
"2018-09-11T12:31:00Z"
},
"value"
:
{
"doubleValue"
:
30.807846801355
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:29:00Z"
,
"endTime"
:
"2018-09-11T12:30:00Z"
},
"value"
:
{
"doubleValue"
:
30.903974115849
}
},
{
"interval"
:
{
"startTime"
:
"2018-09-11T12:28:00Z"
,
"endTime"
:
"2018-09-11T12:29:00Z"
},
"value"
:
{
"doubleValue"
:
30.829426143318
}
}
]
}
]
}
pkg/tsdb/stackdriver/types.go
View file @
2683699a
...
...
@@ -14,18 +14,12 @@ type StackdriverQuery struct {
type
StackDriverResponse
struct
{
TimeSeries
[]
struct
{
Metric
struct
{
Labels
struct
{
InstanceName
string
`json:"instance_name"`
}
`json:"labels"`
Type
string
`json:"type"`
Labels
map
[
string
]
string
`json:"labels"`
Type
string
`json:"type"`
}
`json:"metric"`
Resource
struct
{
Type
string
`json:"type"`
Labels
struct
{
InstanceID
string
`json:"instance_id"`
Zone
string
`json:"zone"`
ProjectID
string
`json:"project_id"`
}
`json:"labels"`
Type
string
`json:"type"`
Labels
map
[
string
]
string
`json:"labels"`
}
`json:"resource"`
MetricKind
string
`json:"metricKind"`
ValueType
string
`json:"valueType"`
...
...
public/app/plugins/datasource/stackdriver/datasource.ts
View file @
2683699a
...
...
@@ -17,6 +17,9 @@ export default class StackdriverDatasource {
datasourceId
:
this
.
id
,
metricType
:
`metric.type="
${
t
.
metricType
}
"`
,
}));
const
result
=
[];
try
{
const
{
data
}
=
await
this
.
backendSrv
.
datasourceRequest
({
url
:
'/api/tsdb/query'
,
...
...
@@ -28,8 +31,6 @@ export default class StackdriverDatasource {
},
});
const
result
=
[];
if
(
data
.
results
)
{
Object
[
'values'
](
data
.
results
).
forEach
(
queryRes
=>
{
queryRes
.
series
.
forEach
(
series
=>
{
...
...
@@ -37,11 +38,11 @@ export default class StackdriverDatasource {
});
});
}
return
{
data
:
result
};
}
catch
(
error
)
{
console
.
log
(
error
);
}
return
{
data
:
result
};
}
testDatasource
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment