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
aa7292fa
Commit
aa7292fa
authored
Feb 07, 2017
by
bergquist
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mqe: adds support for wildcard and index aliases
parent
bccb6500
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
153 additions
and
20 deletions
+153
-20
pkg/tsdb/mqe/httpClient.go
+1
-1
pkg/tsdb/mqe/mqe.go
+1
-0
pkg/tsdb/mqe/response_parser.go
+87
-13
pkg/tsdb/mqe/response_parser_test.go
+62
-6
pkg/tsdb/mqe/types.go
+2
-0
No files found.
pkg/tsdb/mqe/httpClient.go
View file @
aa7292fa
...
@@ -86,7 +86,7 @@ func (e *apiClient) spawnWorker(ctx context.Context, id int, jobs chan QueryToSe
...
@@ -86,7 +86,7 @@ func (e *apiClient) spawnWorker(ctx context.Context, id int, jobs chan QueryToSe
return
return
}
}
series
,
err
:=
e
.
responseParser
.
Parse
(
resp
,
query
.
QueryRef
)
series
,
err
:=
e
.
responseParser
.
Parse
(
resp
,
query
)
if
err
!=
nil
{
if
err
!=
nil
{
errors
<-
err
errors
<-
err
return
return
...
...
pkg/tsdb/mqe/mqe.go
View file @
aa7292fa
...
@@ -40,6 +40,7 @@ func init() {
...
@@ -40,6 +40,7 @@ func init() {
type
QueryToSend
struct
{
type
QueryToSend
struct
{
RawQuery
string
RawQuery
string
Metric
Metric
QueryRef
*
Query
QueryRef
*
Query
}
}
...
...
pkg/tsdb/mqe/response_parser.go
View file @
aa7292fa
...
@@ -4,9 +4,13 @@ import (
...
@@ -4,9 +4,13 @@ import (
"encoding/json"
"encoding/json"
"io/ioutil"
"io/ioutil"
"net/http"
"net/http"
"strconv"
"strings"
"fmt"
"fmt"
"regexp"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana/pkg/tsdb"
...
@@ -18,6 +22,16 @@ func NewResponseParser() *ResponseParser {
...
@@ -18,6 +22,16 @@ func NewResponseParser() *ResponseParser {
}
}
}
}
var
(
indexAliasPattern
*
regexp
.
Regexp
wildcardAliasPattern
*
regexp
.
Regexp
)
func
init
()
{
indexAliasPattern
=
regexp
.
MustCompile
(
`\$(\d)`
)
wildcardAliasPattern
=
regexp
.
MustCompile
(
`[*!]`
)
}
type
MQEResponse
struct
{
type
MQEResponse
struct
{
Success
bool
`json:"success"`
Success
bool
`json:"success"`
Name
string
`json:"name"`
Name
string
`json:"name"`
...
@@ -47,7 +61,7 @@ type ResponseParser struct {
...
@@ -47,7 +61,7 @@ type ResponseParser struct {
log
log
.
Logger
log
log
.
Logger
}
}
func
(
parser
*
ResponseParser
)
Parse
(
res
*
http
.
Response
,
queryRef
*
Query
)
([]
*
tsdb
.
TimeSeries
,
error
)
{
func
(
parser
*
ResponseParser
)
Parse
(
res
*
http
.
Response
,
queryRef
QueryToSend
)
([]
*
tsdb
.
TimeSeries
,
error
)
{
body
,
err
:=
ioutil
.
ReadAll
(
res
.
Body
)
body
,
err
:=
ioutil
.
ReadAll
(
res
.
Body
)
defer
res
.
Body
.
Close
()
defer
res
.
Body
.
Close
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -73,22 +87,14 @@ func (parser *ResponseParser) Parse(res *http.Response, queryRef *Query) ([]*tsd
...
@@ -73,22 +87,14 @@ func (parser *ResponseParser) Parse(res *http.Response, queryRef *Query) ([]*tsd
var
series
[]
*
tsdb
.
TimeSeries
var
series
[]
*
tsdb
.
TimeSeries
for
_
,
body
:=
range
data
.
Body
{
for
_
,
body
:=
range
data
.
Body
{
for
_
,
mqeSerie
:=
range
body
.
Series
{
for
_
,
mqeSerie
:=
range
body
.
Series
{
namePrefix
:=
""
serie
:=
&
tsdb
.
TimeSeries
{
Tags
:
map
[
string
]
string
{},
//append predefined tags to seriename
Name
:
parser
.
formatLegend
(
body
,
mqeSerie
,
queryRef
),
for
key
,
value
:=
range
mqeSerie
.
Tagset
{
if
key
==
"cluster"
&&
queryRef
.
AddClusterToAlias
{
namePrefix
+=
value
+
" "
}
}
}
for
key
,
value
:=
range
mqeSerie
.
Tagset
{
for
key
,
value
:=
range
mqeSerie
.
Tagset
{
if
key
==
"host"
&&
queryRef
.
AddHostToAlias
{
serie
.
Tags
[
key
]
=
value
namePrefix
+=
value
+
" "
}
}
}
serie
:=
&
tsdb
.
TimeSeries
{
Name
:
namePrefix
+
body
.
Name
}
for
i
,
value
:=
range
mqeSerie
.
Values
{
for
i
,
value
:=
range
mqeSerie
.
Values
{
timestamp
:=
body
.
TimeRange
.
Start
+
int64
(
i
)
*
body
.
TimeRange
.
Resolution
timestamp
:=
body
.
TimeRange
.
Start
+
int64
(
i
)
*
body
.
TimeRange
.
Resolution
serie
.
Points
=
append
(
serie
.
Points
,
tsdb
.
NewTimePoint
(
value
,
float64
(
timestamp
)))
serie
.
Points
=
append
(
serie
.
Points
,
tsdb
.
NewTimePoint
(
value
,
float64
(
timestamp
)))
...
@@ -100,3 +106,71 @@ func (parser *ResponseParser) Parse(res *http.Response, queryRef *Query) ([]*tsd
...
@@ -100,3 +106,71 @@ func (parser *ResponseParser) Parse(res *http.Response, queryRef *Query) ([]*tsd
return
series
,
nil
return
series
,
nil
}
}
func
(
parser
*
ResponseParser
)
formatLegend
(
body
MQEResponseSerie
,
mqeSerie
MQESerie
,
queryToSend
QueryToSend
)
string
{
namePrefix
:=
""
//append predefined tags to seriename
for
key
,
value
:=
range
mqeSerie
.
Tagset
{
if
key
==
"cluster"
&&
queryToSend
.
QueryRef
.
AddClusterToAlias
{
namePrefix
+=
value
+
" "
}
}
for
key
,
value
:=
range
mqeSerie
.
Tagset
{
if
key
==
"host"
&&
queryToSend
.
QueryRef
.
AddHostToAlias
{
namePrefix
+=
value
+
" "
}
}
return
namePrefix
+
parser
.
formatName
(
body
,
queryToSend
)
}
func
(
parser
*
ResponseParser
)
formatName
(
body
MQEResponseSerie
,
queryToSend
QueryToSend
)
string
{
if
indexAliasPattern
.
MatchString
(
queryToSend
.
Metric
.
Alias
)
{
return
parser
.
indexAlias
(
body
,
queryToSend
)
}
if
wildcardAliasPattern
.
MatchString
(
queryToSend
.
Metric
.
Metric
)
&&
wildcardAliasPattern
.
MatchString
(
queryToSend
.
Metric
.
Alias
)
{
return
parser
.
wildcardAlias
(
body
,
queryToSend
)
}
return
body
.
Name
}
func
(
parser
*
ResponseParser
)
wildcardAlias
(
body
MQEResponseSerie
,
queryToSend
QueryToSend
)
string
{
regString
:=
strings
.
Replace
(
queryToSend
.
Metric
.
Metric
,
`*`
,
`(.*)`
,
1
)
reg
,
err
:=
regexp
.
Compile
(
regString
)
if
err
!=
nil
{
return
queryToSend
.
Metric
.
Alias
}
matches
:=
reg
.
FindAllStringSubmatch
(
queryToSend
.
RawQuery
,
-
1
)
if
len
(
matches
)
==
0
||
len
(
matches
[
0
])
<
2
{
return
queryToSend
.
Metric
.
Alias
}
return
matches
[
0
][
1
]
}
func
(
parser
*
ResponseParser
)
indexAlias
(
body
MQEResponseSerie
,
queryToSend
QueryToSend
)
string
{
queryNameParts
:=
strings
.
Split
(
body
.
Name
,
`.`
)
name
:=
indexAliasPattern
.
ReplaceAllStringFunc
(
queryToSend
.
Metric
.
Alias
,
func
(
in
string
)
string
{
positionName
:=
strings
.
TrimSpace
(
strings
.
Replace
(
in
,
"$"
,
""
,
1
))
pos
,
err
:=
strconv
.
Atoi
(
positionName
)
if
err
!=
nil
{
return
""
}
for
i
,
part
:=
range
queryNameParts
{
if
i
==
pos
-
1
{
return
strings
.
TrimSpace
(
part
)
}
}
return
""
})
return
strings
.
Replace
(
name
,
" "
,
"."
,
-
1
)
}
pkg/tsdb/mqe/response_parser_test.go
View file @
aa7292fa
...
@@ -8,11 +8,12 @@ import (
...
@@ -8,11 +8,12 @@ import (
"io/ioutil"
"io/ioutil"
"github.com/grafana/grafana/pkg/components/null"
.
"github.com/smartystreets/goconvey/convey"
.
"github.com/smartystreets/goconvey/convey"
)
)
var
(
var
(
dummie
Json
string
test
Json
string
)
)
func
TestMQEResponseParser
(
t
*
testing
.
T
)
{
func
TestMQEResponseParser
(
t
*
testing
.
T
)
{
...
@@ -20,14 +21,17 @@ func TestMQEResponseParser(t *testing.T) {
...
@@ -20,14 +21,17 @@ func TestMQEResponseParser(t *testing.T) {
parser
:=
NewResponseParser
()
parser
:=
NewResponseParser
()
Convey
(
"Can parse response"
,
func
()
{
Convey
(
"Can parse response"
,
func
()
{
queryRef
:=
&
Query
{
queryRef
:=
QueryToSend
{
AddClusterToAlias
:
true
,
QueryRef
:
&
Query
{
AddHostToAlias
:
true
,
AddClusterToAlias
:
true
,
AddHostToAlias
:
true
,
},
Metric
:
Metric
{
Alias
:
""
},
}
}
response
:=
&
http
.
Response
{
response
:=
&
http
.
Response
{
StatusCode
:
200
,
StatusCode
:
200
,
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
dummie
Json
)),
Body
:
ioutil
.
NopCloser
(
strings
.
NewReader
(
test
Json
)),
}
}
res
,
err
:=
parser
.
Parse
(
response
,
queryRef
)
res
,
err
:=
parser
.
Parse
(
response
,
queryRef
)
So
(
err
,
ShouldBeNil
)
So
(
err
,
ShouldBeNil
)
...
@@ -39,12 +43,64 @@ func TestMQEResponseParser(t *testing.T) {
...
@@ -39,12 +43,64 @@ func TestMQEResponseParser(t *testing.T) {
So
(
res
[
0
]
.
Points
[
i
][
0
]
.
Float64
,
ShouldEqual
,
i
+
1
)
So
(
res
[
0
]
.
Points
[
i
][
0
]
.
Float64
,
ShouldEqual
,
i
+
1
)
So
(
res
[
0
]
.
Points
[
i
][
1
]
.
Float64
,
ShouldEqual
,
startTime
+
(
i
*
30000
))
So
(
res
[
0
]
.
Points
[
i
][
1
]
.
Float64
,
ShouldEqual
,
startTime
+
(
i
*
30000
))
}
}
})
Convey
(
"Can format legend"
,
func
()
{
mqeSerie
:=
MQESerie
{
Tagset
:
map
[
string
]
string
{
"cluster"
:
"demoapp"
,
"host"
:
"staples-lab-1"
,
},
Values
:
[]
null
.
Float
{
null
.
NewFloat
(
3
,
true
)},
}
Convey
(
"with empty alias"
,
func
()
{
serie
:=
MQEResponseSerie
{
Name
:
"os.disk.sda3.weighted_io_time"
}
queryRef
:=
QueryToSend
{
QueryRef
:
&
Query
{
AddClusterToAlias
:
true
,
AddHostToAlias
:
true
,
},
Metric
:
Metric
{
Alias
:
""
},
}
legend
:=
parser
.
formatLegend
(
serie
,
mqeSerie
,
queryRef
)
So
(
legend
,
ShouldEqual
,
"demoapp staples-lab-1 os.disk.sda3.weighted_io_time"
)
})
Convey
(
"with index alias (ex $2 $3)"
,
func
()
{
serie
:=
MQEResponseSerie
{
Name
:
"os.disk.sda3.weighted_io_time"
}
queryRef
:=
QueryToSend
{
QueryRef
:
&
Query
{
AddClusterToAlias
:
true
,
AddHostToAlias
:
true
,
},
Metric
:
Metric
{
Alias
:
"$2 $3"
},
}
legend
:=
parser
.
formatLegend
(
serie
,
mqeSerie
,
queryRef
)
So
(
legend
,
ShouldEqual
,
"demoapp staples-lab-1 disk.sda3"
)
})
Convey
(
"with wildcard alias"
,
func
()
{
serie
:=
MQEResponseSerie
{
Name
:
"os.disk.sda3.weighted_io_time"
,
Query
:
"os.disk.*"
}
queryRef
:=
QueryToSend
{
QueryRef
:
&
Query
{
AddClusterToAlias
:
true
,
AddHostToAlias
:
true
,
},
RawQuery
:
"os.disk.sda3.weighted_io_time"
,
Metric
:
Metric
{
Alias
:
"*"
,
Metric
:
"os.disk.*.weighted_io_time"
},
}
legend
:=
parser
.
formatLegend
(
serie
,
mqeSerie
,
queryRef
)
So
(
legend
,
ShouldEqual
,
"demoapp staples-lab-1 sda3"
)
})
})
})
})
})
}
}
func
init
()
{
func
init
()
{
dummie
Json
=
`{
test
Json
=
`{
"success": true,
"success": true,
"name": "select",
"name": "select",
"body": [
"body": [
...
...
pkg/tsdb/mqe/types.go
View file @
aa7292fa
...
@@ -53,6 +53,7 @@ func (q *Query) Build(availableSeries []string) ([]QueryToSend, error) {
...
@@ -53,6 +53,7 @@ func (q *Query) Build(availableSeries []string) ([]QueryToSend, error) {
queriesToSend
=
append
(
queriesToSend
,
QueryToSend
{
queriesToSend
=
append
(
queriesToSend
,
QueryToSend
{
RawQuery
:
rawQuery
,
RawQuery
:
rawQuery
,
QueryRef
:
q
,
QueryRef
:
q
,
Metric
:
metric
,
})
})
}
else
{
}
else
{
m
:=
strings
.
Replace
(
metric
.
Metric
,
"*"
,
".*"
,
-
1
)
m
:=
strings
.
Replace
(
metric
.
Metric
,
"*"
,
".*"
,
-
1
)
...
@@ -70,6 +71,7 @@ func (q *Query) Build(availableSeries []string) ([]QueryToSend, error) {
...
@@ -70,6 +71,7 @@ func (q *Query) Build(availableSeries []string) ([]QueryToSend, error) {
queriesToSend
=
append
(
queriesToSend
,
QueryToSend
{
queriesToSend
=
append
(
queriesToSend
,
QueryToSend
{
RawQuery
:
rawQuery
,
RawQuery
:
rawQuery
,
QueryRef
:
q
,
QueryRef
:
q
,
Metric
:
metric
,
})
})
}
}
}
}
...
...
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