You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2017/06/22 13:16:47 UTC
[20/21] ambari git commit: AMBARI-21322 Log Search UI: implement
loading of logs list with filter conditions. (ababiichuk)
AMBARI-21322 Log Search UI: implement loading of logs list with filter conditions. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1a2d6ced
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1a2d6ced
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1a2d6ced
Branch: refs/heads/branch-feature-logsearch-ui
Commit: 1a2d6cedc162c7b71b93d5f5c3272aed30bc4fc2
Parents: 56681d7
Author: ababiichuk <ab...@hortonworks.com>
Authored: Thu Jun 22 13:47:53 2017 +0300
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Jun 22 15:45:53 2017 +0300
----------------------------------------------------------------------
.../queries/audit-logs-query-params.class.ts | 38 +
.../app/classes/queries/query-params.class.ts | 23 +
.../queries/service-logs-query-params.class.ts | 32 +
.../dropdown-list/dropdown-list.component.less | 22 +
.../dropdown-list/dropdown-list.component.ts | 3 +-
.../filter-dropdown.component.spec.ts | 2 +
.../filter-dropdown.component.ts | 11 +-
.../filter-text-field.component.html | 2 +-
.../filter-text-field.component.spec.ts | 2 +
.../filter-text-field.component.ts | 8 +-
.../filters-panel/filters-panel.component.html | 16 +-
.../filters-panel/filters-panel.component.less | 9 +-
.../src/app/logs-list/logs-list.component.html | 8 +-
.../src/app/logs-list/logs-list.component.less | 5 +-
.../app/logs-list/logs-list.component.spec.ts | 28 +
.../src/app/logs-list/logs-list.component.ts | 111 ++-
.../main-container.component.html | 2 +-
.../app/menu-button/menu-button.component.html | 3 +-
.../menu-button/menu-button.component.spec.ts | 6 +-
.../app/menu-button/menu-button.component.ts | 14 +-
.../src/app/models/log.model.ts | 2 +-
.../src/app/models/service-log.model.ts | 2 +-
.../src/app/services/filtering.service.ts | 153 +++-
.../src/app/services/http-client.service.ts | 72 +-
.../src/app/services/mock-api-data.service.ts | 803 ++---------------
.../src/app/variables.less | 7 +-
.../src/assets/mock-data.ts | 883 +++++++++++++++++++
27 files changed, 1379 insertions(+), 888 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/audit-logs-query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/audit-logs-query-params.class.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/audit-logs-query-params.class.ts
new file mode 100644
index 0000000..749ed21
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/audit-logs-query-params.class.ts
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http; //www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {QueryParams} from '@app/classes/queries/query-params.class';
+
+export class AuditLogsQueryParams extends QueryParams {
+ startIndex?: string = '0';
+ page?: string = '0';
+ pageSize?: string = '25';
+ sortBy?: string;
+ sortType?: string;
+ start_time?: string;
+ end_time?: string;
+ clusters?: string;
+ iMessage?: string;
+ eMessage?: string;
+ mustBe?: string;
+ mustNot?: string;
+ includeQuery?: string;
+ excludeQuery?: string;
+ from?: string;
+ to?: string;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/query-params.class.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/query-params.class.ts
new file mode 100644
index 0000000..73db35a
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/query-params.class.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http; //www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class QueryParams {
+ constructor(options: QueryParams) {
+ Object.assign(this, options);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/service-logs-query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/service-logs-query-params.class.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/service-logs-query-params.class.ts
new file mode 100644
index 0000000..829783e
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/classes/queries/service-logs-query-params.class.ts
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http; //www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {AuditLogsQueryParams} from '@app/classes/queries/audit-logs-query-params.class';
+
+export class ServiceLogsQueryParams extends AuditLogsQueryParams {
+ level?: string;
+ host_name?: string;
+ component_name?: string;
+ file_name?: string;
+ bundle_id?: string;
+ hostList?: string;
+ find?: string;
+ sourceLogId?: string;
+ keywordType?: string;
+ token?: string;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.less
new file mode 100644
index 0000000..d0f079a
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.less
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+:host {
+ max-height: 500px; // TODO get rid of magic number, base on actual design
+ overflow-y: auto;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.ts
index dfd2527..808fcf8 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/dropdown-list/dropdown-list.component.ts
@@ -20,7 +20,8 @@ import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'ul.dropdown-menu',
- templateUrl: './dropdown-list.component.html'
+ templateUrl: './dropdown-list.component.html',
+ styleUrls: ['./dropdown-list.component.less']
})
export class DropdownListComponent implements OnInit {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.spec.ts
index ba0bd03..e0414f3 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.spec.ts
@@ -20,6 +20,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {Http} from '@angular/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {FilteringService} from '@app/services/filtering.service';
import {FilterDropdownComponent} from './filter-dropdown.component';
@@ -39,6 +40,7 @@ describe('FilterDropdownComponent', () => {
useFactory: HttpLoaderFactory,
deps: [Http]
})],
+ providers: [FilteringService],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.ts
index de6e79b..faaafcb 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-dropdown/filter-dropdown.component.ts
@@ -16,6 +16,7 @@
*/
import {Component, OnInit, Input} from '@angular/core';
+import {FilteringService} from '@app/services/filtering.service';
@Component({
selector: 'filter-dropdown',
@@ -24,7 +25,8 @@ import {Component, OnInit, Input} from '@angular/core';
})
export class FilterDropdownComponent implements OnInit {
- constructor() { }
+ constructor(private filtering: FilteringService) {
+ }
ngOnInit() {
this.filterInstance.selectedValue = this.filterInstance.options[0].value;
@@ -38,8 +40,11 @@ export class FilterDropdownComponent implements OnInit {
options: any[];
setSelectedValue(options: any): void {
- this.filterInstance.selectedValue = options.value;
- this.filterInstance.selectedLabel = options.label;
+ if (this.filterInstance.selectedValue !== options.value) {
+ this.filterInstance.selectedValue = options.value;
+ this.filterInstance.selectedLabel = options.label;
+ this.filtering.filteringSubject.next(null);
+ }
};
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.html
index 3ccbd6f..ed3c4ba 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.html
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.html
@@ -17,5 +17,5 @@
<div class="input-group">
<span class="input-group-addon">{{filterInstance.label | translate}}</span>
- <input type="text" class="form-control" [(ngModel)]="filterInstance.value">
+ <input type="text" class="form-control" [(ngModel)]="filterInstance.selectedValue" (change)="onValueChange()"> <!-- TODO use ngModelChange with debounce -->
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.spec.ts
index c54171a..e4f026c 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.spec.ts
@@ -21,6 +21,7 @@ import {Http} from '@angular/http';
import {FormsModule} from '@angular/forms';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
+import {FilteringService} from '@app/services/filtering.service';
import {FilterTextFieldComponent} from './filter-text-field.component';
@@ -43,6 +44,7 @@ describe('FilterTextFieldComponent', () => {
deps: [Http]
})
],
+ providers: [FilteringService],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.ts
index 6bab2e6..3f23ffd 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filter-text-field/filter-text-field.component.ts
@@ -16,6 +16,7 @@
*/
import {Component, OnInit, Input} from '@angular/core';
+import {FilteringService} from '@app/services/filtering.service';
@Component({
selector: 'filter-text-field',
@@ -24,7 +25,8 @@ import {Component, OnInit, Input} from '@angular/core';
})
export class FilterTextFieldComponent implements OnInit {
- constructor() { }
+ constructor(private filtering: FilteringService) {
+ }
ngOnInit() {
}
@@ -32,4 +34,8 @@ export class FilterTextFieldComponent implements OnInit {
@Input()
filterInstance: any;
+ onValueChange() {
+ this.filtering.filteringSubject.next(null);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.html
index 20f4353..6387c22 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.html
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.html
@@ -20,17 +20,19 @@
<filter-text-field [filterInstance]="filtering.filters.text"></filter-text-field>
<filter-dropdown [filterInstance]="filtering.filters.timeRange"></filter-dropdown>
<filter-dropdown [filterInstance]="filtering.filters.timeZone"></filter-dropdown>
- <button class="btn btn-success" type="button">
+ <!--button class="btn btn-success" type="button">
<span class="fa fa-search"></span>
- </button>
+ </button-->
</div>
<div class="default-flex col-md-4">
- <menu-button [label]="filtering.filters.components.label" [iconClass]="filtering.filters.components.iconClass"
- [subItems]="filtering.filters.components.options" [isFilter]="true"></menu-button>
- <menu-button [label]="filtering.filters.levels.label" [iconClass]="filtering.filters.levels.iconClass"
- [subItems]="filtering.filters.levels.options" [isFilter]="true"></menu-button>
- <menu-button label="filter.capture" iconClass="fa fa-caret-right"></menu-button>
<a href="#">
<span class="fa fa-search-minus"></span> {{'filter.excluded' | translate}}
</a>
+ <menu-button [label]="filtering.filters.components.label" [iconClass]="filtering.filters.components.iconClass"
+ [subItems]="filtering.filters.components.options" [isFilter]="true"
+ [filterInstance]="filtering.filters.components"></menu-button>
+ <menu-button [label]="filtering.filters.levels.label" [iconClass]="filtering.filters.levels.iconClass"
+ [subItems]="filtering.filters.levels.options" [isFilter]="true"
+ [filterInstance]="filtering.filters.levels"></menu-button>
+ <menu-button label="filter.capture" iconClass="fa fa-caret-right"></menu-button>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.less
index d2400a4..46a157c 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.less
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/filters-panel/filters-panel.component.less
@@ -29,10 +29,17 @@
filter-dropdown {
border: @input-border;
- border-right-width: 0;
+
+ &:not(:last-child) {
+ border-right-width: 0;
+ }
&:first-child {
border-radius: @button-border-radius 0 0 @button-border-radius;
}
+
+ &:last-child {
+ border-radius: 0 @button-border-radius @button-border-radius 0;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.html
index cf4bb57..827f63c 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<accordion-panel *ngFor="let log of logs; let i = index" [toggleId]="'details-' + i" class="col-md-12">
+<accordion-panel *ngFor="let log of logs | async; let i = index" [toggleId]="'details-' + i" class="col-md-12">
<ng-template>
- <div [ngClass]="'hexagon ' + log.level"></div>
- <div [ngClass]="'col-md-1 log-status ' + log.level">{{log.level}}</div>
+ <div [ngClass]="'hexagon ' + log.className"></div>
+ <div [ngClass]="'col-md-1 log-status ' + log.className">{{log.level}}</div>
<div class="col-md-3">
<div class="log-type">{{log.type}}</div>
<time class="log-time">{{log.time}}</time>
@@ -29,7 +29,7 @@
<span class="action-icon fa fa-external-link"></span>
<span class="action-icon fa fa-bullseye"></span>
</div>
- <div class="log-content" [innerHTML]="log.content"></div>
+ <div class="log-content">{{log.message}}</div>
</div>
</ng-template>
</accordion-panel>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.less
index 6bf54fe..6ed0463 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.less
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.less
@@ -19,7 +19,9 @@
:host {
display: block;
- margin-top: @block-margin-top;
+ overflow: hidden;
+ padding-top: @block-margin-top;
+ background-color: @main-background-color; // TODO implement actual color
.hexagon {
// TODO get rid of magic numbers, base on actual design
@@ -102,6 +104,7 @@
overflow: hidden;
max-height: @default-line-height * 2em;
padding-right: 65px;
+ white-space: pre-wrap;
}
.log-actions {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.spec.ts
index 53cdee6..072bfcd 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.spec.ts
@@ -17,16 +17,44 @@
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {StoreModule} from '@ngrx/store';
+import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service';
+import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service';
+import {HttpClientService} from '@app/services/http-client.service';
+import {FilteringService} from '@app/services/filtering.service';
import {LogsListComponent} from './logs-list.component';
describe('LogsListComponent', () => {
let component: LogsListComponent;
let fixture: ComponentFixture<LogsListComponent>;
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ };
+ }
+ };
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LogsListComponent],
+ imports: [
+ StoreModule.provideStore({
+ auditLogs,
+ serviceLogs
+ })
+ ],
+ providers: [
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ },
+ AuditLogsService,
+ ServiceLogsService,
+ FilteringService
+ ],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.ts
index 5fd0ce5..6bc5ab9 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/logs-list/logs-list.component.ts
@@ -15,7 +15,11 @@
* limitations under the License.
*/
-import {Component, OnInit} from '@angular/core';
+import {Component, OnInit, Input} from '@angular/core';
+import 'rxjs/add/operator/map';
+import {HttpClientService} from '@app/services/http-client.service';
+import {ServiceLogsService} from '@app/services/storage/service-logs.service';
+import {FilteringService} from '@app/services/filtering.service';
@Component({
selector: 'logs-list',
@@ -24,56 +28,69 @@ import {Component, OnInit} from '@angular/core';
})
export class LogsListComponent implements OnInit {
- constructor() {
+ constructor(private httpClient: HttpClientService, private serviceLogsStorage: ServiceLogsService, private filtering: FilteringService) {
+ this.filtering.filteringSubject.subscribe(this.loadLogs.bind(this));
}
ngOnInit() {
+ this.loadLogs();
}
- // TODO implement loading logs from API
- private readonly logs = [
- {
- level: 'fatal',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'error',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'warn',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'info',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'debug',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'trace',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- },
- {
- level: 'unknown',
- type: 'ambari_agent',
- time: '2017/01/31 18:00:00',
- content: 'Something went wrong.<br>Please restart ambari-agent.<br>See log file for details.'
- }
- ];
+ @Input()
+ private logsArrayId: string;
+
+ private readonly usedFilters = {
+ clusters: ['clusters'],
+ text: ['iMessage'],
+ timeRange: ['end_time', 'start_time'],
+ components: ['component_name'],
+ levels: ['level']
+ };
+
+ private logs = this.serviceLogsStorage.getInstances().map(logs => {
+ return logs.map(log => {
+ return {
+ type: log.type,
+ level: log.level,
+ className: log.level.toLowerCase(),
+ message: log.log_message,
+ time: new Date(log.logtime).toLocaleDateString() + ' ' + new Date(log.logtime).toLocaleTimeString() // TODO use moment with custom time zone
+ }
+ });
+ });
+
+ private loadLogs(): void {
+ this.httpClient.get(this.logsArrayId, this.getParams()).subscribe(response => {
+ this.serviceLogsStorage.clear();
+ const logs = response.json().logList;
+ this.serviceLogsStorage.addInstances(logs);
+ });
+ }
+
+ private getParams(): any {
+ let params = {};
+ Object.keys(this.usedFilters).forEach(key => {
+ const inputFilter = this.filtering.filters[key],
+ inputValue = inputFilter.selectedValue,
+ paramNames = this.usedFilters[key];
+ paramNames.forEach(paramName => {
+ let value;
+ const valueGetter = this.filtering.valueGetters[paramName];
+ if (valueGetter) {
+ if (paramName === 'start_time') {
+ value = valueGetter(inputValue, params['end_time']);
+ } else {
+ value = valueGetter(inputValue);
+ }
+ } else {
+ value = inputValue;
+ }
+ if (value) {
+ params[paramName] = value;
+ }
+ });
+ }, this);
+ return params;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/main-container/main-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/main-container/main-container.component.html
index 34af2b8..61562d2 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/main-container/main-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/main-container/main-container.component.html
@@ -17,4 +17,4 @@
<login-form *ngIf="!httpClient.isAuthorized"></login-form>
<filters-panel *ngIf="httpClient.isAuthorized" class="row"></filters-panel>
-<logs-list *ngIf="httpClient.isAuthorized"></logs-list>
+<logs-list *ngIf="httpClient.isAuthorized" [logsArrayId]="'serviceLogs'"></logs-list>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.html
index 4ed01bd..132d717 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.html
@@ -22,5 +22,6 @@
<br>
<a *ngIf="label" (mousedown)="onMouseDown($event)" [ngClass]="labelClass" (mouseup)="onMouseUp($event)"
(click)="$event.stopPropagation()">{{label | translate}}</a>
- <ul class="dropdown-menu" [isFilter]="isFilter" *ngIf="hasSubItems" [items]="subItems"></ul>
+ <ul class="dropdown-menu" [isFilter]="isFilter" *ngIf="hasSubItems" [items]="subItems"
+ (selectedItemChange)="setSelectedValue($event)"></ul>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.spec.ts
index 9af8f00..424d322 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.spec.ts
@@ -22,6 +22,7 @@ import {Http} from '@angular/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {ComponentActionsService} from '@app/services/component-actions.service';
+import {FilteringService} from '@app/services/filtering.service';
import {MenuButtonComponent} from './menu-button.component';
@@ -42,7 +43,10 @@ describe('MenuButtonComponent', () => {
useFactory: HttpLoaderFactory,
deps: [Http]
})],
- providers: [ComponentActionsService],
+ providers: [
+ ComponentActionsService,
+ FilteringService
+ ],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.ts
index 9505f5b..ded01b7 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/menu-button/menu-button.component.ts
@@ -18,6 +18,7 @@
import {Component, AfterViewInit, Input, ViewChild, ElementRef} from '@angular/core';
import {ComponentActionsService} from '@app/services/component-actions.service';
+import {FilteringService} from '@app/services/filtering.service';
import * as $ from 'jquery';
@Component({
@@ -27,7 +28,7 @@ import * as $ from 'jquery';
})
export class MenuButtonComponent implements AfterViewInit {
- constructor(private actions: ComponentActionsService) {
+ constructor(private actions: ComponentActionsService, private filtering: FilteringService) {
}
ngAfterViewInit() {
@@ -46,6 +47,9 @@ export class MenuButtonComponent implements AfterViewInit {
isFilter: boolean;
@Input()
+ filterInstance?: any;
+
+ @Input()
iconClass: string;
@Input()
@@ -87,4 +91,12 @@ export class MenuButtonComponent implements AfterViewInit {
}
}
+ setSelectedValue(options: any): void {
+ if (this.filterInstance.selectedValue !== options.value) {
+ this.filterInstance.selectedValue = options.value;
+ this.filterInstance.selectedLabel = options.label;
+ this.filtering.filteringSubject.next(null);
+ }
+ };
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log.model.ts
index 825b4cf..abe1b48 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log.model.ts
@@ -32,6 +32,6 @@ export interface Log {
event_md5: string;
event_dur_ms: number;
_ttl_: string;
- _expire_at_: string;
+ _expire_at_: number;
_router_field_?: number;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log.model.ts
index e386ad5..6f76bcc 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log.model.ts
@@ -22,6 +22,6 @@ export interface ServiceLog extends Log {
path: string;
host: string;
level: string;
- logtime: string;
+ logtime: number;
ip: string;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/services/filtering.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/filtering.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/filtering.service.ts
index 84cbc50..c4d2bdf 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/filtering.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/filtering.service.ts
@@ -17,6 +17,7 @@
*/
import {Injectable} from '@angular/core';
+import {Subject} from 'rxjs/Subject';
import * as moment from 'moment-timezone';
@Injectable()
@@ -26,67 +27,110 @@ export class FilteringService {
}
// TODO implement loading of real options data
- readonly filters = {
+ filters = {
clusters: {
label: 'filter.clusters',
options: [
{
label: 'filter.all',
- value: 'ALL'
+ value: ''
},
{
- label: 'c0',
- value: 'c0'
+ label: 'cl0',
+ value: 'cl0'
},
{
- label: 'c1',
- value: 'c1'
+ label: 'cl1',
+ value: 'cl1'
+ },
+ {
+ label: 'cl2',
+ value: 'cl2'
+ },
+ {
+ label: 'cl3',
+ value: 'cl3'
+ },
+ {
+ label: 'cl4',
+ value: 'cl4'
}
],
selectedValue: '',
- selectedLabel: ''
+ selectedLabel: '',
+ paramName: 'clusters',
},
text: {
label: 'filter.message',
- value: ''
+ selectedValue: ''
},
timeRange: {
options: [
{
label: 'filter.timeRange.1hr',
- value: '1HR'
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 1
+ }
},
{
label: 'filter.timeRange.24hr',
- value: '24HR'
+ value: {
+ type: 'LAST',
+ unit: 'h',
+ interval: 24
+ }
},
{
label: 'filter.timeRange.today',
- value: 'TODAY'
+ value: {
+ type: 'CURRENT',
+ unit: 'd'
+ }
},
{
label: 'filter.timeRange.yesterday',
- value: 'YESTERDAY'
+ value: {
+ type: 'PAST',
+ unit: 'd'
+ }
},
{
label: 'filter.timeRange.7d',
- value: '7D'
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 7
+ }
},
{
label: 'filter.timeRange.30d',
- value: '30d'
+ value: {
+ type: 'LAST',
+ unit: 'd',
+ interval: 30
+ }
},
{
label: 'filter.timeRange.thisMonth',
- value: 'THIS_MONTH'
+ value: {
+ type: 'CURRENT',
+ unit: 'M'
+ }
},
{
label: 'filter.timeRange.lastMonth',
- value: 'LAST_MONTH'
+ value: {
+ type: 'PAST',
+ unit: 'M'
+ }
},
{
label: 'filter.timeRange.custom',
- value: 'CUSTOM'
+ value: {
+ type: 'CUSTOM'
+ }
}
],
selectedValue: '',
@@ -94,8 +138,9 @@ export class FilteringService {
},
timeZone: {
options: moment.tz.names().map(zone => {
+ // TODO map labels according to actual design requirements
return {
- label: zone,
+ label: `${zone} (${moment.tz(zone).format('Z')})`,
value: zone
};
}),
@@ -107,20 +152,24 @@ export class FilteringService {
iconClass: 'fa fa-cubes',
options: [
{
- label: 'DataNode',
- value: 'DATANODE'
+ label: 'filter.all',
+ value: ''
+ },
+ {
+ label: 'ambari_agent',
+ value: 'ambari_agent'
},
{
- label: 'NameNode',
- value: 'NAMENODE'
+ label: 'ams_collector',
+ value: 'ams_collector'
},
{
- label: 'ZooKeeper Server',
- value: 'ZOOKEEPER_SERVER'
+ label: 'zookeeper_server',
+ value: 'zookeeper_server'
},
{
- label: 'Metrics Collector',
- value: 'METRICS_COLLECTOR'
+ label: 'zookeeper_client',
+ value: 'zookeeper_client'
}
],
selectedValue: '',
@@ -131,6 +180,10 @@ export class FilteringService {
iconClass: 'fa fa-sort-amount-asc',
options: [
{
+ label: 'filter.all',
+ value: ''
+ },
+ {
label: 'levels.fatal',
value: 'FATAL'
},
@@ -164,4 +217,52 @@ export class FilteringService {
}
};
+ readonly valueGetters = {
+ end_time: value => {
+ let time;
+ if (value) {
+ switch (value.type) {
+ case 'LAST':
+ time = moment();
+ break;
+ case 'CURRENT':
+ // TODO consider user's timezone
+ time = moment().endOf(value.unit);
+ break;
+ case 'PAST':
+ // TODO consider user's timezone
+ time = moment().startOf(value.unit).millisecond(-1);
+ break;
+ default:
+ break;
+ }
+ }
+ return time ? time.toISOString() : '';
+ },
+ start_time: (value, current) => {
+ let time;
+ if (value) {
+ const endTime = moment(moment(current).valueOf());
+ switch (value.type) {
+ case 'LAST':
+ time = endTime.subtract(value.interval, value.unit);
+ break;
+ case 'CURRENT':
+ // TODO consider user's timezone
+ time = moment().startOf(value.unit);
+ break;
+ case 'PAST':
+ // TODO consider user's timezone
+ time = endTime.startOf(value.unit);
+ break;
+ default:
+ break;
+ }
+ }
+ return time ? time.toISOString() : '';
+ }
+ };
+
+ filteringSubject = new Subject();
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/services/http-client.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/http-client.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/http-client.service.ts
index 84f82b3..cef6696 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/http-client.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/http-client.service.ts
@@ -21,6 +21,8 @@ import {Observable} from 'rxjs/Observable';
import {Http, XHRBackend, Request, RequestOptions, RequestOptionsArgs, Response} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
+import {AuditLogsQueryParams} from '@app/classes/queries/audit-logs-query-params.class';
+import {ServiceLogsQueryParams} from '@app/classes/queries/service-logs-query-params.class';
@Injectable()
export class HttpClientService extends Http {
@@ -31,9 +33,18 @@ export class HttpClientService extends Http {
private readonly apiPrefix = 'api/v1/';
- private readonly urls = {
- status: 'status',
- auditLogs: 'audit/logs'
+ private readonly endPoints = {
+ status: {
+ url: 'status'
+ },
+ auditLogs: {
+ url: 'audit/logs',
+ params: opts => new AuditLogsQueryParams(opts)
+ },
+ serviceLogs: {
+ url: 'service/logs',
+ params: opts => new ServiceLogsQueryParams(opts)
+ }
};
private readonly unauthorizedStatuses = [401, 403, 419];
@@ -41,21 +52,28 @@ export class HttpClientService extends Http {
isAuthorized: boolean;
generateUrlString(url: string): string {
- const presetUrl = this.urls[url];
- return presetUrl ? (this.apiPrefix + this.urls[url]) : url;
+ const preset = this.endPoints[url];
+ return preset ? `${this.apiPrefix}${preset.url}` : url;
}
- generateUrl(url: string | Request): string | Request {
- if (typeof url === 'string') {
- return this.generateUrlString(url);
+ generateUrl(request: string | Request): string | Request {
+ if (typeof request === 'string') {
+ return this.generateUrlString(request);
}
- if (url instanceof Request) {
- url.url = this.generateUrlString(url.url);
- return url;
+ if (request instanceof Request) {
+ request.url = this.generateUrlString(request.url);
+ return request;
}
}
- handleError(request: Observable<Response>) {
+ generateOptions(url: string, params: {[key: string]: string}): RequestOptionsArgs {
+ const preset = this.endPoints[url];
+ return {
+ params: preset && preset.params ? preset.params(params) : params
+ };
+ }
+
+ handleError(request: Observable<Response>): void {
request.subscribe(null, (error: any) => {
if (this.unauthorizedStatuses.indexOf(error.status) > -1) {
this.isAuthorized = false;
@@ -63,38 +81,14 @@ export class HttpClientService extends Http {
});
}
- request(url: string | Request, options?: RequestOptionsArgs):Observable<Response> {
+ request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let req = super.request(this.generateUrl(url), options);
this.handleError(req);
return req;
}
- get(url: string, options?: RequestOptionsArgs):Observable<Response> {
- return super.get(this.generateUrlString(url), options);
- }
-
- post(url: string, body: any, options?: RequestOptionsArgs):Observable<Response> {
- return super.post(this.generateUrlString(url), body, options);
- }
-
- put(url: string, body: any, options?: RequestOptionsArgs):Observable<Response> {
- return super.put(this.generateUrlString(url), body, options);
- }
-
- delete(url: string, options?: RequestOptionsArgs):Observable<Response> {
- return super.delete(this.generateUrlString(url), options);
- }
-
- patch(url: string, body: any, options?: RequestOptionsArgs):Observable<Response> {
- return super.patch(this.generateUrlString(url), body, options);
- }
-
- head(url: string, options?: RequestOptionsArgs):Observable<Response> {
- return super.head(this.generateUrlString(url), options);
- }
-
- options(url: string, options?: RequestOptionsArgs):Observable<Response> {
- return super.options(this.generateUrlString(url), options);
+ get(url, params?: {[key: string]: string}): Observable<Response> {
+ return super.get(this.generateUrlString(url), this.generateOptions(url, params));
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/services/mock-api-data.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/mock-api-data.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/mock-api-data.service.ts
index a6215e6..757f68d 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/mock-api-data.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/mock-api-data.service.ts
@@ -20,6 +20,8 @@ import {URLSearchParams, Response, ResponseOptions} from '@angular/http';
import {InMemoryDbService, InMemoryBackendService, createErrorResponse} from 'angular-in-memory-web-api';
import {Observable} from 'rxjs/Observable';
import {Subscriber} from 'rxjs/Subscriber';
+import * as moment from 'moment';
+import {mockData} from '../../assets/mock-data';
export class mockBackendService extends InMemoryBackendService {
getLocation(url: string): any {
@@ -29,6 +31,35 @@ export class mockBackendService extends InMemoryBackendService {
export class mockApiDataService implements InMemoryDbService {
+ private readonly filterMap = {
+ 'api/v1/service/logs': {
+ pathToCollection: 'logList',
+ filters: {
+ clusters: {
+ key: 'cluster'
+ },
+ component_name: {
+ key: 'type'
+ },
+ level: {
+ key: 'level'
+ },
+ iMessage: {
+ key: 'log_message',
+ filterFunction: (value, filterValue) => value.toLowerCase().indexOf(filterValue.toLowerCase()) > -1
+ },
+ start_time: {
+ key: 'logtime',
+ filterFunction: (value, filterValue) => value >= moment(filterValue).valueOf()
+ },
+ end_time: {
+ key: 'logtime',
+ filterFunction: (value, filterValue) => value < moment(filterValue).valueOf()
+ }
+ }
+ }
+ };
+
parseUrl(url: string): any {
const urlLocation = mockBackendService.prototype.getLocation(url),
query = urlLocation.search && new URLSearchParams(urlLocation.search.substr(1)),
@@ -51,7 +82,7 @@ export class mockApiDataService implements InMemoryDbService {
return interceptorArgs.passThruBackend.createConnection(interceptorArgs.requestInfo.req).response;
} else {
let is404 = false;
- const data = pathArray.reduce((currentObject, currentKey, index, array) => {
+ const allData = pathArray.reduce((currentObject, currentKey, index, array) => {
if (!currentObject && index < array.length - 1) {
return {};
} else if (currentObject.hasOwnProperty(currentKey)) {
@@ -66,9 +97,31 @@ export class mockApiDataService implements InMemoryDbService {
interceptorArgs.requestInfo.req, 404, 'Not found'
))));
} else {
+ let filteredData;
+ const filterMapItem = this.filterMap[path];
+ if (query && filterMapItem) {
+ filteredData = {};
+ const collection = allData[filterMapItem.pathToCollection],
+ filteredCollection = collection.filter(item => {
+ let result = true;
+ query.paramsMap.forEach((value, key) => {
+ const paramValue = value[0], // TODO implement multiple conditions
+ paramFilter = filterMapItem.filters[key];
+ if (paramFilter &&
+ ((paramFilter.filterFunction && !paramFilter.filterFunction(item[paramFilter.key], paramValue)) ||
+ (!paramFilter.filterFunction && item[paramFilter.key] !== paramValue))) {
+ result = false;
+ }
+ });
+ return result;
+ });
+ filteredData[filterMapItem.pathToCollection] = filteredCollection;
+ } else {
+ filteredData = allData;
+ }
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.next(new Response(new ResponseOptions({
status: 200,
- body: data
+ body: filteredData
}))));
}
}
@@ -80,750 +133,6 @@ export class mockApiDataService implements InMemoryDbService {
}
createDb() {
- return {
- login: {},
- api: {
- v1: {
- audit: {
- logs: {
- logList: [
- {
- policy: 'policy',
- reason: 'Authentication required',
- result: 0,
- text: 'Please log in',
- tags: [
- 'ambari_agent'
- ],
- resource: '/ambari-agent',
- sess: '0',
- access: '0',
- logType: 'AmbariAudit',
- tags_str: 'ambari_agent',
- resType: 'agent',
- reqUser: 'admin',
- reqData: 'data',
- repoType: 1,
- repo: 'ambari',
- proxyUsers: [
- 'admin'
- ],
- evtTime: '2017-05-29T11:30:22.531Z',
- enforcer: 'ambari-acl',
- reqContext: 'ambari',
- cliType: 'GET',
- cliIP: '192.168.0.1',
- agent: 'agent',
- agentHost: 'localhost',
- action: 'SERVICE_CHECK',
- type: 'ambari-audit',
- _version_: 2,
- id: 'id0',
- file: 'ambari-agent.log',
- seq_num: 3,
- bundle_id: 'b0',
- case_id: 'c0',
- log_message: 'User(admin), Operation(SERVICE_CHECK)',
- logfile_line_number: 4,
- message_md5: '12345678900987654321',
- cluster: 'cl0',
- event_count: 0,
- event_md5: '09876543211234567890',
- event_dur_ms: 100,
- _ttl_: "+7DAYS",
- _expire_at_: '2017-05-29T11:30:22.531Z',
- _router_field_: 5
- },
- {
- policy: 'policy',
- reason: 'Server error',
- result: 1,
- text: 'Something went wrong',
- tags: [
- 'ambari_agent'
- ],
- resource: '/ambari-agent',
- sess: '1',
- access: '1',
- logType: 'AmbariAudit',
- tags_str: 'ambari_server',
- resType: 'server',
- reqUser: 'user',
- reqData: 'data',
- repoType: 1,
- repo: 'ambari',
- proxyUsers: [
- 'user'
- ],
- evtTime: '2017-05-29T11:30:22.531Z',
- enforcer: 'hdfs',
- reqContext: 'ambari_server',
- cliType: 'PUT',
- cliIP: '192.168.0.1',
- agent: 'agent',
- agentHost: 'localhost',
- action: 'SERVICE_CHECK',
- type: 'ambari-audit',
- _version_: 4,
- id: 'id1',
- file: 'ambari-agent.log',
- seq_num: 5,
- bundle_id: 'b1',
- case_id: 'c1',
- log_message: 'User(user), Operation(SERVICE_CHECK)',
- logfile_line_number: 6,
- message_md5: '10293847561029384756',
- cluster: 'cl1',
- event_count: 2,
- event_md5: '01928374650192837465',
- event_dur_ms: 500,
- _ttl_: "+7DAYS",
- _expire_at_: '2017-05-29T11:30:22.531Z',
- _router_field_: 10
- }
- ],
- bargraph: {
- graphData: [
- {
- dataCount: [
- {
- name: 'n0',
- value: 1
- },
- {
- name: 'n1',
- value: 2
- }
- ],
- name: 'graph0'
- },
- {
- dataCount: [
- {
- name: 'n2',
- value: 10
- },
- {
- name: 'n3',
- value: 20
- }
- ],
- name: 'graph1'
- }
- ]
- },
- components: {},
- resources: {
- graphData: [
- {
- dataCount: [
- {
- name: 'n16',
- value: 800
- },
- {
- name: 'n17',
- value: 400
- }
- ],
- name: 'graph8'
- },
- {
- dataCount: [
- {
- name: 'n18',
- value: 600
- },
- {
- name: 'n19',
- value: 300
- }
- ],
- name: 'graph9'
- }
- ]
- },
- schema: {
- fields: ''
- },
- serviceload: {
- graphData: [
- {
- dataCount: [
- {
- name: 'n4',
- value: 1
- },
- {
- name: 'n5',
- value: 2
- }
- ],
- name: 'graph2'
- },
- {
- dataCount: [
- {
- name: 'n6',
- value: 10
- },
- {
- name: 'n7',
- value: 20
- }
- ],
- name: 'graph3'
- }
- ]
- }
- }
- },
- public: {
- config: {}
- },
- service: {
- logs: {
- logList: [
- {
- path: '/var/log/ambari-metrics-collector/ambari-metrics-collector.log',
- host: 'h0',
- level: 'WARN',
- logtime: '2017-05-28T11:30:22.531Z',
- ip: '192.168.0.1',
- logfile_line_number: 8,
- type: 'ams_collector',
- _version_: 9,
- id: 'id2',
- file: 'ambari-metrics-collector.log',
- seq_num: 10,
- bundle_id: 'b2',
- case_id: 'c2',
- log_message: 'Connection refused',
- message_md5: '1357908642',
- cluster: 'cl2',
- event_count: 5,
- event_md5: '1908755391',
- event_dur_ms: 200,
- _ttl_: "+5DAYS",
- _expire_at_: '2017-05-29T11:30:22.531Z',
- _router_field_: 20
- },
- {
- path: '/var/log/ambari-metrics-collector/ambari-metrics-collector.log',
- host: 'h1',
- level: 'ERROR',
- logtime: '2017-05-28T10:30:22.531Z',
- ip: '192.168.0.2',
- type: 'ams_collector',
- _version_: 14,
- id: 'id3',
- file: 'ambari-metrics-collector.log',
- seq_num: 15,
- bundle_id: 'b3',
- case_id: 'c3',
- log_message: 'Connection refused',
- logfile_line_number: 16,
- message_md5: '1357908642',
- cluster: 'cl3',
- event_count: 2,
- event_md5: '1029384756',
- event_dur_ms: 700,
- _ttl_: "+5DAYS",
- _expire_at_: '2017-05-29T10:30:22.531Z',
- _router_field_: 5
- }
- ],
- aggregated: {
- graphData: [
- {
- name: 'n0',
- count: 100,
- dataList: [
- {
- name: 'n1',
- count: 50,
- dataList: null
- },
- {
- name: 'n2',
- count: 200,
- dataList: null
- }
- ]
- },
- {
- name: 'n3',
- count: 10,
- dataList: [
- {
- name: 'n4',
- count: 5,
- dataList: null
- },
- {
- name: 'n5',
- count: 20,
- dataList: null
- }
- ]
- }
- ]
- },
- components: {
- count: {
- anygraph: {
- graphData: [
- {
- dataCount: [
- {
- name: 'n8',
- value: 50
- },
- {
- name: 'n9',
- value: 100
- }
- ],
- name: 'graph4'
- },
- {
- dataCount: [
- {
- name: 'n10',
- value: 5
- },
- {
- name: 'n11',
- value: 10
- }
- ],
- name: 'graph5'
- }
- ]
- }
- },
- levels: {
- counts: {
- vNodeList: [
- {
- name: 'ambari',
- type: 0,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '10'
- },
- {
- name: 'WARN',
- value: '50'
- }
- ],
- childs: [
- {
- name: 'hdfs',
- type: 2,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '10'
- },
- {
- name: 'WARN',
- value: '20'
- }
- ],
- isParent: false,
- isRoot: false
- },
- {
- name: 'zookeeper',
- type: 3,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '20'
- },
- {
- name: 'WARN',
- value: '40'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ],
- isParent: true,
- isRoot: false
- },
- {
- name: 'ambari_agent',
- type: 1,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '100'
- },
- {
- name: 'WARN',
- value: '500'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ]
- }
- }
- },
- files: {
- hostLogFiles: {
- clusters: [
- 'c0',
- 'c1'
- ],
- services: [
- 'hdfs',
- 'zookeeper'
- ]
- }
- },
- histogram: {
- graphData: [
- {
- dataCount: [
- {
- name: 'n12',
- value: 1000
- },
- {
- name: 'n13',
- value: 2000
- }
- ],
- name: 'graph6'
- },
- {
- dataCount: [
- {
- name: 'n14',
- value: 700
- },
- {
- name: 'n15',
- value: 900
- }
- ],
- name: 'graph7'
- }
- ]
- },
- hosts: {
- components: {
- vNodeList: [
- {
- name: 'ambari',
- type: 0,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '100'
- },
- {
- name: 'WARN',
- value: '500'
- }
- ],
- childs: [
- {
- name: 'ambari_metrics',
- type: 2,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '100'
- },
- {
- name: 'WARN',
- value: '200'
- }
- ],
- isParent: false,
- isRoot: false
- },
- {
- name: 'hbase',
- type: 3,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '200'
- },
- {
- name: 'WARN',
- value: '400'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ],
- isParent: true,
- isRoot: false
- },
- {
- name: 'ambari_server',
- type: 1,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '1000'
- },
- {
- name: 'WARN',
- value: '5000'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ]
- },
- count: {
- getvCounts: [
- {
- name: 'n20',
- count: 100
- },
- {
- name: 'n21',
- count: 200
- }
- ]
- }
- },
- levels: {
- counts: {
- getvNameValues: [
- {
- name: 'n22',
- count: 1000
- },
- {
- name: 'n23',
- count: 2000
- }
- ]
- }
- },
- schema: {
- fields: ''
- },
- serviceconfig: '',
- tree: {
- vNodeList: [
- {
- name: 'ambari',
- type: 0,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '1000'
- },
- {
- name: 'WARN',
- value: '5000'
- }
- ],
- childs: [
- {
- name: 'yarn',
- type: 2,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '1000'
- },
- {
- name: 'WARN',
- value: '2000'
- }
- ],
- isParent: false,
- isRoot: false
- },
- {
- name: 'hive',
- type: 3,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '2000'
- },
- {
- name: 'WARN',
- value: '4000'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ],
- isParent: true,
- isRoot: false
- },
- {
- name: 'ambari_server',
- type: 1,
- logLevelCount: [
- {
- name: 'ERROR',
- value: '10000'
- },
- {
- name: 'WARN',
- value: '50000'
- }
- ],
- isParent: false,
- isRoot: false
- }
- ]
- },
- truncated: {
- logList: [
- {
- path: '/var/log/ambari-metrics-collector/ambari-metrics-collector.log',
- host: 'h0',
- level: 'WARN',
- logtime: '2017-05-28T11:30:22.531Z',
- ip: '192.168.0.1',
- logfile_line_number: 8,
- type: 'ams_collector',
- _version_: 9,
- id: 'id2',
- file: 'ambari-metrics-collector.log',
- seq_num: 10,
- bundle_id: 'b2',
- case_id: 'c2',
- log_message: 'Connection refused',
- message_md5: '1357908642',
- cluster: 'cl2',
- event_count: 5,
- event_md5: '1908755391',
- event_dur_ms: 200,
- _ttl_: "+5DAYS",
- _expire_at_: '2017-05-29T11:30:22.531Z',
- _router_field_: 20
- },
- {
- path: '/var/log/ambari-metrics-collector/ambari-metrics-collector.log',
- host: 'h1',
- level: 'ERROR',
- logtime: '2017-05-28T10:30:22.531Z',
- ip: '192.168.0.2',
- type: 'ams_collector',
- _version_: 14,
- id: 'id3',
- file: 'ambari-metrics-collector.log',
- seq_num: 15,
- bundle_id: 'b3',
- case_id: 'c3',
- log_message: 'Connection refused',
- logfile_line_number: 16,
- message_md5: '1357908642',
- cluster: 'cl3',
- event_count: 2,
- event_md5: '1029384756',
- event_dur_ms: 700,
- _ttl_: "+5DAYS",
- _expire_at_: '2017-05-29T10:30:22.531Z',
- _router_field_: 5
- }
- ]
- }
- }
- },
- status: {
- auditlogs: {
- znodeReady: true,
- solrCollectionReady: true,
- solrAliasReady: false,
- configurationUploaded: true
- },
- servicelogs: {
- znodeReady: true,
- solrCollectionReady: true,
- configurationUploaded: true
- },
- userconfig: {
- znodeReady: true,
- solrCollectionReady: true,
- configurationUploaded: true
- }
- },
- userconfig: {
- userConfigList: [
- {
- id: 'c0',
- userName: 'admin',
- filtername: 'service',
- values: 'hdfs',
- shareNameList: [
- 's0',
- 's1'
- ],
- rowType: 'history'
- },
- {
- id: 'c0',
- userName: 'user',
- filtername: 'component',
- values: 'namenode',
- shareNameList: [
- 's2',
- 's3'
- ],
- rowType: 'history'
- }
- ],
- filters: {
- filter0: {
- label: 'filter0',
- hosts: [
- 'h0',
- 'h1'
- ],
- defaultLevels: [
- 'l0',
- 'l1'
- ],
- overrideLevels: [
- 'l2',
- 'l3'
- ],
- expiryTime: '2017-05-29T11:30:22.531Z'
- },
- filter1: {
- label: 'filter1',
- hosts: [
- 'h1',
- 'h2'
- ],
- defaultLevels: [
- 'l4',
- 'l5'
- ],
- overrideLevels: [
- 'l6',
- 'l7'
- ],
- expiryTime: '2017-05-30T11:30:22.531Z'
- }
- },
- names: []
- }
- }
- }
- };
+ return mockData;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1a2d6ced/ambari-logsearch/ambari-logsearch-web-new/src/app/variables.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/variables.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/variables.less
index a8c71d1..9a8ea09 100644
--- a/ambari-logsearch/ambari-logsearch-web-new/src/app/variables.less
+++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/variables.less
@@ -26,8 +26,10 @@
@block-margin-top: 20px;
@link-color: #1491C1;
@link-hover-color: #23527C;
+@grey-color: #666;
+@default-line-height: 1.42857143;
+@main-background-color: #ECECEC;
-// TODO implement actual colors
@fatal-color: #830A0A;
@error-color: #E81D1D;
@warning-color: #FF8916;
@@ -36,9 +38,6 @@
@trace-color: #888;
@unknown-color: #BDBDBD;
-@grey-color: #666;
-@default-line-height: 1.42857143;
-
// Mixins
.flex-vertical-align {
display: flex;