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
54a3f5fd
Unverified
Commit
54a3f5fd
authored
Mar 04, 2020
by
David
Committed by
GitHub
Mar 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Loki: use series API for stream facetting (#21332)
parent
2cf538a4
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
102 additions
and
43 deletions
+102
-43
public/app/plugins/datasource/loki/components/__snapshots__/LokiExploreQueryEditor.test.tsx.snap
+34
-2
public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.test.ts
+2
-2
public/app/plugins/datasource/loki/datasource.ts
+3
-5
public/app/plugins/datasource/loki/language_provider.test.ts
+37
-19
public/app/plugins/datasource/loki/language_provider.ts
+0
-0
public/app/plugins/datasource/loki/mocks.ts
+26
-15
No files found.
public/app/plugins/datasource/loki/components/__snapshots__/LokiExploreQueryEditor.test.tsx.snap
View file @
54a3f5fd
...
...
@@ -56,11 +56,43 @@ exports[`LokiExploreQueryEditor should render component 1`] = `
"languageProvider": LokiLanguageProvider {
"cleanText": [Function],
"datasource": [Circular],
"fetchSeriesLabels": [Function],
"getBeginningCompletionItems": [Function],
"getTermCompletionItems": [Function],
"labelKeys": Object {},
"labelValues": Object {},
"labelKeys": Array [],
"labelsCache": LRUCache {
Symbol(max): 10,
Symbol(lengthCalculator): [Function],
Symbol(allowStale): false,
Symbol(maxAge): 0,
Symbol(dispose): undefined,
Symbol(noDisposeOnSet): false,
Symbol(updateAgeOnGet): false,
Symbol(cache): Map {},
Symbol(lruList): Yallist {
"head": null,
"length": 0,
"tail": null,
},
Symbol(length): 0,
},
"request": [Function],
"seriesCache": LRUCache {
Symbol(max): 10,
Symbol(lengthCalculator): [Function],
Symbol(allowStale): false,
Symbol(maxAge): 0,
Symbol(dispose): undefined,
Symbol(noDisposeOnSet): false,
Symbol(updateAgeOnGet): false,
Symbol(cache): Map {},
Symbol(lruList): Yallist {
"head": null,
"length": 0,
"tail": null,
},
Symbol(length): 0,
},
"start": [Function],
},
"metadataRequest": [Function],
...
...
public/app/plugins/datasource/loki/components/useLokiSyntaxAndLabels.test.ts
View file @
54a3f5fd
...
...
@@ -59,9 +59,9 @@ describe('useLokiSyntax hook', () => {
await
waitForNextUpdate
();
expect
(
result
.
current
.
logLabelOptions
).
toEqual
(
logLabelOptionsMock2
);
languageProvider
.
fetchLabelValues
=
(
key
:
string
)
=>
{
languageProvider
.
fetchLabelValues
=
(
key
:
string
,
absoluteRange
:
AbsoluteTimeRange
)
=>
{
languageProvider
.
logLabelOptions
=
logLabelOptionsMock3
;
return
Promise
.
resolve
();
return
Promise
.
resolve
(
[]
);
};
act
(()
=>
result
.
current
.
setActiveOption
([
activeOptionMock
]));
...
...
public/app/plugins/datasource/loki/datasource.ts
View file @
54a3f5fd
...
...
@@ -390,9 +390,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
async
metadataRequest
(
url
:
string
,
params
?:
Record
<
string
,
string
>
)
{
const
res
=
await
this
.
_request
(
url
,
params
,
{
silent
:
true
}).
toPromise
();
return
{
data
:
{
data
:
res
.
data
.
data
||
res
.
data
.
values
||
[]
},
};
return
res
.
data
.
data
||
res
.
data
.
values
||
[];
}
async
metricFindQuery
(
query
:
string
)
{
...
...
@@ -423,7 +421,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
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
}));
return
result
.
map
((
value
:
string
)
=>
({
text
:
value
}));
}
async
labelValuesQuery
(
label
:
string
)
{
...
...
@@ -432,7 +430,7 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
?
`
${
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
}));
return
result
.
map
((
value
:
string
)
=>
({
text
:
value
}));
}
interpolateQueryExpr
(
value
:
any
,
variable
:
any
)
{
...
...
public/app/plugins/datasource/loki/language_provider.test.ts
View file @
54a3f5fd
import
Plain
from
'slate-plain-serializer'
;
import
{
Editor
as
SlateEditor
}
from
'slate'
;
import
LanguageProvider
,
{
LABEL_REFRESH_INTERVAL
,
LokiHistoryItem
,
rangeToParams
}
from
'./language_provider'
;
import
{
AbsoluteTimeRange
}
from
'@grafana/data'
;
...
...
@@ -85,34 +84,53 @@ describe('Language completion provider', () => {
});
});
describe
(
'label suggestions'
,
()
=>
{
it
(
'returns default label suggestions on label context'
,
async
()
=>
{
const
instance
=
new
LanguageProvider
(
datasource
);
const
value
=
Plain
.
deserialize
(
'{}'
);
const
ed
=
new
SlateEditor
({
value
});
const
valueWithSelection
=
ed
.
moveForward
(
1
).
value
;
const
result
=
await
instance
.
provideCompletionItems
(
{
text
:
''
,
prefix
:
''
,
wrapperClasses
:
[
'context-labels'
],
value
:
valueWithSelection
,
},
{
absoluteRange
:
rangeMock
}
);
describe
(
'label key suggestions'
,
()
=>
{
it
(
'returns all label suggestions on empty selector'
,
async
()
=>
{
const
datasource
=
makeMockLokiDatasource
({
label1
:
[],
label2
:
[]
});
const
provider
=
await
getLanguageProvider
(
datasource
);
const
input
=
createTypeaheadInput
(
'{}'
,
''
,
''
,
1
);
const
result
=
await
provider
.
provideCompletionItems
(
input
,
{
absoluteRange
:
rangeMock
});
expect
(
result
.
context
).
toBe
(
'context-labels'
);
expect
(
result
.
suggestions
).
toEqual
([{
items
:
[{
label
:
'
job'
},
{
label
:
'namespace
'
}],
label
:
'Labels'
}]);
expect
(
result
.
suggestions
).
toEqual
([{
items
:
[{
label
:
'
label1'
},
{
label
:
'label2
'
}],
label
:
'Labels'
}]);
});
it
(
'returns
label suggestions from Loki
'
,
async
()
=>
{
it
(
'returns
all label suggestions on selector when starting to type
'
,
async
()
=>
{
const
datasource
=
makeMockLokiDatasource
({
label1
:
[],
label2
:
[]
});
const
provider
=
await
getLanguageProvider
(
datasource
);
const
input
=
createTypeaheadInput
(
'{
}'
,
''
);
const
input
=
createTypeaheadInput
(
'{
l}'
,
''
,
''
,
2
);
const
result
=
await
provider
.
provideCompletionItems
(
input
,
{
absoluteRange
:
rangeMock
});
expect
(
result
.
context
).
toBe
(
'context-labels'
);
expect
(
result
.
suggestions
).
toEqual
([{
items
:
[{
label
:
'label1'
},
{
label
:
'label2'
}],
label
:
'Labels'
}]);
});
});
describe
(
'label suggestions facetted'
,
()
=>
{
it
(
'returns facetted label suggestions based on selector'
,
async
()
=>
{
const
datasource
=
makeMockLokiDatasource
(
{
label1
:
[],
label2
:
[]
},
{
'{foo="bar"}'
:
[{
label1
:
'label_val1'
}]
}
);
const
provider
=
await
getLanguageProvider
(
datasource
);
const
input
=
createTypeaheadInput
(
'{foo="bar",}'
,
''
,
''
,
11
);
const
result
=
await
provider
.
provideCompletionItems
(
input
,
{
absoluteRange
:
rangeMock
});
expect
(
result
.
context
).
toBe
(
'context-labels'
);
expect
(
result
.
suggestions
).
toEqual
([{
items
:
[{
label
:
'label1'
}],
label
:
'Labels'
}]);
});
it
(
'returns facetted label suggestions for multipule selectors'
,
async
()
=>
{
const
datasource
=
makeMockLokiDatasource
(
{
label1
:
[],
label2
:
[]
},
{
'{baz="42",foo="bar"}'
:
[{
label2
:
'label_val2'
}]
}
);
const
provider
=
await
getLanguageProvider
(
datasource
);
const
input
=
createTypeaheadInput
(
'{baz="42",foo="bar",}'
,
''
,
''
,
20
);
const
result
=
await
provider
.
provideCompletionItems
(
input
,
{
absoluteRange
:
rangeMock
});
expect
(
result
.
context
).
toBe
(
'context-labels'
);
expect
(
result
.
suggestions
).
toEqual
([{
items
:
[{
label
:
'label2'
}],
label
:
'Labels'
}]);
});
});
describe
(
'label suggestions'
,
()
=>
{
it
(
'returns label values suggestions from Loki'
,
async
()
=>
{
const
datasource
=
makeMockLokiDatasource
({
label1
:
[
'label1_val1'
,
'label1_val2'
],
label2
:
[]
});
const
provider
=
await
getLanguageProvider
(
datasource
);
...
...
public/app/plugins/datasource/loki/language_provider.ts
View file @
54a3f5fd
This diff is collapsed.
Click to expand it.
public/app/plugins/datasource/loki/mocks.ts
View file @
54a3f5fd
...
...
@@ -3,34 +3,45 @@ import { DataSourceSettings } from '@grafana/data';
import
{
LokiOptions
}
from
'./types'
;
import
{
createDatasourceSettings
}
from
'../../../features/datasources/mocks'
;
export
function
makeMockLokiDatasource
(
labelsAndValues
:
{
[
label
:
string
]:
string
[]
}):
LokiDatasource
{
interface
Labels
{
[
label
:
string
]:
string
[];
}
interface
Series
{
[
label
:
string
]:
string
;
}
interface
SeriesForSelector
{
[
selector
:
string
]:
Series
[];
}
export
function
makeMockLokiDatasource
(
labelsAndValues
:
Labels
,
series
?:
SeriesForSelector
):
LokiDatasource
{
const
legacyLokiLabelsAndValuesEndpointRegex
=
/^
\/
api
\/
prom
\/
label
\/(\w
*
)\/
values/
;
const
lokiLabelsAndValuesEndpointRegex
=
/^
\/
loki
\/
api
\/
v1
\/
label
\/(\w
*
)\/
values/
;
const
lokiSeriesEndpointRegex
=
/^
\/
loki
\/
api
\/
v1
\/
series/
;
const
legacyLokiLabelsEndpoint
=
`
${
LEGACY_LOKI_ENDPOINT
}
/label`
;
const
lokiLabelsEndpoint
=
`
${
LOKI_ENDPOINT
}
/label`
;
const
labels
=
Object
.
keys
(
labelsAndValues
);
return
{
metadataRequest
:
(
url
:
string
)
=>
{
let
responseData
;
metadataRequest
:
(
url
:
string
,
params
?:
{
[
key
:
string
]:
string
})
=>
{
if
(
url
===
legacyLokiLabelsEndpoint
||
url
===
lokiLabelsEndpoint
)
{
re
sponseData
=
labels
;
re
turn
labels
;
}
else
{
const
match
=
url
.
match
(
legacyLokiLabelsAndValuesEndpointRegex
)
||
url
.
match
(
lokiLabelsAndValuesEndpointRegex
);
if
(
match
)
{
responseData
=
labelsAndValues
[
match
[
1
]];
}
}
if
(
responseData
)
{
return
{
data
:
{
data
:
responseData
,
},
};
const
legacyLabelsMatch
=
url
.
match
(
legacyLokiLabelsAndValuesEndpointRegex
);
const
labelsMatch
=
url
.
match
(
lokiLabelsAndValuesEndpointRegex
);
const
seriesMatch
=
url
.
match
(
lokiSeriesEndpointRegex
);
if
(
legacyLabelsMatch
)
{
return
labelsAndValues
[
legacyLabelsMatch
[
1
]]
||
[];
}
else
if
(
labelsMatch
)
{
return
labelsAndValues
[
labelsMatch
[
1
]]
||
[];
}
else
if
(
seriesMatch
)
{
return
series
[
params
.
match
]
||
[];
}
else
{
throw
new
Error
(
`Unexpected url error,
${
url
}
`
);
}
}
},
}
as
any
;
}
...
...
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