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
45259f43
Unverified
Commit
45259f43
authored
Dec 03, 2019
by
Ivana Huckova
Committed by
GitHub
Dec 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Loki: Support for template variable queries (#20697)
parent
5710e52c
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
118 additions
and
7 deletions
+118
-7
public/app/plugins/datasource/loki/datasource.test.ts
+62
-0
public/app/plugins/datasource/loki/datasource.ts
+47
-4
public/app/plugins/datasource/loki/mocks.ts
+9
-3
No files found.
public/app/plugins/datasource/loki/datasource.test.ts
View file @
45259f43
...
@@ -5,6 +5,7 @@ import { AnnotationQueryRequest, DataSourceApi, DataFrame, dateTime, TimeRange }
...
@@ -5,6 +5,7 @@ import { AnnotationQueryRequest, DataSourceApi, DataFrame, dateTime, TimeRange }
import
{
BackendSrv
}
from
'app/core/services/backend_srv'
;
import
{
BackendSrv
}
from
'app/core/services/backend_srv'
;
import
{
TemplateSrv
}
from
'app/features/templating/template_srv'
;
import
{
TemplateSrv
}
from
'app/features/templating/template_srv'
;
import
{
CustomVariable
}
from
'app/features/templating/custom_variable'
;
import
{
CustomVariable
}
from
'app/features/templating/custom_variable'
;
import
{
makeMockLokiDatasource
}
from
'./mocks'
;
import
{
ExploreMode
}
from
'app/types'
;
import
{
ExploreMode
}
from
'app/types'
;
import
{
of
}
from
'rxjs'
;
import
{
of
}
from
'rxjs'
;
import
omit
from
'lodash/omit'
;
import
omit
from
'lodash/omit'
;
...
@@ -357,6 +358,57 @@ describe('LokiDatasource', () => {
...
@@ -357,6 +358,57 @@ describe('LokiDatasource', () => {
expect
(
res
[
1
].
tags
).
toEqual
([
'value2'
]);
expect
(
res
[
1
].
tags
).
toEqual
([
'value2'
]);
});
});
});
});
describe
(
'metricFindQuery'
,
()
=>
{
const
ds
=
new
LokiDatasource
(
instanceSettings
,
backendSrv
,
templateSrvMock
);
const
mocks
=
makeMetadataAndVersionsMocks
();
mocks
.
forEach
((
mock
,
index
)
=>
{
it
(
`should return label names for Loki v
${
index
}
`
,
async
()
=>
{
ds
.
getVersion
=
mock
.
getVersion
;
ds
.
metadataRequest
=
mock
.
metadataRequest
;
const
query
=
'label_names()'
;
const
res
=
await
ds
.
metricFindQuery
(
query
);
expect
(
res
[
0
].
text
).
toEqual
(
'label1'
);
expect
(
res
[
1
].
text
).
toEqual
(
'label2'
);
expect
(
res
.
length
).
toBe
(
2
);
});
});
mocks
.
forEach
((
mock
,
index
)
=>
{
it
(
`should return label names for Loki v
${
index
}
`
,
async
()
=>
{
ds
.
getVersion
=
mock
.
getVersion
;
ds
.
metadataRequest
=
mock
.
metadataRequest
;
const
query
=
'label_names()'
;
const
res
=
await
ds
.
metricFindQuery
(
query
);
expect
(
res
[
0
].
text
).
toEqual
(
'label1'
);
expect
(
res
[
1
].
text
).
toEqual
(
'label2'
);
expect
(
res
.
length
).
toBe
(
2
);
});
});
mocks
.
forEach
((
mock
,
index
)
=>
{
it
(
`should return label values for Loki v
${
index
}
`
,
async
()
=>
{
ds
.
getVersion
=
mock
.
getVersion
;
ds
.
metadataRequest
=
mock
.
metadataRequest
;
const
query
=
'label_values(label1)'
;
const
res
=
await
ds
.
metricFindQuery
(
query
);
expect
(
res
[
0
].
text
).
toEqual
(
'value1'
);
expect
(
res
[
1
].
text
).
toEqual
(
'value2'
);
expect
(
res
.
length
).
toBe
(
2
);
});
});
mocks
.
forEach
((
mock
,
index
)
=>
{
it
(
`should return empty array when incorrect query for Loki v
${
index
}
`
,
async
()
=>
{
ds
.
getVersion
=
mock
.
getVersion
;
ds
.
metadataRequest
=
mock
.
metadataRequest
;
const
query
=
'incorrect_query'
;
const
res
=
await
ds
.
metricFindQuery
(
query
);
expect
(
res
.
length
).
toBe
(
0
);
});
});
});
});
});
type
LimitTestArgs
=
{
type
LimitTestArgs
=
{
...
@@ -418,3 +470,13 @@ function makeAnnotationQueryRequest(): AnnotationQueryRequest<LokiQuery> {
...
@@ -418,3 +470,13 @@ function makeAnnotationQueryRequest(): AnnotationQueryRequest<LokiQuery> {
rangeRaw
:
timeRange
,
rangeRaw
:
timeRange
,
};
};
}
}
function
makeMetadataAndVersionsMocks
()
{
const
mocks
=
[];
for
(
let
i
=
0
;
i
<=
1
;
i
++
)
{
const
mock
:
LokiDatasource
=
makeMockLokiDatasource
({
label1
:
[
'value1'
,
'value2'
],
label2
:
[
'value3'
,
'value4'
]
});
mock
.
getVersion
=
jest
.
fn
().
mockReturnValue
(
`v
${
i
}
`
);
mocks
.
push
(
mock
);
}
return
mocks
;
}
public/app/plugins/datasource/loki/datasource.ts
View file @
45259f43
...
@@ -52,9 +52,12 @@ import LanguageProvider from './language_provider';
...
@@ -52,9 +52,12 @@ import LanguageProvider from './language_provider';
export
type
RangeQueryOptions
=
Pick
<
DataQueryRequest
<
LokiQuery
>
,
'range'
|
'intervalMs'
|
'maxDataPoints'
|
'reverse'
>
;
export
type
RangeQueryOptions
=
Pick
<
DataQueryRequest
<
LokiQuery
>
,
'range'
|
'intervalMs'
|
'maxDataPoints'
|
'reverse'
>
;
export
const
DEFAULT_MAX_LINES
=
1000
;
export
const
DEFAULT_MAX_LINES
=
1000
;
const
LEGACY_QUERY_ENDPOINT
=
'/api/prom/query'
;
export
const
LEGACY_LOKI_ENDPOINT
=
'/api/prom'
;
const
RANGE_QUERY_ENDPOINT
=
'/loki/api/v1/query_range'
;
export
const
LOKI_ENDPOINT
=
'/loki/api/v1'
;
const
INSTANT_QUERY_ENDPOINT
=
'/loki/api/v1/query'
;
const
LEGACY_QUERY_ENDPOINT
=
`
${
LEGACY_LOKI_ENDPOINT
}
/query`
;
const
RANGE_QUERY_ENDPOINT
=
`
${
LOKI_ENDPOINT
}
/query_range`
;
const
INSTANT_QUERY_ENDPOINT
=
`
${
LOKI_ENDPOINT
}
/query`
;
const
DEFAULT_QUERY_PARAMS
:
Partial
<
LokiLegacyQueryRequest
>
=
{
const
DEFAULT_QUERY_PARAMS
:
Partial
<
LokiLegacyQueryRequest
>
=
{
direction
:
'BACKWARD'
,
direction
:
'BACKWARD'
,
...
@@ -76,9 +79,9 @@ interface LokiContextQueryOptions {
...
@@ -76,9 +79,9 @@ interface LokiContextQueryOptions {
export
class
LokiDatasource
extends
DataSourceApi
<
LokiQuery
,
LokiOptions
>
{
export
class
LokiDatasource
extends
DataSourceApi
<
LokiQuery
,
LokiOptions
>
{
private
streams
=
new
LiveStreams
();
private
streams
=
new
LiveStreams
();
private
version
:
string
;
languageProvider
:
LanguageProvider
;
languageProvider
:
LanguageProvider
;
maxLines
:
number
;
maxLines
:
number
;
version
:
string
;
/** @ngInject */
/** @ngInject */
constructor
(
constructor
(
...
@@ -374,6 +377,46 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
...
@@ -374,6 +377,46 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
};
};
}
}
async
metricFindQuery
(
query
:
string
)
{
if
(
!
query
)
{
return
Promise
.
resolve
([]);
}
const
interpolated
=
this
.
templateSrv
.
replace
(
query
,
{},
this
.
interpolateQueryExpr
);
return
await
this
.
processMetricFindQuery
(
interpolated
);
}
async
processMetricFindQuery
(
query
:
string
)
{
const
labelNamesRegex
=
/^label_names
\(\)\s
*$/
;
const
labelValuesRegex
=
/^label_values
\((?:(
.+
)
,
\s
*
)?([
a-zA-Z_
][
a-zA-Z0-9_
]
*
)\)\s
*$/
;
const
labelNames
=
query
.
match
(
labelNamesRegex
);
if
(
labelNames
)
{
return
await
this
.
labelNamesQuery
();
}
const
labelValues
=
query
.
match
(
labelValuesRegex
);
if
(
labelValues
)
{
return
await
this
.
labelValuesQuery
(
labelValues
[
2
]);
}
return
Promise
.
resolve
([]);
}
async
labelNamesQuery
()
{
const
url
=
(
await
this
.
getVersion
())
===
'v0'
?
`
${
LEGACY_LOKI_ENDPOINT
}
/label`
:
`
${
LOKI_ENDPOINT
}
/label`
;
const
result
=
await
this
.
metadataRequest
(
url
);
return
result
.
data
.
data
.
map
((
value
:
string
)
=>
({
text
:
value
}));
}
async
labelValuesQuery
(
label
:
string
)
{
const
url
=
(
await
this
.
getVersion
())
===
'v0'
?
`
${
LEGACY_LOKI_ENDPOINT
}
/label/
${
label
}
/values`
:
`
${
LOKI_ENDPOINT
}
/label/
${
label
}
/values`
;
const
result
=
await
this
.
metadataRequest
(
url
);
return
result
.
data
.
data
.
map
((
value
:
string
)
=>
({
text
:
value
}));
}
interpolateQueryExpr
(
value
:
any
,
variable
:
any
)
{
interpolateQueryExpr
(
value
:
any
,
variable
:
any
)
{
// if no multi or include all do not regexEscape
// if no multi or include all do not regexEscape
if
(
!
variable
.
multi
&&
!
variable
.
includeAll
)
{
if
(
!
variable
.
multi
&&
!
variable
.
includeAll
)
{
...
...
public/app/plugins/datasource/loki/mocks.ts
View file @
45259f43
import
LokiDatasource
from
'./datasource'
;
import
{
LokiDatasource
,
LOKI_ENDPOINT
,
LEGACY_LOKI_ENDPOINT
}
from
'./datasource'
;
import
{
DataSourceSettings
}
from
'@grafana/data'
;
import
{
DataSourceSettings
}
from
'@grafana/data'
;
import
{
LokiOptions
}
from
'./types'
;
import
{
LokiOptions
}
from
'./types'
;
import
{
createDatasourceSettings
}
from
'../../../features/datasources/mocks'
;
import
{
createDatasourceSettings
}
from
'../../../features/datasources/mocks'
;
export
function
makeMockLokiDatasource
(
labelsAndValues
:
{
[
label
:
string
]:
string
[]
}):
LokiDatasource
{
export
function
makeMockLokiDatasource
(
labelsAndValues
:
{
[
label
:
string
]:
string
[]
}):
LokiDatasource
{
const
legacyLokiLabelsAndValuesEndpointRegex
=
/^
\/
api
\/
prom
\/
label
\/(\w
*
)\/
values/
;
const
lokiLabelsAndValuesEndpointRegex
=
/^
\/
loki
\/
api
\/
v1
\/
label
\/(\w
*
)\/
values/
;
const
legacyLokiLabelsEndpoint
=
`
${
LEGACY_LOKI_ENDPOINT
}
/label`
;
const
lokiLabelsEndpoint
=
`
${
LOKI_ENDPOINT
}
/label`
;
const
labels
=
Object
.
keys
(
labelsAndValues
);
const
labels
=
Object
.
keys
(
labelsAndValues
);
return
{
return
{
metadataRequest
:
(
url
:
string
)
=>
{
metadataRequest
:
(
url
:
string
)
=>
{
let
responseData
;
let
responseData
;
if
(
url
===
'/api/prom/label'
)
{
if
(
url
===
legacyLokiLabelsEndpoint
||
url
===
lokiLabelsEndpoint
)
{
responseData
=
labels
;
responseData
=
labels
;
}
else
{
}
else
{
const
match
=
url
.
match
(
/^
\/
api
\/
prom
\/
label
\/(\w
*
)\/
values/
);
const
match
=
url
.
match
(
legacyLokiLabelsAndValuesEndpointRegex
)
||
url
.
match
(
lokiLabelsAndValuesEndpointRegex
);
if
(
match
)
{
if
(
match
)
{
responseData
=
labelsAndValues
[
match
[
1
]];
responseData
=
labelsAndValues
[
match
[
1
]];
}
}
...
...
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