Browse Source

Added JSON and Raw views of events for #507 and #461

Rashid Khan 12 years ago
parent
commit
db088f5740

+ 0 - 2
src/app/components/kbn.js

@@ -90,8 +90,6 @@ function($, _) {
       return a[1] - b[1];
       return a[1] - b[1];
     }).reverse().slice(0,count);
     }).reverse().slice(0,count);
 
 
-    console.log(hasArrays);
-
     return {
     return {
       counts: counts,
       counts: counts,
       hasArrays : hasArrays
       hasArrays : hasArrays

+ 13 - 5
src/app/panels/table/module.html

@@ -56,19 +56,25 @@
         </thead>
         </thead>
         <tbody ng-repeat="event in data | slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
         <tbody 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-repeat="field in panel.fields" ng-bind-html-unsafe="(event.highlight[field]||event._source[field]) | tableFieldFormat:field:event:this |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td>-->
             <td ng-show="panel.fields.length<1">{{event._source|stringify|tableTruncate:panel.trimFactor:1}}</td>
             <td ng-show="panel.fields.length<1">{{event._source|stringify|tableTruncate:panel.trimFactor:1}}</td>
-            <td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields" ng-bind-html-unsafe="(event.highlight[field]||event._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td>
+            <td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields" ng-bind-html-unsafe="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td>
           </tr>
           </tr>
           <tr ng-show="event.kibana.details">
           <tr ng-show="event.kibana.details">
-            <td colspan=1000>
-              <table class='table table-bordered table-condensed'>
+            <td colspan=10000 ng-switch="event.kibana.view">
+              <span>
+                View:
+                <a class="link" ng-class="{'strong':event.kibana.view == 'table'}" ng-click="event.kibana.view = 'table'">Table</a> /
+                <a class="link" ng-class="{'strong':event.kibana.view == 'json'}" ng-click="event.kibana.view = 'json'">JSON</a> /
+                <a class="link" ng-class="{'strong':event.kibana.view == 'raw'}" ng-click="event.kibana.view = 'raw'">Raw</a>
+                <i class="link pull-right icon-chevron-up" ng-click="toggle_details(event)"></i>
+              </span>
+              <table class='table table-bordered table-condensed' ng-switch-when="table">
                 <thead>
                 <thead>
                   <th>Field</th>
                   <th>Field</th>
                   <th>Action</th>
                   <th>Action</th>
                   <th>Value</th>
                   <th>Value</th>
                 </thead>
                 </thead>
-                <tr ng-repeat="(key,value) in event.kibana.details._source" ng-class-odd="'odd'">
+                <tr ng-repeat="(key,value) in event.kibana._source" ng-class-odd="'odd'">
                   <td>{{key}}</td>
                   <td>{{key}}</td>
                   <td style="white-space:nowrap">
                   <td style="white-space:nowrap">
                     <i class='icon-search pointer' ng-click="build_search(key,value)" bs-tooltip="'Add filter to match this value'"></i>
                     <i class='icon-search pointer' ng-click="build_search(key,value)" bs-tooltip="'Add filter to match this value'"></i>
@@ -79,6 +85,8 @@
                   <td style="white-space:pre-wrap" ng-bind-html-unsafe="value|noXml|urlLink|stringify"></td>
                   <td style="white-space:pre-wrap" ng-bind-html-unsafe="value|noXml|urlLink|stringify"></td>
                 </tr>
                 </tr>
               </table>
               </table>
+              <pre style="white-space:pre-wrap"  ng-bind-html="without_kibana(event)|tableJson:2" ng-switch-when="json"></pre>
+              <pre ng-bind-html="without_kibana(event)|tableJson:1" ng-switch-when="raw"></pre>
             </td>
             </td>
           </tr>
           </tr>
         </tbody>
         </tbody>

+ 59 - 15
src/app/panels/table/module.js

@@ -88,7 +88,7 @@ function (angular, app, _, kbn, moment) {
     $scope.percent = kbn.to_percent;
     $scope.percent = kbn.to_percent;
 
 
     $scope.toggle_micropanel = function(field,groups) {
     $scope.toggle_micropanel = function(field,groups) {
-      var docs = _.pluck($scope.data,'_source');
+      var docs = _.map($scope.data,function(_d){return _d.kibana._source;});
       var topFieldValues = kbn.top_field_values(docs,field,10,groups);
       var topFieldValues = kbn.top_field_values(docs,field,10,groups);
       $scope.micropanel = {
       $scope.micropanel = {
         field: field,
         field: field,
@@ -131,8 +131,9 @@ function (angular, app, _, kbn, moment) {
     };
     };
 
 
     $scope.toggle_details = function(row) {
     $scope.toggle_details = function(row) {
-      row.kibana = row.kibana || {};
-      row.kibana.details = !row.kibana.details ? $scope.without_kibana(row) : false;
+      row.kibana.details = row.kibana.details ? false : true;
+      row.kibana.view = row.kibana.view || 'table';
+      //row.kibana.details = !row.kibana.details ? $scope.without_kibana(row) : false;
     };
     };
 
 
     $scope.page = function(page) {
     $scope.page = function(page) {
@@ -220,21 +221,21 @@ function (angular, app, _, kbn, moment) {
         // Check that we're still on the same query, if not stop
         // Check that we're still on the same query, if not stop
         if($scope.query_id === query_id) {
         if($scope.query_id === query_id) {
           $scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) {
           $scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) {
-            return {
-              _source   : kbn.flatten_json(hit._source),
-              highlight : kbn.flatten_json(hit.highlight||{}),
-              _type     : hit._type,
-              _index    : hit._index,
-              _id       : hit._id,
-              _sort     : hit.sort
+            var _h = _.clone(hit);
+            //_h._source = kbn.flatten_json(hit._source);
+            //_h.highlight = kbn.flatten_json(hit.highlight||{});
+            _h.kibana = {
+              _source : kbn.flatten_json(hit._source),
+              highlight : kbn.flatten_json(hit.highlight||{})
             };
             };
+            return _h;
           }));
           }));
 
 
           $scope.hits += results.hits.total;
           $scope.hits += results.hits.total;
 
 
           // Sort the data
           // Sort the data
           $scope.data = _.sortBy($scope.data, function(v){
           $scope.data = _.sortBy($scope.data, function(v){
-            return v._sort[0];
+            return v.sort[0];
           });
           });
 
 
           // Reverse if needed
           // Reverse if needed
@@ -266,10 +267,9 @@ function (angular, app, _, kbn, moment) {
     };
     };
 
 
     $scope.without_kibana = function (row) {
     $scope.without_kibana = function (row) {
-      return {
-        _source   : row._source,
-        highlight : row.highlight
-      };
+      var _c = _.clone(row);
+      delete _c.kibana;
+      return _c;
     };
     };
 
 
     $scope.set_refresh = function (state) {
     $scope.set_refresh = function (state) {
@@ -283,6 +283,20 @@ function (angular, app, _, kbn, moment) {
       $scope.refresh =  false;
       $scope.refresh =  false;
     };
     };
 
 
+    $scope.locate = function(obj, path) {
+      path = path.split('.');
+      var arrayPattern = /(.+)\[(\d+)\]/;
+      for (var i = 0; i < path.length; i++) {
+        var match = arrayPattern.exec(path[i]);
+        if (match) {
+          obj = obj[match[1]][parseInt(match[2],10)];
+        } else {
+          obj = obj[path[i]];
+        }
+      }
+      return obj;
+    };
+
 
 
   });
   });
 
 
@@ -311,6 +325,36 @@ function (angular, app, _, kbn, moment) {
     };
     };
   });
   });
 
 
+  module.filter('tableJson', function() {
+    var json;
+    return function(text,prettyLevel) {
+      if (!_.isUndefined(text) && !_.isNull(text) && text.toString().length > 0) {
+        json = angular.toJson(text,prettyLevel > 0 ? true : false);
+        json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+        if(prettyLevel > 1) {
+          /* jshint maxlen: false */
+          json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
+            var cls = 'number';
+            if (/^"/.test(match)) {
+              if (/:$/.test(match)) {
+                cls = 'key strong';
+              } else {
+                cls = '';
+              }
+            } else if (/true|false/.test(match)) {
+              cls = 'boolean';
+            } else if (/null/.test(match)) {
+              cls = 'null';
+            }
+            return '<span class="' + cls + '">' + match + '</span>';
+          });
+        }
+        return json;
+      }
+      return '';
+    };
+  });
+
   // WIP
   // WIP
   module.filter('tableFieldFormat', function(fields){
   module.filter('tableFieldFormat', function(fields){
     return function(text,field,event,scope) {
     return function(text,field,event,scope) {

File diff suppressed because it is too large
+ 0 - 0
src/css/bootstrap.dark.min.css


File diff suppressed because it is too large
+ 0 - 0
src/css/bootstrap.light.min.css


+ 9 - 4
src/vendor/bootstrap/less/overrides.less

@@ -41,7 +41,7 @@
 }
 }
 
 
 .row-close {
 .row-close {
-  color: #bbb;  
+  color: #bbb;
   position: absolute;
   position: absolute;
   font-size: 9pt;
   font-size: 9pt;
   font-weight: 200;
   font-weight: 200;
@@ -51,7 +51,7 @@
 
 
 .row-open {
 .row-open {
   text-align: right;
   text-align: right;
-  color: #bbb;  
+  color: #bbb;
   margin-top:30px;
   margin-top:30px;
   position: absolute;
   position: absolute;
   font-size: 13pt;
   font-size: 13pt;
@@ -62,8 +62,8 @@
   -webkit-transform-origin: 40px;
   -webkit-transform-origin: 40px;
   transform-origin: 40px;
   transform-origin: 40px;
   transform: rotate(-90deg);
   transform: rotate(-90deg);
-  -webkit-transform: rotate(-90deg); 
-  -moz-transform: rotate(-90deg); 
+  -webkit-transform: rotate(-90deg);
+  -moz-transform: rotate(-90deg);
   -ms-transform: rotate(-90deg);
   -ms-transform: rotate(-90deg);
 }
 }
 
 
@@ -178,6 +178,11 @@
   width: 75px;
   width: 75px;
 }
 }
 
 
+.string {color:lighten(@textColor, 5%)}
+.number {color:lighten(@infoText, 5%)}
+.boolean {color:lighten(@warningText, 5%)}
+.key {color:lighten(@errorText, 5%)}
+
 .typeahead { z-index: 1051; }
 .typeahead { z-index: 1051; }
 
 
 .btn-active {
 .btn-active {

Some files were not shown because too many files changed in this diff