option to adjust table time field to browser's local timezone. Set as default on logstash dashboard

This commit is contained in:
Rashid Khan 2013-12-04 15:48:36 -07:00
parent f4cc56468a
commit 6696e13073
5 changed files with 76 additions and 60 deletions

View File

@ -52,12 +52,18 @@ columns in the table, would trim each column at 20 character. The entirety of th
still available in the expanded view of the event. still available in the expanded view of the event.
// src/app/panels/table/module.js:105 // src/app/panels/table/module.js:105
spyable:: Set to false to disable the inspect icon localTime:: Set to true to adjust the timeField to the browser's local time
// src/app/panels/table/module.js:112 // src/app/panels/table/module.js:112
timeField:: If localTime is set to true, this field will be adjusted to the browsers local time
// src/app/panels/table/module.js:116
spyable:: Set to false to disable the inspect icon
// src/app/panels/table/module.js:120
==== Queries ==== Queries
queries object:: This object describes the queries to use on this panel. queries object:: This object describes the queries to use on this panel.
queries.mode::: Of the queries available, which to use. Options: +all, pinned, unpinned, selected+ queries.mode::: Of the queries available, which to use. Options: +all, pinned, unpinned, selected+
queries.ids::: In +selected+ mode, which query ids are selected. queries.ids::: In +selected+ mode, which query ids are selected.
// src/app/panels/table/module.js:116 // src/app/panels/table/module.js:124

View File

@ -128,6 +128,8 @@
}, },
"overflow": "min-height", "overflow": "min-height",
"fields": [], "fields": [],
"localTime": true,
"timeField": "@timestamp",
"highlight": [], "highlight": [],
"sortable": true, "sortable": true,
"header": true, "header": true,

View File

@ -1,48 +1,49 @@
<div class="row-fluid"> <div class="row-fluid">
<div class="span4"> <div class="section span6">
<form class="input-append"> <h5>Columns</h5>
<h6>Add Column</h6> <form class="input-append editor-option">
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model='newfield'> <input bs-typeahead="fields.list" type="text" class="input-small" ng-model='newfield'>
<button class="btn" ng-click="toggle_field(newfield);newfield=''"><i class="icon-plus"></i></button> <button class="btn" ng-click="toggle_field(newfield);newfield=''"><i class="icon-plus"></i></button>
</form> </form><br>
<span style="margin-left:3px" ng-repeat="field in $parent.panel.fields" class="label">{{field}} <i class="pointer icon-remove-sign" ng-click="toggle_field(field)"></i></span>
</div> </div>
<div class="span8"> <div class="section span6">
<h6>Columns <small>Click to remove</small></h6> <h5>Hightlighted Fields</h5>
<span style="margin-left:3px" ng-click="toggle_field(field)" ng-repeat="field in $parent.panel.fields" class="label pointer remove">{{field}} </span> <form class="input-append editor-option">
</div>
</div>
<div class="row-fluid">
<div class="span4">
<form class="input-append">
<h6>Add field</h6>
<input bs-typeahead="fields.list" type="text" class="input-small" ng-model='newhighlight' ng-change="set_refresh(true)"> <input bs-typeahead="fields.list" type="text" class="input-small" ng-model='newhighlight' ng-change="set_refresh(true)">
<button class="btn" ng-click="toggle_highlight(newhighlight);newhighlight=''"><i class="icon-plus"></i></button> <button class="btn" ng-click="toggle_highlight(newhighlight);newhighlight=''"><i class="icon-plus"></i></button>
</form> </form><br>
</div> <span style="margin-left:3px" ng-repeat="field in $parent.panel.highlight" class="label">{{field}} <i class="pointer icon-remove-sign" ng-click="toggle_highlight(field);set_refresh(true)" ></i></span>
<div class="span8">
<h6>Highlighted fields <small>Click to remove</small></h6>
<span style="margin-left:3px" ng-click="toggle_highlight(field);set_refresh(true)" ng-repeat="field in $parent.panel.highlight" class="label remove pointer">{{field}} </span>
</div> </div>
</div> </div>
<h5>Options</h5>
<div class="row-fluid"> <div class="editor-row">
<div class="span1"> <div class="section">
<h6>Header</h6><input type="checkbox" ng-model="panel.header" ng-checked="panel.header"> <h5>Options</h5>
</div> <div class="editor-option">
<div class="span1"> <h6>Header</h6><input type="checkbox" ng-model="panel.header" ng-checked="panel.header">
<h6>Sorting</h6><input type="checkbox" ng-model="panel.sortable" ng-checked="panel.sortable"> </div>
</div> <div class="editor-option">
<div class="span3" style="white-space:nowrap" ng-show='panel.sortable'> <h6>Sorting</h6><input type="checkbox" ng-model="panel.sortable" ng-checked="panel.sortable">
<h6>Sort</h6> </div>
<input ng-show="all_fields.length<=0 || !all_fields"style="width:85%" ng-model="panel.sort[0]" type="text"></input> <div class="editor-option" style="white-space:nowrap" ng-show='panel.sortable'>
<select ng-show="all_fields.length>0"style="width:85%" ng-model="panel.sort[0]" ng-options="f for f in all_fields"></select> <h6>Sort</h6>
<i ng-click="set_sort(panel.sort[0])" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i> <input class="input-small" bs-typeahead="fields.list" ng-model="panel.sort[0]" type="text"></input>
</div> <i ng-click="set_sort(panel.sort[0])" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
<div class="span2"><h6>Font Size</h6> </div>
<select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span> <div class="editor-option"><h6>Font Size</h6>
</div> <select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
<div class="span2"> </div>
<h6>Trim Factor <tip>Trim fields to this long divided by # of rows. Requires data refresh.</tip></h6> <div class="editor-option">
<input type="number" class="input-small" ng-model="panel.trimFactor" ng-change="set_refresh(true)"> <h6>Trim Factor <tip>Trim fields to this long divided by # of rows. Requires data refresh.</tip></h6>
<input type="number" class="input-small" ng-model="panel.trimFactor" ng-change="set_refresh(true)">
</div>
<div class="editor-option">
<h6>Local Time <tip>Adjust time field to browser's local time</tip></h6><input type="checkbox" ng-change="set_refresh(true)" ng-model="panel.localTime" ng-checked="panel.localTime">
</div>
<div class="editor-option" ng-show="panel.localTime">
<h6>Time Field</h6>
<input type="text" class="input-small" ng-model="panel.timeField" ng-change="set_refresh(true)" bs-typeahead="fields.list">
</div>
</div> </div>
</div> </div>

View File

@ -69,7 +69,10 @@
<tbody bindonce ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'"> <tbody bindonce ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
<tr ng-click="toggle_details(event)" class="pointer"> <tr ng-click="toggle_details(event)" class="pointer">
<td ng-if="panel.fields.length<1" bo-text="event._source|stringify|tableTruncate:panel.trimFactor:1"></td> <td ng-if="panel.fields.length<1" bo-text="event._source|stringify|tableTruncate:panel.trimFactor:1"></td>
<td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields" bo-html="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td> <td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields">
<span ng-if="!panel.localTime || panel.timeField != field" bo-html="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></span>
<span ng-if="panel.localTime && panel.timeField == field" bo-html="event.sort[1]|tableLocalTime:event"></span>
</td>
</tr> </tr>
<tr ng-if="event.kibana.details"> <tr ng-if="event.kibana.details">
<td colspan={{panel.fields.length}} ng-switch="event.kibana.view"> <td colspan={{panel.fields.length}} ng-switch="event.kibana.view">

View File

@ -109,6 +109,14 @@ function (angular, app, _, kbn, moment) {
* still available in the expanded view of the event. * still available in the expanded view of the event.
*/ */
trimFactor: 300, trimFactor: 300,
/** @scratch /panels/table/5
* localTime:: Set to true to adjust the timeField to the browser's local time
*/
localTime: false,
/** @scratch /panels/table/5
* timeField:: If localTime is set to true, this field will be adjusted to the browsers local time
*/
timeField: '@timestamp',
/** @scratch /panels/table/5 /** @scratch /panels/table/5
* spyable:: Set to false to disable the inspect icon * spyable:: Set to false to disable the inspect icon
*/ */
@ -258,7 +266,8 @@ function (angular, app, _, kbn, moment) {
_segment, _segment,
request, request,
boolQuery, boolQuery,
results; queries,
sort;
$scope.panel.error = false; $scope.panel.error = false;
@ -267,6 +276,12 @@ function (angular, app, _, kbn, moment) {
return; return;
} }
sort = [$scope.ejs.Sort($scope.panel.sort[0]).order($scope.panel.sort[1])];
if($scope.panel.localTime) {
sort.push($scope.ejs.Sort($scope.panel.timeField).order($scope.panel.sort[1]));
}
$scope.panelMeta.loading = true; $scope.panelMeta.loading = true;
_segment = _.isUndefined(segment) ? 0 : segment; _segment = _.isUndefined(segment) ? 0 : segment;
@ -275,7 +290,8 @@ function (angular, app, _, kbn, moment) {
request = $scope.ejs.Request().indices(dashboard.indices[_segment]); request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries); $scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
queries = querySrv.getQueryObjs($scope.panel.queries.ids);
boolQuery = $scope.ejs.BoolQuery(); boolQuery = $scope.ejs.BoolQuery();
_.each(queries,function(q) { _.each(queries,function(q) {
@ -294,14 +310,12 @@ function (angular, app, _, kbn, moment) {
.postTags('@end-highlight@') .postTags('@end-highlight@')
) )
.size($scope.panel.size*$scope.panel.pages) .size($scope.panel.size*$scope.panel.pages)
.sort($scope.panel.sort[0],$scope.panel.sort[1]); .sort(sort);
$scope.populate_modal(request); $scope.populate_modal(request);
results = request.doSearch();
// Populate scope when we have results // Populate scope when we have results
results.then(function(results) { request.doSearch().then(function(results) {
$scope.panelMeta.loading = false; $scope.panelMeta.loading = false;
if(_segment === 0) { if(_segment === 0) {
@ -470,19 +484,9 @@ function (angular, app, _, kbn, moment) {
}); });
// WIP // WIP
module.filter('tableFieldFormat', function(fields){ module.filter('tableLocalTime', function(){
return function(text,field,event,scope) { return function(text,event) {
var type; return moment(event.sort[1]).format("YYYY-MM-DDTHH:mm:ss.SSSZ");
if(
!_.isUndefined(fields.mapping[event._index]) &&
!_.isUndefined(fields.mapping[event._index][event._type])
) {
type = fields.mapping[event._index][event._type][field]['type'];
if(type === 'date' && scope.panel.normTimes) {
return moment(text).format('YYYY-MM-DD HH:mm:ss');
}
}
return text;
}; };
}); });