Add event log search and filter capabilities
Change-Id: I9dc891e0f1e30abe488d401c57e1cf4f5656c3af
Signed-off-by: Iftekharul Islam <iislam@us.ibm.com>
diff --git a/app/server-health/controllers/log-controller.html b/app/server-health/controllers/log-controller.html
new file mode 100644
index 0000000..713b879
--- /dev/null
+++ b/app/server-health/controllers/log-controller.html
@@ -0,0 +1,70 @@
+<div id="event-log">
+ <div class="row column">
+ <h1>Event Log</h1>
+ </div>
+ <section class="row column">
+ <div class="page-header">
+ <h2 class="inline h4">All events generated by the system</h2>
+ <div class="event-log__timezone inline float-right">
+ <button class="dropdown__button" ng-click="timezone = timezone == true ? false : true;" toggle-flag="timezone"
+ >User timezone: <span ng-show="tmz== 'EDT'">EDT (UTC-4)</span><span ng-show="tmz=='UTC'">UTC - 0</span>
+ </button>
+ <ul class="dropdown__list inline" ng-show="timezone">
+ <li>
+ <button ng-click="tmz = 'EDT'; timezone=false;">User timezone: EDT (UTC-4)</button>
+ </li>
+ <li>
+ <button ng-click="tmz = 'UTC'; timezone=false;">UTC Timezone : UTC - 0</button>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </section>
+ <!-- Filters -->
+ <section class="row column">
+ <!-- search -->
+ <log-search-control></log-search-control>
+ <!-- filters -->
+ <log-filter></log-filter>
+ </section> <!-- end filter -->
+ <section id="event-log__events" class="row column">
+ <div id="event__actions-bar" class="row header__actions-bar">
+ <div class="column small-1 large-1 event-log__col-check">
+ <label class="control-check">
+ <input type="checkbox" name="events__check-all" ng-model="all" ng-checked="(logs|filter:{selected: true}).length == logs.length"/>
+ <div class="control__indicator"></div>
+ </label>
+ </div>
+ <div class="column small-11 large-11 end col-logged-events">
+ <!-- top bar confirmation - ADD ACTIVE CLASS TO DISPLAY-->
+ <div class="inline__confirm event__confirm" ng-class="{active: confirm}">
+ <div class="inline__confirm-message">
+ <p class="h3"><i></i>Are you sure you want to <strong class="ng-binding">delete {{selectedEvents.length}} logs</strong>?
+ </p>
+ </div>
+ <div class="inline__confirm-buttons">
+ <button class="btn-primary" ng-click="accept()">Yes</button>
+ <button class="btn-primary" ng-click="confirm = false">No</button>
+ </div>
+ </div>
+ <p class="inline"><span class="event__select-count">{{filteredLogs.length}}</span> Events are logged</p>
+ <!-- when logs are selected, this text changes to show how many logs are checked -->
+ <div class="event__actions">
+ <button class="inline btn-delete" ng-show="selectedEvents.length || all" ng-click="confirm= ! confirm">
+ <img class="event__icon" src="assets/images/icon-trashcan-white.svg" alt="">Delete
+ </button>
+ <button class="inline btn-resolve" ng-show="selectedEvents.length || all">
+ <img class="event__icon" src="assets/images/icon-checklist-white.svg" alt="">Mark as resolved
+ </button>
+ <a ng-href="data:text/json;charset=utf-8,{{export_data}}" class="inline btn-export" download="{{export_name}}" ng-show="selectedEvents.length || all">Export</a>
+ </div>
+ </div>
+ </div>
+ <log-event
+ dir-paginate="event in (filteredLogs = (logs|filter:filterBySeverity|filter:filterByStatus|filter:filterByDate|filter:filterBySearchTerms))| itemsPerPage: itemsPerPage"
+ event="event"
+ tmz="tmz">
+ </log-event>
+ </section>
+ <dir-pagination-controls template-url="common/directives/dirPagination.tpl.html"></dir-pagination-controls>
+</div> <!-- end event log -->
\ No newline at end of file
diff --git a/app/server-health/controllers/log-controller.js b/app/server-health/controllers/log-controller.js
new file mode 100644
index 0000000..59ebd01
--- /dev/null
+++ b/app/server-health/controllers/log-controller.js
@@ -0,0 +1,139 @@
+/**
+ * Controller for log
+ *
+ * @module app/serverHealth
+ * @exports logController
+ * @name logController
+ * @version 0.1.0
+ */
+
+window.angular && (function (angular) {
+ 'use strict';
+ var logData = [], originalData = {};
+ angular
+ .module('app.serverHealth')
+ .controller('logController', [
+ '$scope',
+ '$window',
+ 'APIUtils',
+ 'dataService',
+ 'Constants',
+ function($scope, $window, APIUtils, dataService, Constants){
+ $scope.dataService = dataService;
+ $scope.logs = [];
+ $scope.tmz = 'EDT';
+ $scope.itemsPerPage = Constants.PAGINATION.LOG_ITEMS_PER_PAGE;
+ // priority buttons
+ $scope.selectedSeverity = {
+ all: true,
+ low: false,
+ medium: false,
+ high: false
+ };
+ $scope.selectedStatus = {
+ all: true,
+ resolved: false
+ };
+
+ $scope.customSearch = "";
+ $scope.searchItems = [];
+ $scope.selectedEvents = [];
+
+ $scope.loadLogs = function(){
+ APIUtils.getLogs(function(data, originalData){
+ logData = data;
+ originalData = originalData;
+ $scope.logs = data;
+ $scope.originalData = originalData;
+ });
+ };
+ $scope.jsonData = function(data){
+ return JSON.stringify(data);
+ };
+
+ $scope.filterBySeverity = function(log){
+ if($scope.selectedSeverity.all) return true;
+
+ return( (log.severity_flags.low && $scope.selectedSeverity.low) ||
+ (log.severity_flags.medium && $scope.selectedSeverity.medium) ||
+ (log.severity_flags.high && $scope.selectedSeverity.high)
+ );
+ }
+
+
+ $scope.filterByStatus = function(log){
+ if ($scope.selectedStatus.all) return true;
+ return( (log.Resolved && $scope.selectedStatus.resolved)||
+ (!log.Resolved && !$scope.selectedStatus.resolved)
+ );
+ }
+
+ $scope.filterByDate = function(log){
+ if($scope.start_date && $scope.end_date){
+ var date = new Date(log.Timestamp);
+ return (date >= $scope.start_date &&
+ date <= $scope.end_date );
+ }else{
+ return true;
+ }
+ }
+
+ $scope.filterBySearchTerms = function(log){
+ if(!$scope.searchItems.length) return true;
+
+ var flag = false;
+ for(var i = 0, length = $scope.searchItems.length; i < length; i++){
+ if(log.search_text.indexOf($scope.searchItems[i].toLowerCase()) == -1) return false;
+ }
+ return true;
+ }
+
+ $scope.addSearchItem = function(searchTerms){
+ var terms = searchTerms.split(" ");
+ terms.forEach(function(searchTerm){
+ if($scope.searchItems.indexOf(searchTerm) == -1){
+ $scope.searchItems.push(searchTerm);
+ }
+ });
+ }
+
+ $scope.clearSearchItem = function(searchTerm){
+ $scope.searchItems = [];
+ }
+
+ $scope.removeSearchItem = function(searchTerm){
+ var termIndex = $scope.searchItems.indexOf(searchTerm);
+
+ if(termIndex > -1){
+ $scope.searchItems.splice(termIndex,1);
+ }
+ }
+
+ $scope.$watch('all', function(){
+ $scope.logs.forEach(function(item){
+ item.selected = $scope.all;
+ });
+ });
+
+ function updateExportData(){
+ $scope.export_name = ($scope.selectedEvents.length == 1) ? $scope.selectedEvents[0].Id + ".json" : "export.json";
+ var data = {};
+ $scope.selectedEvents.forEach(function(item){
+ data[item.data.key] = item.data.value;
+ });
+ $scope.export_data = JSON.stringify(data);
+ }
+
+ $scope.$watch('logs', function(){
+ $scope.selectedEvents = $scope.logs.filter(function(item){
+ return item.selected;
+ });
+ updateExportData();
+ }, true);
+
+ $scope.loadLogs();
+ }
+ ]
+ );
+
+})(angular);