AMBARI-21726 Log Search UI: columns set for logs list should be customized by user. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f4bb14c1 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f4bb14c1 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f4bb14c1 Branch: refs/heads/branch-feature-logsearch-ui Commit: f4bb14c19cc943c7a46dc5cc336851cc54d9592c Parents: f50c17b Author: ababiichuk <[email protected]> Authored: Tue Aug 15 17:21:49 2017 +0300 Committer: ababiichuk <[email protected]> Committed: Tue Aug 15 17:21:49 2017 +0300 ---------------------------------------------------------------------- .../src/app/app.module.ts | 4 + .../dropdown-button.component.html | 2 +- .../dropdown-button.component.less | 2 + .../dropdown-button.component.ts | 8 +- .../filter-dropdown.component.less | 22 -- .../filter-dropdown.component.ts | 2 +- .../logs-container.component.html | 5 +- .../logs-container.component.spec.ts | 10 + .../logs-container/logs-container.component.ts | 65 +++++- .../logs-list/logs-list.component.html | 25 ++- .../logs-list/logs-list.component.less | 9 +- .../components/logs-list/logs-list.component.ts | 9 + .../main-container.component.html | 2 +- .../main-container.component.spec.ts | 8 +- .../main-container/main-container.component.ts | 27 ++- .../pagination-controls.component.less | 1 + .../src/app/mock-data.ts | 122 ++++++++-- .../src/app/models/audit-log-field.model.ts | 225 +++++++++++++++++++ .../src/app/models/log-field.model.ts | 27 +++ .../src/app/models/service-log-field.model.ts | 107 +++++++++ .../src/app/models/store.model.ts | 28 ++- .../app/services/component-actions.service.ts | 5 + .../src/app/services/http-client.service.ts | 6 + .../storage/audit-logs-fields.service.ts | 32 +++ .../app/services/storage/reducers.service.ts | 8 +- .../storage/service-logs-fields.service.ts | 32 +++ .../src/assets/i18n/en.json | 68 +++++- 27 files changed, 790 insertions(+), 71 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/app.module.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/app.module.ts index f81e75b..775ac55 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/app.module.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/app.module.ts @@ -45,6 +45,8 @@ import {UserConfigsService} from '@app/services/storage/user-configs.service'; import {FiltersService} from '@app/services/storage/filters.service'; import {ClustersService} from '@app/services/storage/clusters.service'; import {ComponentsService} from '@app/services/storage/components.service'; +import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-fields.service'; +import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service'; import {reducer} from '@app/services/storage/reducers.service'; import {AppComponent} from '@app/components/app.component'; @@ -138,6 +140,8 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR FiltersService, ClustersService, ComponentsService, + ServiceLogsFieldsService, + AuditLogsFieldsService, { provide: XHRBackend, useFactory: getXHRBackend, http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.html index bd0d528..b777b52 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.html +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.html @@ -18,7 +18,7 @@ <div class="filter-label" *ngIf="label">{{label | translate}}</div> <div [ngClass]="{'dropup': isDropup}"> <button class="btn btn-link dropdown-toggle" data-toggle="dropdown"> - {{selectedLabel | translate}} <span class="caret"></span> + <span *ngIf="!isMultipleChoice">{{selectedLabel | translate}}</span> <span class="caret"></span> </button> <ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}" [items]="options" (selectedItemChange)="updateValue($event)"></ul> http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.less index a60246c..55699b4 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.less +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.less @@ -18,7 +18,9 @@ @import '../variables'; :host { + .default-flex; position: relative; + float: left; .filter-label { padding: @input-group-addon-padding; http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.ts index 3aecd9e..029d87b 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/dropdown-button/dropdown-button.component.ts @@ -50,6 +50,12 @@ export class DropdownButtonComponent implements OnInit { action?: string; @Input() + additionalArgs?: any[] = []; + + @Input() + isMultipleChoice?: boolean = false; + + @Input() isRightAlign?: boolean = false; @Input() @@ -73,7 +79,7 @@ export class DropdownButtonComponent implements OnInit { this.value = value; this.selectedLabel = options.label; if (this.action) { - this.actions[this.action](value); + this.actions[this.action](value, ...this.additionalArgs); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.less deleted file mode 100644 index e5e85f4..0000000 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.less +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 '../variables'; - -:host { - .default-flex; -} http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.ts index 8352ff1..c414782 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/filter-dropdown/filter-dropdown.component.ts @@ -24,7 +24,7 @@ import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown- @Component({ selector: 'filter-dropdown', templateUrl: '../dropdown-button/dropdown-button.component.html', - styleUrls: ['../dropdown-button/dropdown-button.component.less', './filter-dropdown.component.less'], + styleUrls: ['../dropdown-button/dropdown-button.component.less'], providers: [ { provide: NG_VALUE_ACCESSOR, http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.html index a7dabe8..2e642be 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.html +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.html @@ -16,4 +16,7 @@ --> <time-histogram class="col-md-12" [data]="histogramData" [customOptions]="histogramOptions"></time-histogram> -<logs-list [logs]="logs | async" [totalCount]="totalCount"></logs-list> +<dropdown-button class="pull-right" label="logs.columns" [options]="availableColumns | async" isRightAlign="true" + isMultipleChoice="true" action="updateSelectedColumns" + [additionalArgs]="this[this.logsTypeMapObject.fieldsModel]"></dropdown-button> +<logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"></logs-list> http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.spec.ts index 7792fa9..4d6509b 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.spec.ts @@ -22,7 +22,10 @@ import {StoreModule} from '@ngrx/store'; import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service'; import {ClustersService, clusters} from '@app/services/storage/clusters.service'; import {ComponentsService, components} from '@app/services/storage/components.service'; +import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service'; +import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service'; import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service'; +import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service'; import {HttpClientService} from '@app/services/http-client.service'; import {FilteringService} from '@app/services/filtering.service'; @@ -50,7 +53,10 @@ describe('LogsContainerComponent', () => { appSettings, clusters, components, + auditLogs, + auditLogsFields, serviceLogs, + serviceLogsFields, serviceLogsHistogramData }) ], @@ -62,7 +68,10 @@ describe('LogsContainerComponent', () => { AppSettingsService, ClustersService, ComponentsService, + AuditLogsService, + AuditLogsFieldsService, ServiceLogsService, + ServiceLogsFieldsService, ServiceLogsHistogramDataService, FilteringService, UtilsService @@ -75,6 +84,7 @@ describe('LogsContainerComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(LogsContainerComponent); component = fixture.componentInstance; + component.logsType = 'serviceLogs'; fixture.detectChanges(); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.ts index 5823846..40e7d89 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-container/logs-container.component.ts @@ -18,11 +18,18 @@ import {Component, OnInit, Input} from '@angular/core'; import {FormGroup} from '@angular/forms'; +import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import {HttpClientService} from '@app/services/http-client.service'; import {FilteringService} from '@app/services/filtering.service'; +import {AuditLogsService} from '@app/services/storage/audit-logs.service'; +import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service'; import {ServiceLogsService} from '@app/services/storage/service-logs.service'; +import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-fields.service'; import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service'; +import {AuditLog} from '@app/models/audit-log.model'; +import {ServiceLog} from '@app/models/service-log.model'; +import {LogField} from '@app/models/log-field.model'; @Component({ selector: 'logs-container', @@ -31,7 +38,7 @@ import {ServiceLogsHistogramDataService} from '@app/services/storage/service-log }) export class LogsContainerComponent implements OnInit { - constructor(private httpClient: HttpClientService, private serviceLogsStorage: ServiceLogsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private filtering: FilteringService) { + constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private filtering: FilteringService) { this.serviceLogsHistogramStorage.getAll().subscribe(data => { let histogramData = {}; data.forEach(type => { @@ -51,6 +58,31 @@ export class LogsContainerComponent implements OnInit { } ngOnInit() { + this.logsTypeMapObject = this.logsTypeMap[this.logsType]; + this.availableColumns = this[this.logsTypeMapObject.fieldsModel].getAll().map(fields => { + const availableFields = fields.filter(field => field.isAvailable), + availableNames = availableFields.map(field => field.name); + if (availableNames.length) { + this.logs = this[this.logsTypeMapObject.logsModel].getAll().map(logs => logs.map(log => { + let logObject = availableNames.reduce((obj, key) => Object.assign(obj, { + [key]: log[key] + }), {}); + if (logObject.level) { + logObject.className = logObject.level.toLowerCase(); + } + return logObject; + })); + } + return availableFields.map(field => { + return { + value: field.name, + label: field.displayName || field.name + }; + }); + }); + this[this.logsTypeMapObject.fieldsModel].getAll().subscribe(columns => { + this.displayedColumns = columns.filter(column => column.isAvailable && column.isDisplayed); + }); this.loadLogs(); this.filtersForm.valueChanges.subscribe(() => { this.loadLogs(); @@ -58,7 +90,9 @@ export class LogsContainerComponent implements OnInit { } @Input() - private logsArrayId: string; + private logsType: string; + + logsTypeMapObject: any; totalCount: number = 0; @@ -77,15 +111,22 @@ export class LogsContainerComponent implements OnInit { timeRange: ['to', 'from'] }; - logs = this.serviceLogsStorage.getAll().map(logs => logs.map(log => { - return { - type: log.type, - level: log.level, - className: log.level.toLowerCase(), - message: log.log_message, - time: log.logtime - }; - })); + private readonly logsTypeMap = { + auditLogs: { + logsModel: 'auditLogsStorage', + fieldsModel: 'auditLogsFieldsStorage' + }, + serviceLogs: { + logsModel: 'serviceLogsStorage', + fieldsModel: 'serviceLogsFieldsStorage' + } + }; + + logs: Observable<AuditLog[] | ServiceLog[]>; + + availableColumns: Observable<LogField[]>; + + displayedColumns: any[] = []; histogramData: any; @@ -106,7 +147,7 @@ export class LogsContainerComponent implements OnInit { } private loadLogs(): void { - this.httpClient.get(this.logsArrayId, this.getParams('listFilters')).subscribe(response => { + this.httpClient.get(this.logsType, this.getParams('listFilters')).subscribe(response => { const jsonResponse = response.json(); this.serviceLogsStorage.clear(); if (jsonResponse) { http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.html index e9b3c67..caae24e 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.html +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.html @@ -15,11 +15,11 @@ limitations under the License. --> -<form *ngIf="logs.length" [formGroup]="filtersForm" class="pull-right"> +<form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="pull-right"> <filter-dropdown [label]="filters.sorting.label" formControlName="sorting" [options]="filters.sorting.options" [defaultLabel]="filters.sorting.defaultLabel" isRightAlign="true"></filter-dropdown> </form> -<div class="col-md-12 text-center" *ngIf="logs.length"> +<div class="col-md-12 text-center" *ngIf="logs && logs.length"> <div class="logs-header"> <div class="col-md-1">{{'logs.status' | translate}}</div> <div class="col-md-11">{{'logs.details' | translate}}</div> @@ -27,11 +27,13 @@ </div> <accordion-panel *ngFor="let log of logs; let i = index" [toggleId]="'details-' + i" class="col-md-12"> <ng-template> - <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 | amTz: timeZone | amDateFormat: timeFormat}}</time> + <div *ngIf="isColumnDisplayed('level')" [ngClass]="'hexagon ' + log.className"></div> + <div *ngIf="isColumnDisplayed('level')" [ngClass]="'col-md-1 log-status ' + log.className">{{log.level}}</div> + <div *ngIf="isColumnDisplayed('type') || isColumnDisplayed('logtime')" class="col-md-3"> + <div *ngIf="isColumnDisplayed('type')" class="log-type">{{log.type}}</div> + <time *ngIf="isColumnDisplayed('logtime')" class="log-time"> + {{log.logtime | amTz: timeZone | amDateFormat: timeFormat}} + </time> </div> <div class="col-md-6 log-content-wrapper"> <div class="collapse log-actions" [attr.id]="'details-' + i"> @@ -39,9 +41,14 @@ <span class="action-icon fa fa-external-link"></span> <span class="action-icon fa fa-bullseye"></span> </div> - <div class="log-content">{{log.message}}</div> + <div class="log-content-inner-wrapper"> + <div class="log-content" *ngIf="isColumnDisplayed('log_message')">{{log.log_message}}</div> + </div> + </div> + <div *ngFor="let column of displayedColumns"> + <div *ngIf="customStyledColumns.indexOf(column.name) === -1" [innerHTML]="log[column.name]" class="col-md-1"></div> </div> </ng-template> </accordion-panel> -<pagination class="col-md-12" *ngIf="logs.length" [totalCount]="totalCount" [filtersForm]="filtersForm" +<pagination class="col-md-12" *ngIf="logs && logs.length" [totalCount]="totalCount" [filtersForm]="filtersForm" [filterInstance]="filters.pageSize" [currentCount]="logs.length"></pagination> http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.less index 63c0354..91d796f 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.less +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.less @@ -107,11 +107,14 @@ position: relative; // TODO get rid of magic numbers, base on actual design - .log-content { + .log-content-inner-wrapper { overflow: hidden; max-height: @default-line-height * 2em; padding-right: 65px; - white-space: pre-wrap; + + .log-content { + white-space: pre-wrap; + } } .log-actions { @@ -120,7 +123,7 @@ top: 0; border: @input-border; - &.collapsing + .log-content, &.collapse.in + .log-content { + &.collapsing + .log-content-inner-wrapper, &.collapse.in + .log-content-inner-wrapper { min-height: 6em; max-height: none; overflow-x: auto; http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.ts index 27b5021..6d73dcb 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/logs-list/logs-list.component.ts @@ -36,6 +36,11 @@ export class LogsListComponent { @Input() totalCount: number = 0; + @Input() + displayedColumns: any[] = []; + + readonly customStyledColumns = ['level', 'type', 'logtime', 'log_message']; + timeFormat: string = 'DD/MM/YYYY HH:mm:ss'; get timeZone(): string { @@ -50,4 +55,8 @@ export class LogsListComponent { return this.filtering.filtersForm; } + isColumnDisplayed(key: string): boolean { + return this.displayedColumns.some(column => column.name === key); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.html ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.html index f4cf47a..69b3887 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.html +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.html @@ -21,4 +21,4 @@ </div> <login-form *ngIf="!isInitialLoading && !isAuthorized"></login-form> <filters-panel *ngIf="isAuthorized" class="row"></filters-panel> -<logs-container *ngIf="isAuthorized" logsArrayId="serviceLogs"></logs-container> +<logs-container *ngIf="isAuthorized" logsType="serviceLogs"></logs-container> http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.spec.ts index fa8954c..42fba68 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.spec.ts @@ -21,6 +21,8 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {HttpModule} from '@angular/http'; import {StoreModule} from '@ngrx/store'; import {AppStateService, appState} from '@app/services/storage/app-state.service'; +import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service'; +import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; import {HttpClientService} from '@app/services/http-client.service'; import {MainContainerComponent} from './main-container.component'; @@ -35,12 +37,16 @@ describe('MainContainerComponent', () => { imports: [ HttpModule, StoreModule.provideStore({ - appState + appState, + auditLogsFields, + serviceLogsFields }) ], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [ AppStateService, + AuditLogsFieldsService, + ServiceLogsFieldsService, HttpClientService ] }) http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.ts index b0c3943..78df822 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/main-container/main-container.component.ts @@ -17,7 +17,12 @@ */ import {Component, ContentChild, TemplateRef} from '@angular/core'; +import {HttpClientService} from '@app/services/http-client.service'; import {AppStateService} from '@app/services/storage/app-state.service'; +import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service'; +import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-fields.service'; +import {AuditLogField} from '@app/models/audit-log-field.model'; +import {ServiceLogField} from '@app/models/service-log-field.model'; @Component({ selector: 'main-container', @@ -26,7 +31,8 @@ import {AppStateService} from '@app/services/storage/app-state.service'; }) export class MainContainerComponent { - constructor(private appState: AppStateService) { + constructor(private httpClient: HttpClientService, private appState: AppStateService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService) { + this.loadColumnsNames(); this.appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value); this.appState.getParameter('isInitialLoading').subscribe(value => this.isInitialLoading = value); } @@ -38,4 +44,23 @@ export class MainContainerComponent { isInitialLoading: boolean = false; + private loadColumnsNames(): void { + this.httpClient.get('serviceLogsFields').subscribe(response => { + const jsonResponse = response.json(); + if (jsonResponse) { + this.serviceLogsFieldsStorage.addInstances(this.getColumnsArray(jsonResponse, ServiceLogField)); + } + }); + this.httpClient.get('auditLogsFields').subscribe(response => { + const jsonResponse = response.json(); + if (jsonResponse) { + this.auditLogsFieldsStorage.addInstances(this.getColumnsArray(jsonResponse, AuditLogField)); + } + }); + } + + private getColumnsArray(keysObject: any, fieldClass: any): any[] { + return Object.keys(keysObject).map(key => new fieldClass(key)); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/components/pagination-controls/pagination-controls.component.less ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/pagination-controls/pagination-controls.component.less b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/pagination-controls/pagination-controls.component.less index c21e83e..8238eaf 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/components/pagination-controls/pagination-controls.component.less +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/components/pagination-controls/pagination-controls.component.less @@ -15,6 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + @import '../variables'; .pagination-control { http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/mock-data.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/mock-data.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/mock-data.ts index ecac362..1f738ae 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/mock-data.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/mock-data.ts @@ -68,7 +68,7 @@ export const mockData = { event_count: 0, event_md5: '09876543211234567890', event_dur_ms: 100, - _ttl_: "+7DAYS", + _ttl_: '+7DAYS', _expire_at_: '2017-05-29T11:30:22.531Z', _router_field_: 5 }, @@ -115,7 +115,7 @@ export const mockData = { event_count: 2, event_md5: '01928374650192837465', event_dur_ms: 500, - _ttl_: "+7DAYS", + _ttl_: '+7DAYS', _expire_at_: '2017-05-29T11:30:22.531Z', _router_field_: 10 } @@ -182,7 +182,79 @@ export const mockData = { ] }, schema: { - fields: '' + fields: { + 'cluster': 'key_lower_case', + 'ws_status': 'text_ws', + 'reason': 'text_std_token_lower_case', + 'agent': 'key_lower_case', + 'Base URL': 'key_lower_case', + 'sess': 'key_lower_case', + 'type': 'key_lower_case', + 'seq_num': 'tlong', + 'path': 'key_lower_case', + 'ugi': 'key_lower_case', + 'host': 'key_lower_case', + 'case_id': 'key_lower_case', + 'action': 'key_lower_case', + 'id': 'string', + 'logger_name': 'key_lower_case', + 'text': 'text_std_token_lower_case', + 'Repo id': 'key_lower_case', + 'Stack version': 'tdouble', + 'logfile_line_number': 'tint', + 'Status': 'tlong', + 'RequestId': 'tlong', + 'level': 'key_lower_case', + 'resource': 'key_lower_case', + 'resType': 'key_lower_case', + 'ip': 'key_lower_case', + 'Hostname': 'key_lower_case', + 'Roles': 'key_lower_case', + 'Stack': 'key_lower_case', + 'req_self_id': 'key_lower_case', + 'repoType': 'tint', + 'VersionNote': 'key_lower_case', + 'Cluster name': 'key_lower_case', + 'bundle_id': 'key_lower_case', + 'cliType': 'key_lower_case', + 'reqContext': 'key_lower_case', + 'ws_result_status': 'text_ws', + 'proxyUsers': 'key_lower_case', + 'RequestType': 'key_lower_case', + 'Repositories': 'key_lower_case', + 'logType': 'key_lower_case', + 'Repo version': 'key_lower_case', + 'TaskId': 'tlong', + 'User': 'key_lower_case', + 'access': 'key_lower_case', + 'dst': 'key_lower_case', + 'perm': 'key_lower_case', + 'event_count': 'tlong', + 'repo': 'key_lower_case', + 'reqUser': 'key_lower_case', + 'task_id': 'tlong', + 'Operation': 'key_lower_case', + 'Reason': 'key_lower_case', + 'reqData': 'text_std_token_lower_case', + 'result': 'tint', + 'file': 'key_lower_case', + 'log_message': 'key_lower_case', + 'agentHost': 'key_lower_case', + 'Component': 'key_lower_case', + 'authType': 'key_lower_case', + 'Display name': 'key_lower_case', + 'policy': 'tlong', + 'cliIP': 'key_lower_case', + 'OS': 'key_lower_case', + 'RemoteIp': 'key_lower_case', + 'ResultStatus': 'tlong', + 'evtTime': 'tdate', + 'VersionNumber': 'key_lower_case', + 'url': 'key_lower_case', + 'req_caller_id': 'key_lower_case', + 'enforcer': 'key_lower_case', + 'Command': 'key_lower_case' + } }, serviceload: { graphData: [ @@ -242,7 +314,7 @@ export const mockData = { event_count: 5, event_md5: '1908755391', event_dur_ms: 200, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().add(5, 'd').valueOf(), _router_field_: 20 }, @@ -266,7 +338,7 @@ export const mockData = { event_count: 2, event_md5: '1029384756', event_dur_ms: 700, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().add(3, 'd').valueOf(), _router_field_: 5 }, @@ -290,7 +362,7 @@ export const mockData = { event_count: 2, event_md5: '67589403', event_dur_ms: 100, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().subtract(5, 'd').valueOf(), _router_field_: 45 }, @@ -314,7 +386,7 @@ export const mockData = { event_count: 2, event_md5: '67589403', event_dur_ms: 1000, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().subtract(25, 'h').add(5, 'd').valueOf(), _router_field_: 55 }, @@ -338,7 +410,7 @@ export const mockData = { event_count: 2, event_md5: '67589403', event_dur_ms: 1000, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().subtract(20, 'd').valueOf(), _router_field_: 55 }, @@ -362,7 +434,7 @@ export const mockData = { event_count: 2, event_md5: '67589403', event_dur_ms: 1000, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().subtract(2, 'h').add(5, 'd').valueOf(), _router_field_: 55 }, @@ -386,7 +458,7 @@ export const mockData = { event_count: 2, event_md5: '67589403', event_dur_ms: 1000, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: moment().subtract(26, 'd').valueOf(), _router_field_: 55 } @@ -688,7 +760,31 @@ export const mockData = { } }, schema: { - fields: '' + fields: { + cluster: 'key_lower_case', + method: 'key_lower_case', + level: 'key_lower_case', + event_count: 'tlong', + ip: 'string', + rowtype: 'key_lower_case', + key_log_message: 'key_lower_case', + type: 'key_lower_case', + seq_num: 'tlong', + path: 'key_lower_case', + logtype: 'key_lower_case', + file: 'key_lower_case', + line_number: 'tint', + thread_name: 'key_lower_case', + bundle_id: 'key_lower_case', + host: 'key_lower_case', + case_id: 'key_lower_case', + log_message: 'text_std_token_lower_case', + id: 'string', + logger_name: 'key_lower_case', + text: 'text_std_token_lower_case', + logfile_line_number: 'tint', + logtime: 'tdate' + } }, serviceconfig: '', tree: { @@ -783,7 +879,7 @@ export const mockData = { event_count: 5, event_md5: '1908755391', event_dur_ms: 200, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: '2017-05-29T11:30:22.531Z', _router_field_: 20 }, @@ -807,7 +903,7 @@ export const mockData = { event_count: 2, event_md5: '1029384756', event_dur_ms: 700, - _ttl_: "+5DAYS", + _ttl_: '+5DAYS', _expire_at_: '2017-05-29T10:30:22.531Z', _router_field_: 5 } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/models/audit-log-field.model.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/audit-log-field.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/audit-log-field.model.ts new file mode 100644 index 0000000..96372a1 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/audit-log-field.model.ts @@ -0,0 +1,225 @@ +/** + * 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 {LogField} from '@app/models/log-field.model'; + +const columnsNamesMap = { + access: { + displayName: 'logs.accessType', + isDisplayed: true + }, + action: { + displayName: 'logs.action' + }, + agent: { + displayName: 'logs.agent' + }, + agentHost: { + displayName: 'logs.agentHost' + }, + authType: { + displayName: 'logs.authType' + }, + bundle_id: { + displayName: 'logs.bundleId' + }, + case_id: { + displayName: 'logs.caseId' + }, + cliIP: { + displayName: 'logs.clientIp', + isDisplayed: true + }, + cliType: { + displayName: 'logs.clientType' + }, + cluster: { + displayName: 'logs.cluster' + }, + dst: { + displayName: 'logs.dst' + }, + evtTime: { + displayName: 'logs.eventTime', + isDisplayed: true + }, + file: { + displayName: 'logs.file' + }, + host: { + displayName: 'logs.host' + }, + id: { + displayName: 'logs.id' + }, + ip: { + displayName: 'logs.ip' + }, + level: { + displayName: 'logs.level' + }, + log_message: { + displayName: 'logs.message' + }, + logType: { + displayName: 'logs.logType' + }, + logfile_line_number: { + displayName: 'logs.logfileLineNumber' + }, + logger_name: { + displayName: 'logs.loggerName' + }, + logtime: { + displayName: 'logs.logTime' + }, + path: { + displayName: 'logs.path' + }, + perm: { + displayName: 'logs.perm' + }, + policy: { + displayName: 'logs.policy' + }, + proxyUsers: { + displayName: 'logs.proxyUsers' + }, + reason: { + displayName: 'logs.reason' + }, + repo: { + displayName: 'logs.repo', + isDisplayed: true + }, + repoType: { + displayName: 'logs.repoType' + }, + req_caller_id: { + displayName: 'logs.reqCallerId' + }, + reqContext: { + displayName: 'logs.reqContext' + }, + reqData: { + displayName: 'logs.reqData' + }, + req_self_id: { + displayName: 'logs.reqSelfId' + }, + resType: { + displayName: 'logs.resType' + }, + resource: { + displayName: 'logs.resource', + isDisplayed: true + }, + result: { + displayName: 'logs.result', + isDisplayed: true + }, + sess: { + displayName: 'logs.session' + }, + text: { + displayName: 'logs.text' + }, + type: { + displayName: 'logs.type' + }, + ugi: { + displayName: 'logs.ugi' + }, + reqUser: { + displayName: 'logs.user', + isDisplayed: true + }, + ws_base_url: { + displayName: 'logs.baseUrl' + }, + ws_command: { + displayName: 'logs.command' + }, + ws_component: { + displayName: 'logs.component' + }, + ws_details: { + displayName: 'logs.details' + }, + ws_display_name: { + displayName: 'logs.displayName' + }, + ws_os: { + displayName: 'logs.os' + }, + ws_repo_id: { + displayName: 'logs.repoId' + }, + ws_repo_version: { + displayName: 'logs.repoVersion' + }, + ws_repositories: { + displayName: 'logs.repositories' + }, + ws_request_id: { + displayName: 'logs.requestId' + }, + ws_result_status: { + displayName: 'logs.resultStatus' + }, + ws_roles: { + displayName: 'logs.roles' + }, + ws_stack_version: { + displayName: 'logs.stackVersion' + }, + ws_stack: { + displayName: 'logs.stack' + }, + ws_status: { + displayName: 'logs.status' + }, + ws_task_id: { + displayName: 'logs.taskId' + }, + ws_version_note: { + displayName: 'logs.versionNote' + }, + ws_version_number: { + displayName: 'logs.versionNumber' + }, + tags: { + isAvailable: false + }, + tags_str: { + isAvailable: false + }, + seq_num: { + isAvailable: false + } +}; + +export class AuditLogField extends LogField { + constructor(name: string) { + super(name); + const preset = columnsNamesMap[this.name]; + if (preset) { + Object.assign(this, preset); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log-field.model.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log-field.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log-field.model.ts new file mode 100644 index 0000000..0e738ab --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/log-field.model.ts @@ -0,0 +1,27 @@ +/** + * 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 LogField { + constructor(name: string) { + this.name = name; + } + name: string; + displayName: string = this.name; + isDisplayed: boolean = false; + isAvailable: boolean = true; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log-field.model.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log-field.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log-field.model.ts new file mode 100644 index 0000000..081eecf --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/service-log-field.model.ts @@ -0,0 +1,107 @@ +/** + * 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 {LogField} from '@app/models/log-field.model'; + +const columnsNamesMap = { + log_message: { + displayName: 'logs.message', + isDisplayed: true + }, + bundle_id: { + displayName: 'logs.bundleId' + }, + case_id: { + displayName: 'logs.caseId' + }, + cluster: { + displayName: 'logs.cluster' + }, + event_count: { + displayName: 'logs.eventCount' + }, + file: { + displayName: 'logs.file' + }, + host: { + displayName: 'logs.host' + }, + id: { + displayName: 'logs.id' + }, + ip: { + displayName: 'logs.ip' + }, + level: { + displayName: 'logs.level', + isDisplayed: true + }, + line_number: { + displayName: 'logs.lineNumber' + }, + logtype: { + displayName: 'logs.logType' + }, + logfile_line_number: { + displayName: 'logs.logfileLineNumber' + }, + logger_name: { + displayName: 'logs.loggerName' + }, + logtime: { + isDisplayed: true + }, + method: { + displayName: 'logs.method' + }, + path: { + displayName: 'logs.path' + }, + rowtype: { + displayName: 'logs.rowType' + }, + thread_name: { + displayName: 'logs.threadName' + }, + type: { + displayName: 'logs.type', + isDisplayed: true + }, + tags: { + isAvailable: false + }, + text: { + isAvailable: false + }, + message: { + isAvailable: false + }, + seq_num: { + isAvailable: false + } +}; + +export class ServiceLogField extends LogField { + constructor(name: string) { + super(name); + const preset = columnsNamesMap[this.name]; + if (preset) { + Object.assign(this, preset); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/models/store.model.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/store.model.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/store.model.ts index fce72d7..13a1e68 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/models/store.model.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/models/store.model.ts @@ -7,7 +7,7 @@ * "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 + * 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, @@ -27,12 +27,15 @@ import {Graph} from '@app/models/graph.model'; import {Node} from '@app/models/node.model'; import {UserConfig} from '@app/models/user-config.model'; import {Filter} from '@app/models/filter.model'; +import {AuditLogField} from '@app/models/audit-log-field.model'; +import {ServiceLogField} from '@app/models/service-log-field.model'; export const storeActions = { 'ARRAY.ADD': 'ADD', 'ARRAY.DELETE.PRIMITIVE': 'DELETE_PRIMITIVE', 'ARRAY.DELETE.OBJECT': 'DELETE_OBJECT', 'ARRAY.CLEAR': 'CLEAR', + 'ARRAY.UPDATE.OBJECT': 'UPDATE_OBJECT', 'OBJECT.SET': 'SET' }; @@ -49,6 +52,8 @@ export interface AppStore { filters: Filter[]; clusters: string[]; components: string[]; + serviceLogsFields: ServiceLogField[]; + auditLogsFields: AuditLogField[]; } export class ModelService { @@ -90,7 +95,7 @@ export class CollectionModelService extends ModelService { deletePrimitiveInstance(instance: any): void { this.store.dispatch({ - type: `${storeActions['ARRAY.DELETE.PRINITIVE']}_${this.modelName}`, + type: `${storeActions['ARRAY.DELETE.PRIMITIVE']}_${this.modelName}`, payload: instance }); } @@ -101,6 +106,17 @@ export class CollectionModelService extends ModelService { }); } + updateObjectInstance(key: string, value: any, keyToModify: string, modifier: (value: any) => {}): void { + this.store.dispatch({ + type: `${storeActions['ARRAY.UPDATE.OBJECT']}_${this.modelName}`, + payload: { + selector: item => item[key] === value, + key: keyToModify, + modifier: (currentValue) => modifier(currentValue) + } + }); + } + } export class ObjectModelService extends ModelService { @@ -135,6 +151,14 @@ export function getCollectionReducer(modelName: string, defaultState: any = []): return state.filter(item => item !== action.payload); case `${storeActions['ARRAY.CLEAR']}_${modelName}`: return []; + case `${storeActions['ARRAY.UPDATE.OBJECT']}_${modelName}`: + const payload = action.payload; + let newState = state.slice(), + item = newState.find(payload.selector); + if (item) { + item[payload.key] = payload.modifier(item[payload.key]); + } + return newState; default: return state; } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/services/component-actions.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/component-actions.service.ts index 512b4f3..f79ba45 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/component-actions.service.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/component-actions.service.ts @@ -18,6 +18,7 @@ import {Injectable} from '@angular/core'; import {AppSettingsService} from '@app/services/storage/app-settings.service'; +import {CollectionModelService} from '@app/models/store.model'; @Injectable() export class ComponentActionsService { @@ -43,4 +44,8 @@ export class ComponentActionsService { this.appSettings.setParameter('timeZone', timeZone); } + updateSelectedColumns(columnName: string, model: CollectionModelService): void { + model.updateObjectInstance('name', columnName, 'isDisplayed', currentValue => !currentValue); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/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 260b920..625a55c 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 @@ -42,6 +42,9 @@ export class HttpClientService extends Http { url: 'audit/logs', params: opts => new AuditLogsQueryParams(opts) }, + auditLogsFields: { + url: 'audit/logs/schema/fields' + }, serviceLogs: { url: 'service/logs', params: opts => new ServiceLogsQueryParams(opts) @@ -50,6 +53,9 @@ export class HttpClientService extends Http { url: 'service/logs/histogram', params: opts => new ServiceLogsHistogramQueryParams(opts) }, + serviceLogsFields: { + url: 'service/logs/schema/fields' + }, components: { url: 'service/logs/components' }, http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/audit-logs-fields.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/audit-logs-fields.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/audit-logs-fields.service.ts new file mode 100644 index 0000000..bb8c661 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/audit-logs-fields.service.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 {Injectable} from '@angular/core'; +import {Store} from '@ngrx/store'; +import {AppStore, CollectionModelService, getCollectionReducer} from '@app/models/store.model'; + +export const modelName = 'auditLogsFields'; + +@Injectable() +export class AuditLogsFieldsService extends CollectionModelService { + constructor(store: Store<AppStore>) { + super(modelName, store); + } +} + +export const auditLogsFields = getCollectionReducer(modelName); http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/reducers.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/reducers.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/reducers.service.ts index 3c92c75..d941beb 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/reducers.service.ts +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/reducers.service.ts @@ -7,7 +7,7 @@ * "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 + * 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, @@ -27,6 +27,8 @@ import {graphs} from '@app/services/storage/graphs.service'; import {nodes} from '@app/services/storage/nodes.service'; import {serviceLogs} from '@app/services/storage/service-logs.service'; import {serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service'; +import {serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; +import {auditLogsFields} from '@app/services/storage/audit-logs-fields.service'; import {userConfigs} from '@app/services/storage/user-configs.service'; export const reducers = { @@ -40,7 +42,9 @@ export const reducers = { userConfigs, filters, clusters, - components + components, + serviceLogsFields, + auditLogsFields }; export function reducer(state: any, action: any) { http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/service-logs-fields.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/service-logs-fields.service.ts b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/service-logs-fields.service.ts new file mode 100644 index 0000000..0082cd6 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web-new/src/app/services/storage/service-logs-fields.service.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 {Injectable} from '@angular/core'; +import {Store} from '@ngrx/store'; +import {AppStore, CollectionModelService, getCollectionReducer} from '@app/models/store.model'; + +export const modelName = 'serviceLogsFields'; + +@Injectable() +export class ServiceLogsFieldsService extends CollectionModelService { + constructor(store: Store<AppStore>) { + super(modelName, store); + } +} + +export const serviceLogsFields = getCollectionReducer(modelName); http://git-wip-us.apache.org/repos/asf/ambari/blob/f4bb14c1/ambari-logsearch/ambari-logsearch-web-new/src/assets/i18n/en.json ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web-new/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web-new/src/assets/i18n/en.json index d6a46ac..1b71f24 100644 --- a/ambari-logsearch/ambari-logsearch-web-new/src/assets/i18n/en.json +++ b/ambari-logsearch/ambari-logsearch-web-new/src/assets/i18n/en.json @@ -49,6 +49,72 @@ "pagination.title": "Rows per page:", "pagination.numbers": "{{startIndex}}-{{endIndex}} of {{totalCount}}", + "logs.columns": "Columns", "logs.status": "Status", - "logs.details": "Details" + "logs.details": "Details", + "logs.message": "Message", + "logs.bundleId": "Bundle Id", + "logs.caseId": "Case Id", + "logs.cluster": "Cluster", + "logs.eventCount": "Event Count", + "logs.file": "File", + "logs.host": "Host", + "logs.id": "Id", + "logs.ip": "Ip", + "logs.level": "Level", + "logs.lineNumber": "Line Number", + "logs.logType": "Log Type", + "logs.logfileLineNumber": "Logfile Line Number", + "logs.loggerName": "Logger Name", + "logs.method": "Method", + "logs.path": "Path", + "logs.rowType": "Row Type", + "logs.threadName": "Thread", + "logs.type": "Type", + "logs.enforcer": "Access Enforcer", + "logs.accessType": "Access Type", + "logs.action": "Action", + "logs.agent": "Agent", + "logs.agentHost": "Agent Host", + "logs.authType": "Auth Type", + "logs.clientIp": "Client Ip", + "logs.clientType": "Client Type", + "logs.dst": "DST", + "logs.eventTime": "Event Time", + "logs.logMessage": "Log Message", + "logs.logTime": "Log Time", + "logs.perm": "Perm", + "logs.policy": "Policy", + "logs.proxyUsers": "Proxy Users", + "logs.reason": "Reason", + "logs.repo": "Repo", + "logs.repoType": "Repo Type", + "logs.reqCallerId": "Req Caller Id", + "logs.reqContext": "Req Context", + "logs.reqData": "Req Data", + "logs.reqSelfId": "Req Self Id", + "logs.resType": "Res Type", + "logs.resource": "Resource", + "logs.result": "Result", + "logs.session": "Session", + "logs.text": "Text", + "logs.ugi": "UGI", + "logs.user": "User", + "logs.baseUrl": "Base URL", + "logs.command": "Command", + "logs.component": "Component", + "logs.details": "Details", + "logs.displayName": "Display Name", + "logs.os": "OS", + "logs.repoId": "Repo Id", + "logs.repoVersion": "Repo Version", + "logs.repositories": "Repositories", + "logs.requestId": "Request Id", + "logs.resultStatus": "Result Status", + "logs.roles": "Roles", + "logs.stackVersion": "Stack Version", + "logs.stack": "Stack", + "logs.taskId": "Task Id", + "logs.versionNote": "Version Note", + "logs.versionNumber": "Version Number" }
