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
b2401e37
Unverified
Commit
b2401e37
authored
Dec 22, 2018
by
David
Committed by
GitHub
Dec 22, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14414 from grafana/davkal/explore-logging-search
Explore: Split logging query into selector and search
parents
f8e2e117
117adbbe
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
78 additions
and
8 deletions
+78
-8
public/app/features/explore/QueryField.tsx
+9
-2
public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx
+13
-2
public/app/plugins/datasource/loki/components/LokiQueryField.tsx
+50
-3
public/app/plugins/datasource/loki/query_utils.ts
+1
-0
public/sass/components/_slate_editor.scss
+5
-1
No files found.
public/app/features/explore/QueryField.tsx
View file @
b2401e37
...
@@ -4,6 +4,7 @@ import ReactDOM from 'react-dom';
...
@@ -4,6 +4,7 @@ import ReactDOM from 'react-dom';
import
{
Change
,
Value
}
from
'slate'
;
import
{
Change
,
Value
}
from
'slate'
;
import
{
Editor
}
from
'slate-react'
;
import
{
Editor
}
from
'slate-react'
;
import
Plain
from
'slate-plain-serializer'
;
import
Plain
from
'slate-plain-serializer'
;
import
classnames
from
'classnames'
;
import
{
CompletionItem
,
CompletionItemGroup
,
TypeaheadOutput
}
from
'app/types/explore'
;
import
{
CompletionItem
,
CompletionItemGroup
,
TypeaheadOutput
}
from
'app/types/explore'
;
...
@@ -30,6 +31,7 @@ function hasSuggestions(suggestions: CompletionItemGroup[]): boolean {
...
@@ -30,6 +31,7 @@ function hasSuggestions(suggestions: CompletionItemGroup[]): boolean {
export
interface
QueryFieldProps
{
export
interface
QueryFieldProps
{
additionalPlugins
?:
any
[];
additionalPlugins
?:
any
[];
cleanText
?:
(
text
:
string
)
=>
string
;
cleanText
?:
(
text
:
string
)
=>
string
;
disabled
?:
boolean
;
initialQuery
:
string
|
null
;
initialQuery
:
string
|
null
;
onBlur
?:
()
=>
void
;
onBlur
?:
()
=>
void
;
onFocus
?:
()
=>
void
;
onFocus
?:
()
=>
void
;
...
@@ -78,7 +80,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
...
@@ -78,7 +80,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
this
.
placeholdersBuffer
=
new
PlaceholdersBuffer
(
props
.
initialQuery
||
''
);
this
.
placeholdersBuffer
=
new
PlaceholdersBuffer
(
props
.
initialQuery
||
''
);
// Base plugins
// Base plugins
this
.
plugins
=
[
ClearPlugin
(),
NewlinePlugin
(),
...
props
.
additionalPlugins
].
filter
(
p
=>
p
);
this
.
plugins
=
[
ClearPlugin
(),
NewlinePlugin
(),
...
(
props
.
additionalPlugins
||
[])
].
filter
(
p
=>
p
);
this
.
state
=
{
this
.
state
=
{
suggestions
:
[],
suggestions
:
[],
...
@@ -440,12 +442,17 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
...
@@ -440,12 +442,17 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
};
};
render
()
{
render
()
{
const
{
disabled
}
=
this
.
props
;
const
wrapperClassName
=
classnames
(
'slate-query-field__wrapper'
,
{
'slate-query-field__wrapper--disabled'
:
disabled
,
});
return
(
return
(
<
div
className=
"slate-query-field-wrapper"
>
<
div
className=
{
wrapperClassName
}
>
<
div
className=
"slate-query-field"
>
<
div
className=
"slate-query-field"
>
{
this
.
renderMenu
()
}
{
this
.
renderMenu
()
}
<
Editor
<
Editor
autoCorrect=
{
false
}
autoCorrect=
{
false
}
readOnly=
{
this
.
props
.
disabled
}
onBlur=
{
this
.
handleBlur
}
onBlur=
{
this
.
handleBlur
}
onKeyDown=
{
this
.
onKeyDown
}
onKeyDown=
{
this
.
onKeyDown
}
onChange=
{
this
.
onChange
}
onChange=
{
this
.
onChange
}
...
...
public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx
View file @
b2401e37
...
@@ -2,14 +2,23 @@ import React from 'react';
...
@@ -2,14 +2,23 @@ import React from 'react';
const
CHEAT_SHEET_ITEMS
=
[
const
CHEAT_SHEET_ITEMS
=
[
{
{
title
:
'See your logs'
,
label
:
'Start by selecting a log stream from the Log Labels selector.'
,
},
{
title
:
'Logs From a Job'
,
title
:
'Logs From a Job'
,
expression
:
'{job="default/prometheus"}'
,
expression
:
'{job="default/prometheus"}'
,
label
:
'Returns all log lines emitted by instances of this job.'
,
label
:
'Returns all log lines emitted by instances of this job.'
,
},
},
{
{
title
:
'Combine Stream Selectors'
,
expression
:
'{app="cassandra",namespace="prod"}'
,
label
:
'Returns all log lines from streams that have both labels.'
,
},
{
title
:
'Search For Text'
,
title
:
'Search For Text'
,
expression
:
'{app="cassandra"}
Maximum memory usage
'
,
expression
:
'{app="cassandra"}
(duration|latency)
\\
s*(=|is|of)
\\
s*[
\\
d
\\
.]+
'
,
label
:
'
Returns all log lines for the selector and highlights the given text in the results
.'
,
label
:
'
The right search field takes a regular expression to search for
.'
,
},
},
];
];
...
@@ -19,12 +28,14 @@ export default (props: any) => (
...
@@ -19,12 +28,14 @@ export default (props: any) => (
{
CHEAT_SHEET_ITEMS
.
map
(
item
=>
(
{
CHEAT_SHEET_ITEMS
.
map
(
item
=>
(
<
div
className=
"cheat-sheet-item"
key=
{
item
.
expression
}
>
<
div
className=
"cheat-sheet-item"
key=
{
item
.
expression
}
>
<
div
className=
"cheat-sheet-item__title"
>
{
item
.
title
}
</
div
>
<
div
className=
"cheat-sheet-item__title"
>
{
item
.
title
}
</
div
>
{
item
.
expression
&&
(
<
div
<
div
className=
"cheat-sheet-item__expression"
className=
"cheat-sheet-item__expression"
onClick=
{
e
=>
props
.
onClickExample
({
refId
:
'1'
,
expr
:
item
.
expression
})
}
onClick=
{
e
=>
props
.
onClickExample
({
refId
:
'1'
,
expr
:
item
.
expression
})
}
>
>
<
code
>
{
item
.
expression
}
</
code
>
<
code
>
{
item
.
expression
}
</
code
>
</
div
>
</
div
>
)
}
<
div
className=
"cheat-sheet-item__label"
>
{
item
.
label
}
</
div
>
<
div
className=
"cheat-sheet-item__label"
>
{
item
.
label
}
</
div
>
</
div
>
</
div
>
))
}
))
}
...
...
public/app/plugins/datasource/loki/components/LokiQueryField.tsx
View file @
b2401e37
...
@@ -12,9 +12,15 @@ import BracesPlugin from 'app/features/explore/slate-plugins/braces';
...
@@ -12,9 +12,15 @@ import BracesPlugin from 'app/features/explore/slate-plugins/braces';
import
RunnerPlugin
from
'app/features/explore/slate-plugins/runner'
;
import
RunnerPlugin
from
'app/features/explore/slate-plugins/runner'
;
import
QueryField
,
{
TypeaheadInput
,
QueryFieldState
}
from
'app/features/explore/QueryField'
;
import
QueryField
,
{
TypeaheadInput
,
QueryFieldState
}
from
'app/features/explore/QueryField'
;
import
{
DataQuery
}
from
'app/types'
;
import
{
DataQuery
}
from
'app/types'
;
import
{
parseQuery
,
formatQuery
}
from
'../query_utils'
;
const
PRISM_SYNTAX
=
'promql'
;
const
PRISM_SYNTAX
=
'promql'
;
const
SEARCH_FIELD_STYLES
=
{
width
:
'66%'
,
marginLeft
:
3
,
};
export
function
willApplySuggestion
(
suggestion
:
string
,
{
typeaheadContext
,
typeaheadText
}:
QueryFieldState
):
string
{
export
function
willApplySuggestion
(
suggestion
:
string
,
{
typeaheadContext
,
typeaheadText
}:
QueryFieldState
):
string
{
// Modify suggestion based on context
// Modify suggestion based on context
switch
(
typeaheadContext
)
{
switch
(
typeaheadContext
)
{
...
@@ -67,7 +73,10 @@ interface LokiQueryFieldState {
...
@@ -67,7 +73,10 @@ interface LokiQueryFieldState {
class
LokiQueryField
extends
React
.
PureComponent
<
LokiQueryFieldProps
,
LokiQueryFieldState
>
{
class
LokiQueryField
extends
React
.
PureComponent
<
LokiQueryFieldProps
,
LokiQueryFieldState
>
{
plugins
:
any
[];
plugins
:
any
[];
pluginsSearch
:
any
[];
languageProvider
:
any
;
languageProvider
:
any
;
modifiedSearch
:
string
;
modifiedQuery
:
string
;
constructor
(
props
:
LokiQueryFieldProps
,
context
)
{
constructor
(
props
:
LokiQueryFieldProps
,
context
)
{
super
(
props
,
context
);
super
(
props
,
context
);
...
@@ -85,6 +94,8 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
...
@@ -85,6 +94,8 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
}),
}),
];
];
this
.
pluginsSearch
=
[
RunnerPlugin
({
handler
:
props
.
onPressEnter
})];
this
.
state
=
{
this
.
state
=
{
logLabelOptions
:
[],
logLabelOptions
:
[],
syntaxLoaded
:
false
,
syntaxLoaded
:
false
,
...
@@ -134,12 +145,35 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
...
@@ -134,12 +145,35 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
};
};
onChangeQuery
=
(
value
:
string
,
override
?:
boolean
)
=>
{
onChangeQuery
=
(
value
:
string
,
override
?:
boolean
)
=>
{
const
enableSearchField
=
!
this
.
modifiedQuery
&&
value
;
this
.
modifiedQuery
=
value
;
// Send text change to parent
// Send text change to parent
const
{
initialQuery
,
onQueryChange
}
=
this
.
props
;
const
{
initialQuery
,
onQueryChange
}
=
this
.
props
;
if
(
onQueryChange
)
{
if
(
onQueryChange
)
{
const
search
=
this
.
modifiedSearch
||
parseQuery
(
initialQuery
.
expr
).
regexp
;
const
expr
=
formatQuery
(
value
,
search
);
const
query
=
{
const
query
=
{
...
initialQuery
,
...
initialQuery
,
expr
:
value
,
expr
,
};
onQueryChange
(
query
,
override
);
}
// Enable the search field if we have a selector query
if
(
enableSearchField
)
{
this
.
forceUpdate
();
}
};
onChangeSearch
=
(
value
:
string
,
override
?:
boolean
)
=>
{
this
.
modifiedSearch
=
value
;
// Send text change to parent
const
{
initialQuery
,
onQueryChange
}
=
this
.
props
;
if
(
onQueryChange
)
{
const
selector
=
this
.
modifiedQuery
||
parseQuery
(
initialQuery
.
expr
).
query
;
const
expr
=
formatQuery
(
selector
,
value
);
const
query
=
{
...
initialQuery
,
expr
,
};
};
onQueryChange
(
query
,
override
);
onQueryChange
(
query
,
override
);
}
}
...
@@ -190,6 +224,9 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
...
@@ -190,6 +224,9 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
const
{
logLabelOptions
,
syntaxLoaded
}
=
this
.
state
;
const
{
logLabelOptions
,
syntaxLoaded
}
=
this
.
state
;
const
cleanText
=
this
.
languageProvider
?
this
.
languageProvider
.
cleanText
:
undefined
;
const
cleanText
=
this
.
languageProvider
?
this
.
languageProvider
.
cleanText
:
undefined
;
const
chooserText
=
syntaxLoaded
?
'Log labels'
:
'Loading labels...'
;
const
chooserText
=
syntaxLoaded
?
'Log labels'
:
'Loading labels...'
;
const
parsedInitialQuery
=
parseQuery
(
initialQuery
.
expr
);
// Disable search field to make clear that we need a selector query first
const
searchDisabled
=
!
parsedInitialQuery
.
query
&&
!
this
.
modifiedQuery
;
return
(
return
(
<
div
className=
"prom-query-field"
>
<
div
className=
"prom-query-field"
>
...
@@ -204,11 +241,11 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
...
@@ -204,11 +241,11 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
<
QueryField
<
QueryField
additionalPlugins=
{
this
.
plugins
}
additionalPlugins=
{
this
.
plugins
}
cleanText=
{
cleanText
}
cleanText=
{
cleanText
}
initialQuery=
{
initialQuery
.
expr
}
initialQuery=
{
parsedInitialQuery
.
query
}
onTypeahead=
{
this
.
onTypeahead
}
onTypeahead=
{
this
.
onTypeahead
}
onWillApplySuggestion=
{
willApplySuggestion
}
onWillApplySuggestion=
{
willApplySuggestion
}
onValueChanged=
{
this
.
onChangeQuery
}
onValueChanged=
{
this
.
onChangeQuery
}
placeholder=
"
Enter a Loki Log query
"
placeholder=
"
Start with a Loki stream selector
"
portalOrigin=
"loki"
portalOrigin=
"loki"
syntaxLoaded=
{
syntaxLoaded
}
syntaxLoaded=
{
syntaxLoaded
}
/>
/>
...
@@ -224,6 +261,16 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
...
@@ -224,6 +261,16 @@ class LokiQueryField extends React.PureComponent<LokiQueryFieldProps, LokiQueryF
</
div
>
</
div
>
)
:
null
}
)
:
null
}
</
div
>
</
div
>
<
div
className=
"prom-query-field-wrapper"
style=
{
SEARCH_FIELD_STYLES
}
>
<
QueryField
additionalPlugins=
{
this
.
pluginsSearch
}
disabled=
{
searchDisabled
}
initialQuery=
{
parsedInitialQuery
.
regexp
}
onValueChanged=
{
this
.
onChangeSearch
}
placeholder=
"Search by regular expression"
portalOrigin=
"loki"
/>
</
div
>
</
div
>
</
div
>
);
);
}
}
...
...
public/app/plugins/datasource/loki/query_utils.ts
View file @
b2401e37
const
selectorRegexp
=
/
(?:
^|
\s)
{
[^
{
]
*}/g
;
const
selectorRegexp
=
/
(?:
^|
\s)
{
[^
{
]
*}/g
;
export
function
parseQuery
(
input
:
string
)
{
export
function
parseQuery
(
input
:
string
)
{
input
=
input
||
''
;
const
match
=
input
.
match
(
selectorRegexp
);
const
match
=
input
.
match
(
selectorRegexp
);
let
query
=
''
;
let
query
=
''
;
let
regexp
=
input
;
let
regexp
=
input
;
...
...
public/sass/components/_slate_editor.scss
View file @
b2401e37
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
word-break
:
break-word
;
word-break
:
break-word
;
}
}
.slate-query-field
-
wrapper
{
.slate-query-field
__
wrapper
{
position
:
relative
;
position
:
relative
;
display
:
inline-block
;
display
:
inline-block
;
padding
:
6px
7px
4px
;
padding
:
6px
7px
4px
;
...
@@ -20,6 +20,10 @@
...
@@ -20,6 +20,10 @@
transition
:
all
0
.3s
;
transition
:
all
0
.3s
;
}
}
.slate-query-field__wrapper--disabled
{
background-color
:
inherit
;
}
.slate-typeahead
{
.slate-typeahead
{
.typeahead
{
.typeahead
{
position
:
absolute
;
position
:
absolute
;
...
...
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