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
f361f324
Commit
f361f324
authored
Sep 07, 2015
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(elasticsearch): more polish to editor, made interval configurable per query, #1034
parent
3999a3ca
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
88 additions
and
145 deletions
+88
-145
public/app/plugins/datasource/elasticsearch/bucketAgg.js
+34
-17
public/app/plugins/datasource/elasticsearch/partials/bucketAgg.html
+18
-5
public/app/plugins/datasource/elasticsearch/partials/query.editor.html
+0
-59
public/app/plugins/datasource/elasticsearch/partials/query.options.html
+1
-54
public/app/plugins/datasource/elasticsearch/queryBuilder.js
+18
-7
public/app/plugins/datasource/elasticsearch/queryCtrl.js
+1
-1
public/app/plugins/datasource/elasticsearch/queryDef.js
+11
-0
public/test/specs/elasticsearch-querybuilder-specs.js
+5
-2
No files found.
public/app/plugins/datasource/elasticsearch/bucketAgg.js
View file @
f361f324
...
...
@@ -15,6 +15,7 @@ function (angular, _, queryDef) {
$scope
.
bucketAggTypes
=
queryDef
.
bucketAggTypes
;
$scope
.
orderOptions
=
queryDef
.
orderOptions
;
$scope
.
sizeOptions
=
queryDef
.
sizeOptions
;
$scope
.
intervalOptions
=
queryDef
.
intervalOptions
;
$rootScope
.
onAppEvent
(
'elastic-query-updated'
,
function
()
{
$scope
.
validateModel
();
...
...
@@ -27,36 +28,52 @@ function (angular, _, queryDef) {
};
$scope
.
onChangeInternal
=
function
()
{
if
(
$scope
.
validateModel
())
{
$scope
.
onChange
();
}
$scope
.
onChange
();
};
$scope
.
onTypeChanged
=
function
()
{
$scope
.
agg
.
settings
=
{};
$scope
.
showOptions
=
false
;
$scope
.
validateModel
();
$scope
.
onChange
();
};
$scope
.
validateModel
=
function
()
{
$scope
.
index
=
_
.
indexOf
(
bucketAggs
,
$scope
.
agg
);
$scope
.
isFirst
=
$scope
.
index
===
0
;
$scope
.
isLast
=
$scope
.
index
===
bucketAggs
.
length
-
1
;
$scope
.
settingsLinkText
=
""
;
if
(
$scope
.
agg
.
type
===
"terms"
)
{
$scope
.
agg
.
order
=
$scope
.
agg
.
order
||
"asc"
;
$scope
.
agg
.
size
=
$scope
.
agg
.
size
||
"0"
;
$scope
.
agg
.
orderBy
=
$scope
.
agg
.
orderBy
||
"_term"
;
var
settingsLinkText
=
""
;
var
settings
=
$scope
.
agg
.
settings
||
{};
if
(
$scope
.
agg
.
size
!==
'0'
)
{
$scope
.
settingsLinkText
=
queryDef
.
describeOrder
(
$scope
.
agg
.
order
)
+
' '
+
$scope
.
agg
.
size
+
', '
;
}
switch
(
$scope
.
agg
.
type
)
{
case
'terms'
:
{
settings
.
order
=
settings
.
order
||
"asc"
;
settings
.
size
=
settings
.
size
||
"0"
;
settings
.
orderBy
=
settings
.
orderBy
||
"_term"
;
$scope
.
settingsLinkText
+=
'Order by: '
+
queryDef
.
describeOrderBy
(
$scope
.
agg
.
orderBy
,
$scope
.
target
);
if
(
settings
.
size
!==
'0'
)
{
settingsLinkText
=
queryDef
.
describeOrder
(
settings
.
order
)
+
' '
+
settings
.
size
+
', '
;
}
if
(
$scope
.
agg
.
size
===
'0'
)
{
$scope
.
settingsLinkText
+=
' ('
+
$scope
.
agg
.
order
+
')'
;
settingsLinkText
+=
'Order by: '
+
queryDef
.
describeOrderBy
(
settings
.
orderBy
,
$scope
.
target
);
if
(
settings
.
size
===
'0'
)
{
settingsLinkText
+=
' ('
+
settings
.
order
+
')'
;
}
break
;
}
case
'date_histogram'
:
{
settings
.
interval
=
settings
.
interval
||
'auto'
;
$scope
.
agg
.
field
=
$scope
.
target
.
timeField
;
settingsLinkText
=
'Interval: '
+
settings
.
interval
;
}
}
else
if
(
$scope
.
agg
.
type
===
'date_histogram'
)
{
$scope
.
agg
.
field
=
$scope
.
target
.
timeField
;
}
$scope
.
settingsLinkText
=
settingsLinkText
;
$scope
.
agg
.
settings
=
settings
;
return
true
;
};
...
...
public/app/plugins/datasource/elasticsearch/partials/bucketAgg.html
View file @
f361f324
...
...
@@ -5,10 +5,10 @@
<span
ng-hide=
"isFirst"
>
Then by
</span>
</li>
<li>
<metric-segment-model
property=
"agg.type"
options=
"bucketAggTypes"
on-change=
"on
ChangeInternal
()"
custom=
"false"
css-class=
"tight-form-item-large"
></metric-segment-model>
<metric-segment-model
property=
"agg.type"
options=
"bucketAggTypes"
on-change=
"on
TypeChanged
()"
custom=
"false"
css-class=
"tight-form-item-large"
></metric-segment-model>
</li>
<li>
<metric-segment-model
property=
"agg.field"
get-options=
"getFields()"
on-change=
"onChange
Internal
()"
css-class=
"tight-form-item-xxlarge"
></metric-segment>
<metric-segment-model
property=
"agg.field"
get-options=
"getFields()"
on-change=
"onChange()"
css-class=
"tight-form-item-xxlarge"
></metric-segment>
</li>
<li
class=
"tight-form-item last"
ng-if=
"settingsLinkText"
>
<a
ng-click=
"toggleOptions()"
>
{{settingsLinkText}}
</a>
...
...
@@ -27,6 +27,19 @@
</div>
<div
class=
"tight-form"
ng-if=
"showOptions"
>
<div
class=
"tight-form-inner-box"
ng-if=
"agg.type === 'date_histogram'"
>
<div
class=
"tight-form last"
>
<ul
class=
"tight-form-list"
>
<li
class=
"tight-form-item"
style=
"width: 60px"
>
Interval
</li>
<li>
<metric-segment-model
property=
"agg.settings.interval"
options=
"intervalOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
custom=
"true"
></metric-segment-model>
</li>
</ul>
<div
class=
"clearfix"
></div>
</div>
</div>
<div
class=
"tight-form-inner-box"
ng-if=
"agg.type === 'terms'"
>
<div
class=
"tight-form"
>
<ul
class=
"tight-form-list"
>
...
...
@@ -34,7 +47,7 @@
Order
</li>
<li>
<metric-segment-model
property=
"agg.order"
options=
"orderOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
<metric-segment-model
property=
"agg.
settings.
order"
options=
"orderOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
</li>
</ul>
<div
class=
"clearfix"
></div>
...
...
@@ -45,7 +58,7 @@
Size
</li>
<li>
<metric-segment-model
property=
"agg.size"
options=
"sizeOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
<metric-segment-model
property=
"agg.s
ettings.s
ize"
options=
"sizeOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
</li>
</ul>
<div
class=
"clearfix"
></div>
...
...
@@ -56,7 +69,7 @@
Order By
</li>
<li>
<metric-segment-model
property=
"agg.orderBy"
options=
"orderByOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
<metric-segment-model
property=
"agg.
settings.
orderBy"
options=
"orderByOptions"
on-change=
"onChangeInternal()"
css-class=
"last"
></metric-segment-model>
</li>
</ul>
<div
class=
"clearfix"
></div>
...
...
public/app/plugins/datasource/elasticsearch/partials/query.editor.html
View file @
f361f324
...
...
@@ -74,63 +74,4 @@
</elastic-bucket-agg>
</div>
<!-- <div class="tight-form"> -->
<!-- <ul class="tight-form-list"> -->
<!-- <li class="tight-form-item query-keyword tight-form-align" style="width: 75px;"> -->
<!-- <span ng-show="$first">Group by</span> -->
<!-- <span ng-show="!$first">Then by</span> -->
<!-- </li> -->
<!-- <li> -->
<!-- <elastic-query-component model="agg" get-fields="getFields()" on-change="queryUpdated()"></elastic-query-component> -->
<!-- </li> -->
<!-- </ul> -->
<!-- -->
<!-- <ul class="tight-form-list pull-right"> -->
<!-- <li class="tight-form-item" ng-if="$index === 0"> -->
<!-- <a class="pointer" ng-click="addBucketAgg()"><i class="fa fa-plus"></i></a> -->
<!-- </li> -->
<!-- <li class="tight-form-item" ng-if="!$last"> -->
<!-- <a class="pointer" ng-click="removeBucketAgg($index)"><i class="fa fa-minus"></i></a> -->
<!-- </li> -->
<!-- </ul> -->
<!-- <div class="clearfix"></div> -->
<!-- </div> -->
<!-- -->
<!-- <div class="tight-form" ng-if="agg.showOptions"> -->
<!-- <div style="margin: 20px 0 20px 148px;display: inline-block"> -->
<!-- <div class="tight-form"> -->
<!-- <ul class="tight-form-list"> -->
<!-- <li class="tight-form-item" style="width: 60px"> -->
<!-- Order -->
<!-- </li> -->
<!-- <li> -->
<!-- <metric-segment segment="" get-alt-segments="getFields()" on-value-changed="timeFieldChanged()"></metric-segment> -->
<!-- </li> -->
<!-- </ul> -->
<!-- <div class="clearfix"></div> -->
<!-- </div> -->
<!-- <div class="tight-form"> -->
<!-- <ul class="tight-form-list"> -->
<!-- <li class="tight-form-item" style="width: 60px"> -->
<!-- Size -->
<!-- </li> -->
<!-- <li> -->
<!-- <input type="text" class="input-mini tight-form-input" ng-model="agg.options.size" spellcheck='false' placeholder="0" ng-blur="get_data()"> -->
<!-- </li> -->
<!-- </ul> -->
<!-- <div class="clearfix"></div> -->
<!-- </div> -->
<!-- <div class="tight-form last"> -->
<!-- <ul class="tight-form-list"> -->
<!-- <li class="tight-form-item" style="width: 60px"> -->
<!-- Order by -->
<!-- </li> -->
<!-- <li> -->
<!-- <metric-segment segment="timeSegment" get-alt-segments="getFields()" on-value-changed="timeFieldChanged()"></metric-segment> -->
<!-- </li> -->
<!-- </ul> -->
<!-- <div class="clearfix"></div> -->
<!-- </div> -->
<!-- </div> -->
</div>
public/app/plugins/datasource/elasticsearch/partials/query.options.html
View file @
f361f324
<section
class=
"grafana-metric-options"
>
<div
class=
"tight-form"
>
<ul
class=
"tight-form-list"
>
<li
class=
"tight-form-item tight-form-item-icon"
>
<i
class=
"fa fa-wrench"
></i>
</li>
<li
class=
"tight-form-item"
>
Group by time interval
</li>
<li>
<input
type=
"text"
class=
"input-medium tight-form-input"
ng-model=
"panel.interval"
ng-blur=
"get_data();"
spellcheck=
'false'
placeholder=
"example: >10s"
>
</li>
<li
class=
"tight-form-item"
>
<i
class=
"fa fa-question-circle"
bs-tooltip=
"'Set a low limit by having a greater sign: example: >60s'"
data-placement=
"right"
></i>
</li>
</ul>
<div
class=
"clearfix"
></div>
</div>
<div
class=
"tight-form"
>
<div
class=
"tight-form last"
>
<ul
class=
"tight-form-list"
>
<li
class=
"tight-form-item tight-form-item-icon"
>
<i
class=
"fa fa-info-circle"
></i>
...
...
@@ -28,16 +9,6 @@
alias patterns
</a>
</li>
<li
class=
"tight-form-item"
>
<a
ng-click=
"toggleEditorHelp(2)"
bs-tooltip=
"'click to show helpful info'"
data-placement=
"bottom"
>
stacking
&
and fill
</a>
</li>
<li
class=
"tight-form-item"
>
<a
ng-click=
"toggleEditorHelp(3)"
bs-tooltip=
"'click to show helpful info'"
data-placement=
"bottom"
>
group by time
</a>
</li>
</ul>
<div
class=
"clearfix"
></div>
</div>
...
...
@@ -56,30 +27,6 @@
</ul>
</div>
<div
class=
"grafana-info-box span6"
ng-if=
"editorHelpIndex === 2"
>
<h5>
Stacking and fill
</h5>
<ul>
<li>
When stacking is enabled it important that points align
</li>
<li>
If there are missing points for one series it can cause gaps or missing bars
</li>
<li>
You must use fill(0), and select a group by time low limit
</li>
<li>
Use the group by time option below your queries and specify for example
>
10s if your metrics are written every 10 seconds
</li>
<li>
This will insert zeros for series that are missing measurements and will make stacking work properly
</li>
</ul>
</div>
<div
class=
"grafana-info-box span6"
ng-if=
"editorHelpIndex === 3"
>
<h5>
Group by time
</h5>
<ul>
<li>
Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana
</li>
<li>
Leave the group by time field empty for each query and it will be calculated based on time range and pixel width of the graph
</li>
<li>
If you use fill(0) or fill(null) set a low limit for the auto group by time interval
</li>
<li>
The low limit can only be set in the group by time option below your queries
</li>
<li>
You set a low limit by adding a greater sign before the interval
</li>
<li>
Example:
>
60s if you write metrics to ElasticDB every 60 seconds
</li>
</ul>
</div>
</div>
</div>
...
...
public/app/plugins/datasource/elasticsearch/queryBuilder.js
View file @
f361f324
...
...
@@ -16,21 +16,24 @@ function (angular) {
ElasticQueryBuilder
.
prototype
.
buildTermsAgg
=
function
(
aggDef
,
queryNode
,
target
)
{
var
metricRef
,
metric
,
size
,
y
;
queryNode
.
terms
=
{
"field"
:
aggDef
.
field
};
size
=
parseInt
(
aggDef
.
size
,
10
);
if
(
!
aggDef
.
settings
)
{
return
queryNode
;
}
size
=
parseInt
(
aggDef
.
settings
.
size
,
10
);
if
(
size
>
0
)
{
queryNode
.
terms
.
size
=
size
;
}
if
(
aggDef
.
orderBy
!==
void
0
)
{
if
(
aggDef
.
settings
.
orderBy
!==
void
0
)
{
queryNode
.
terms
.
order
=
{};
queryNode
.
terms
.
order
[
aggDef
.
orderBy
]
=
aggDef
.
order
;
queryNode
.
terms
.
order
[
aggDef
.
settings
.
orderBy
]
=
aggDef
.
settings
.
order
;
// if metric ref, look it up and add it to this agg level
metricRef
=
parseInt
(
aggDef
.
orderBy
,
10
);
metricRef
=
parseInt
(
aggDef
.
settings
.
orderBy
,
10
);
if
(
!
isNaN
(
metricRef
))
{
for
(
y
=
0
;
y
<
target
.
metrics
.
length
;
y
++
)
{
metric
=
target
.
metrics
[
y
];
if
(
metric
.
id
===
aggDef
.
orderBy
)
{
if
(
metric
.
id
===
aggDef
.
settings
.
orderBy
)
{
queryNode
.
aggs
=
{};
queryNode
.
aggs
[
metric
.
id
]
=
{};
queryNode
.
aggs
[
metric
.
id
][
metric
.
type
]
=
{
field
:
metric
.
field
};
...
...
@@ -43,6 +46,14 @@ function (angular) {
return
queryNode
;
};
ElasticQueryBuilder
.
prototype
.
getInterval
=
function
(
agg
)
{
if
(
agg
.
settings
&&
agg
.
settings
.
interval
!==
'auto'
)
{
return
agg
.
settings
.
interval
;
}
else
{
return
'$interval'
;
}
};
ElasticQueryBuilder
.
prototype
.
build
=
function
(
target
)
{
if
(
target
.
rawQuery
)
{
return
angular
.
fromJson
(
target
.
rawQuery
);
...
...
@@ -77,7 +88,7 @@ function (angular) {
switch
(
aggDef
.
type
)
{
case
'date_histogram'
:
{
esAgg
[
"date_histogram"
]
=
{
"interval"
:
t
arget
.
interval
||
"$interval"
,
"interval"
:
t
his
.
getInterval
(
aggDef
)
,
"field"
:
this
.
timeField
,
"min_doc_count"
:
1
,
"extended_bounds"
:
{
"min"
:
"$timeFrom"
,
"max"
:
"$timeTo"
}
...
...
public/app/plugins/datasource/elasticsearch/queryCtrl.js
View file @
f361f324
...
...
@@ -14,7 +14,7 @@ function (angular, _) {
if
(
!
target
)
{
return
;
}
target
.
metrics
=
target
.
metrics
||
[{
type
:
'count'
,
id
:
'1'
}];
target
.
bucketAggs
=
target
.
bucketAggs
||
[{
type
:
'date_histogram'
,
id
:
'2'
}];
target
.
bucketAggs
=
target
.
bucketAggs
||
[{
type
:
'date_histogram'
,
id
:
'2'
,
settings
:
{
interval
:
'auto'
}
}];
target
.
timeField
=
$scope
.
datasource
.
timeField
;
};
...
...
public/app/plugins/datasource/elasticsearch/queryDef.js
View file @
f361f324
...
...
@@ -53,6 +53,17 @@ function (_) {
{
text
:
'Std Dev Lower'
,
value
:
'std_deviation_bounds_lower'
},
],
intervalOptions
:
[
{
text
:
'auto'
,
value
:
'auto'
},
{
text
:
'10s'
,
value
:
'10s'
},
{
text
:
'1m'
,
value
:
'1m'
},
{
text
:
'5m'
,
value
:
'5m'
},
{
text
:
'10m'
,
value
:
'10m'
},
{
text
:
'20m'
,
value
:
'20m'
},
{
text
:
'1h'
,
value
:
'1h'
},
{
text
:
'1d'
,
value
:
'1d'
},
],
getOrderByOptions
:
function
(
target
)
{
var
self
=
this
;
var
metricRefs
=
[];
...
...
public/test/specs/elasticsearch-querybuilder-specs.js
View file @
f361f324
...
...
@@ -48,9 +48,12 @@ define([
it
(
'with term agg and order by metric agg'
,
function
()
{
var
query
=
builder
.
build
({
metrics
:
[{
type
:
'count'
,
id
:
'1'
},
{
type
:
'avg'
,
field
:
'@value'
,
id
:
'5'
}],
metrics
:
[
{
type
:
'count'
,
id
:
'1'
},
{
type
:
'avg'
,
field
:
'@value'
,
id
:
'5'
}
],
bucketAggs
:
[
{
type
:
'terms'
,
field
:
'@host'
,
s
ize
:
5
,
order
:
'asc'
,
orderBy
:
'5'
,
id
:
'2'
},
{
type
:
'terms'
,
field
:
'@host'
,
s
ettings
:
{
size
:
5
,
order
:
'asc'
,
orderBy
:
'5'
}
,
id
:
'2'
},
{
type
:
'date_histogram'
,
field
:
'@timestamp'
,
id
:
'3'
}
],
},
100
,
1000
);
...
...
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