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/09/29 13:28:44 UTC
[1/2] ambari git commit: AMBARI-22093 Log Search UI: implement
service logs actions functionality. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk 7950e3c11 -> 8852edd2f
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
index b6ec8d7..f043f42 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
@@ -25,8 +25,10 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {HttpClientService} from '@app/services/http-client.service';
import {FilteringService} from '@app/services/filtering.service';
@@ -53,8 +55,10 @@ describe('ComponentGeneratorService', () => {
serviceLogsFields,
serviceLogsHistogramData,
appSettings,
+ appState,
clusters,
- components
+ components,
+ serviceLogsTruncated
})
],
providers: [
@@ -72,8 +76,10 @@ describe('ComponentGeneratorService', () => {
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
AppSettingsService,
+ AppStateService,
ClustersService,
- ComponentsService
+ ComponentsService,
+ ServiceLogsTruncatedService
]
});
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
index 8fed570..44a5f6a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
@@ -23,6 +23,7 @@ import {Http, XHRBackend, Request, RequestOptions, RequestOptionsArgs, Response,
import {AuditLogsQueryParams} from '@app/classes/queries/audit-logs-query-params.class';
import {ServiceLogsQueryParams} from '@app/classes/queries/service-logs-query-params.class';
import {ServiceLogsHistogramQueryParams} from '@app/classes/queries/service-logs-histogram-query-params.class';
+import {ServiceLogsTruncatedQueryParams} from '@app/classes/queries/service-logs-truncated-query-params.class';
import {AppStateService} from '@app/services/storage/app-state.service';
@Injectable()
@@ -56,6 +57,10 @@ export class HttpClientService extends Http {
serviceLogsFields: {
url: 'service/logs/schema/fields'
},
+ serviceLogsTruncated: {
+ url: 'service/logs/truncated',
+ params: opts => new ServiceLogsTruncatedQueryParams(opts)
+ },
components: {
url: 'service/logs/components'
},
@@ -88,7 +93,7 @@ export class HttpClientService extends Http {
const preset = this.endPoints[url],
rawParams = preset && preset.params ? preset.params(params) : params;
if (rawParams) {
- const paramsString = Object.keys(rawParams).map(key => `${key}=${rawParams[key]}`).join('&'),
+ const paramsString = Object.keys(rawParams).map((key: string): string => `${key}=${rawParams[key]}`).join('&'),
urlParams = new URLSearchParams(paramsString, {
encodeKey: key => key,
encodeValue: value => encodeURIComponent(value)
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
index 8ebbd72..a762fef 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
@@ -24,9 +24,11 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {HttpClientService} from '@app/services/http-client.service';
import {FilteringService} from '@app/services/filtering.service';
@@ -51,9 +53,11 @@ describe('LogsContainerService', () => {
serviceLogsFields,
serviceLogsHistogramData,
appSettings,
+ appState,
clusters,
components,
- hosts
+ hosts,
+ serviceLogsTruncated
})
],
providers: [
@@ -63,9 +67,11 @@ describe('LogsContainerService', () => {
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
AppSettingsService,
+ AppStateService,
ClustersService,
ComponentsService,
HostsService,
+ ServiceLogsTruncatedService,
LogsContainerService,
{
provide: HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
index bef28cf..14e9ad4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
@@ -24,11 +24,24 @@ import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.se
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 {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
+import {AppStateService} from '@app/services/storage/app-state.service';
+import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry.class';
@Injectable()
export class LogsContainerService {
- constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, 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 serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private filtering: FilteringService) {
+ appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => this.activeLog = value);
+ appState.getParameter('isServiceLogsFileView').subscribe((value: boolean): void => {
+ const activeLog = this.activeLog,
+ filtersForm = this.filtering.filtersForm;
+ if (value && activeLog) {
+ filtersForm.controls.hosts.setValue(activeLog.host_name);
+ filtersForm.controls.components.setValue(activeLog.component_name);
+ }
+ this.isServiceLogsFileView = value;
+ });
}
readonly colors = {
@@ -77,26 +90,65 @@ export class LogsContainerService {
totalCount: number = 0;
+ isServiceLogsFileView: boolean = false;
+
+ activeLog: ActiveServiceLogEntry | null = null;
+
loadLogs(logsType: string): void {
this.httpClient.get(logsType, this.getParams('listFilters')).subscribe(response => {
- const jsonResponse = response.json();
- this.logsTypeMap[logsType].logsModel.clear();
+ const jsonResponse = response.json(),
+ model = this.logsTypeMap[logsType].logsModel;
+ model.clear();
if (jsonResponse) {
const logs = jsonResponse.logList,
count = jsonResponse.totalCount || 0;
if (logs) {
- this.serviceLogsStorage.addInstances(logs);
+ model.addInstances(logs);
}
this.totalCount = count;
}
});
- this.httpClient.get('serviceLogsHistogram', this.getParams('histogramFilters')).subscribe(response => {
+ if (logsType === 'serviceLogs') {
+ // TODO rewrite to implement conditional data loading for service logs histogram or audit logs graph
+ this.httpClient.get('serviceLogsHistogram', this.getParams('histogramFilters')).subscribe(response => {
+ const jsonResponse = response.json();
+ this.serviceLogsHistogramStorage.clear();
+ if (jsonResponse) {
+ const histogramData = jsonResponse.graphData;
+ if (histogramData) {
+ this.serviceLogsHistogramStorage.addInstances(histogramData);
+ }
+ }
+ });
+ }
+ }
+
+ loadLogContext(id: string, hostName: string, componentName: string, scrollType: 'before' | 'after' | '' = ''): void {
+ const params = {
+ id: id,
+ host_name: hostName,
+ component_name: componentName,
+ scrollType: scrollType
+ };
+ this.httpClient.get('serviceLogsTruncated', params).subscribe(response => {
const jsonResponse = response.json();
- this.serviceLogsHistogramStorage.clear();
+ if (!scrollType) {
+ this.serviceLogsTruncatedStorage.clear();
+ }
if (jsonResponse) {
- const histogramData = jsonResponse.graphData;
- if (histogramData) {
- this.serviceLogsHistogramStorage.addInstances(histogramData);
+ const logs = jsonResponse.logList;
+ if (logs) {
+ if (scrollType === 'before') {
+ this.serviceLogsTruncatedStorage.addInstancesToStart(logs);
+ } else {
+ this.serviceLogsTruncatedStorage.addInstances(logs);
+ }
+ if (!scrollType) {
+ this.appState.setParameters({
+ isServiceLogContextView: true,
+ activeLog: params
+ });
+ }
}
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts
index 08f237d..ca8a632 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts
@@ -27,6 +27,7 @@ import {graphs} from '@app/services/storage/graphs.service';
import {hosts} from '@app/services/storage/hosts.service';
import {serviceLogs} from '@app/services/storage/service-logs.service';
import {serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.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';
@@ -37,6 +38,7 @@ export const reducers = {
auditLogs,
serviceLogs,
serviceLogsHistogramData,
+ serviceLogsTruncated,
graphs,
hosts,
userConfigs,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/service-logs-truncated.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/service-logs-truncated.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/service-logs-truncated.service.ts
new file mode 100644
index 0000000..f8fe0f7
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/service-logs-truncated.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 = 'serviceLogsTruncated';
+
+@Injectable()
+export class ServiceLogsTruncatedService extends CollectionModelService {
+ constructor(store: Store<AppStore>) {
+ super(modelName, store);
+ }
+}
+
+export const serviceLogsTruncated = getCollectionReducer(modelName);
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
index 0d40bc7..1dee559 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
+++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
@@ -4,6 +4,7 @@
"modal.submit": "OK",
"modal.cancel": "Cancel",
"modal.apply": "Apply",
+ "modal.close": "Close",
"authorization.name": "Username",
"authorization.password": "Password",
@@ -141,5 +142,9 @@
"logs.versionNote": "Version Note",
"logs.versionNumber": "Version Number",
"logs.addToQuery": "Add to Query",
- "logs.excludeFromQuery": "Exclude from Query"
+ "logs.excludeFromQuery": "Exclude from Query",
+ "logs.copy": "Copy",
+ "logs.open": "Open Log",
+ "logs.context": "Context",
+ "logs.loadMore": "Load more"
}
[2/2] ambari git commit: AMBARI-22093 Log Search UI: implement
service logs actions functionality. (ababiichuk)
Posted by ab...@apache.org.
AMBARI-22093 Log Search UI: implement service logs actions functionality. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8852edd2
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8852edd2
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8852edd2
Branch: refs/heads/trunk
Commit: 8852edd2f5458a22109bc0931fd6e91341d0523f
Parents: 7950e3c
Author: ababiichuk <ab...@hortonworks.com>
Authored: Fri Sep 29 15:45:40 2017 +0300
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Fri Sep 29 15:45:40 2017 +0300
----------------------------------------------------------------------
.../ambari-logsearch-web/src/app/app.module.ts | 6 ++
.../classes/active-service-log-entry.class.ts | 23 ++++
.../src/app/classes/list-item.class.ts | 1 +
.../queries/audit-logs-query-params.class.ts | 2 +-
...service-logs-truncated-query-params.class.ts | 36 +++++++
.../classes/service-log-context-entry.class.ts | 26 +++++
.../dropdown-button.component.html | 3 +-
.../dropdown-button.component.spec.ts | 5 +-
.../dropdown-list/dropdown-list.component.html | 2 +-
.../dropdown-list.component.spec.ts | 12 ++-
.../dropdown-list/dropdown-list.component.ts | 9 +-
.../filter-button.component.spec.ts | 5 +-
.../filter-dropdown.component.spec.ts | 5 +-
.../filters-panel.component.spec.ts | 5 +-
.../log-context/log-context.component.html | 33 ++++++
.../log-context/log-context.component.less | 23 ++++
.../log-context/log-context.component.spec.ts | 108 +++++++++++++++++++
.../log-context/log-context.component.ts | 91 ++++++++++++++++
.../log-file-entry.component.html | 20 ++++
.../log-file-entry.component.less | 31 ++++++
.../log-file-entry.component.spec.ts | 56 ++++++++++
.../log-file-entry/log-file-entry.component.ts | 51 +++++++++
.../logs-container.component.html | 8 +-
.../logs-container.component.spec.ts | 5 +-
.../logs-container/logs-container.component.ts | 29 +++--
.../logs-list/logs-list.component.html | 30 +++---
.../logs-list/logs-list.component.less | 36 +------
.../logs-list/logs-list.component.spec.ts | 3 +
.../components/logs-list/logs-list.component.ts | 34 +++++-
.../main-container.component.html | 7 ++
.../main-container.component.less | 4 +
.../main-container.component.spec.ts | 13 ++-
.../main-container/main-container.component.ts | 28 ++++-
.../menu-button/menu-button.component.spec.ts | 5 +-
.../timezone-picker.component.spec.ts | 5 +-
.../src/app/components/variables.less | 30 ++++++
.../src/app/models/app-state.model.ts | 10 +-
.../src/app/models/bar-graph.model.ts | 2 +-
.../src/app/models/graph.model.ts | 2 +-
.../src/app/models/log.model.ts | 1 +
.../src/app/models/store.model.ts | 11 ++
.../services/component-actions.service.spec.ts | 8 +-
.../app/services/component-actions.service.ts | 50 ++++++++-
.../component-generator.service.spec.ts | 10 +-
.../src/app/services/http-client.service.ts | 7 +-
.../app/services/logs-container.service.spec.ts | 8 +-
.../src/app/services/logs-container.service.ts | 70 ++++++++++--
.../app/services/storage/reducers.service.ts | 2 +
.../storage/service-logs-truncated.service.ts | 32 ++++++
.../src/assets/i18n/en.json | 7 +-
50 files changed, 908 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index c4dc698..ff791fe 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -44,6 +44,7 @@ import {AppStateService} from '@app/services/storage/app-state.service';
import {AuditLogsService} from '@app/services/storage/audit-logs.service';
import {ServiceLogsService} from '@app/services/storage/service-logs.service';
import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
import {GraphsService} from '@app/services/storage/graphs.service';
import {HostsService} from '@app/services/storage/hosts.service';
import {UserConfigsService} from '@app/services/storage/user-configs.service';
@@ -76,6 +77,8 @@ import {NodeBarComponent} from '@app/components/node-bar/node-bar.component';
import {SearchBoxComponent} from '@app/components/search-box/search-box.component';
import {TimeRangePickerComponent} from '@app/components/time-range-picker/time-range-picker.component';
import {DatePickerComponent} from '@app/components/date-picker/date-picker.component';
+import {LogContextComponent} from '@app/components/log-context/log-context.component';
+import {LogFileEntryComponent} from '@app/components/log-file-entry/log-file-entry.component';
import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
import {TimerSecondsPipe} from '@app/pipes/timer-seconds.pipe';
@@ -124,6 +127,8 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
SearchBoxComponent,
TimeRangePickerComponent,
DatePickerComponent,
+ LogContextComponent,
+ LogFileEntryComponent,
TimeZoneAbbrPipe,
TimerSecondsPipe
],
@@ -157,6 +162,7 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
AuditLogsService,
ServiceLogsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
GraphsService,
HostsService,
UserConfigsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/classes/active-service-log-entry.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/active-service-log-entry.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/active-service-log-entry.class.ts
new file mode 100644
index 0000000..d3d7d95
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/active-service-log-entry.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 interface ActiveServiceLogEntry {
+ id: string;
+ host_name: string;
+ component_name: string;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/classes/list-item.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/list-item.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/list-item.class.ts
index adb023b..1aaaecc 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/list-item.class.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/list-item.class.ts
@@ -22,4 +22,5 @@ export interface ListItem {
value: any;
iconClass?: string;
isChecked?: boolean;
+ action?: string;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/audit-logs-query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/audit-logs-query-params.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/audit-logs-query-params.class.ts
index e36bf18..3727abb 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/audit-logs-query-params.class.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/audit-logs-query-params.class.ts
@@ -35,7 +35,7 @@ export class AuditLogsQueryParams extends QueryParams {
pageSize: string;
startIndex: string;
sortBy?: string;
- sortType?: string;
+ sortType?: 'asc' | 'desc';
clusters?: string;
mustBe?: string;
mustNot?: string;
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-truncated-query-params.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-truncated-query-params.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-truncated-query-params.class.ts
new file mode 100644
index 0000000..da05cee
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/queries/service-logs-truncated-query-params.class.ts
@@ -0,0 +1,36 @@
+/**
+ * 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 const defaultParams = {
+ numberRows: '10',
+ scrollType: ''
+};
+
+export class ServiceLogsTruncatedQueryParams extends QueryParams {
+ constructor(options: ServiceLogsTruncatedQueryParams) {
+ const finalParams = Object.assign({}, defaultParams, options);
+ super(finalParams);
+ }
+ id: string;
+ host_name: string;
+ component_name: string;
+ numberRows: string;
+ scrollType: 'before' | 'after' | '';
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/classes/service-log-context-entry.class.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/service-log-context-entry.class.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/service-log-context-entry.class.ts
new file mode 100644
index 0000000..15c05fb
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/service-log-context-entry.class.ts
@@ -0,0 +1,26 @@
+/**
+ * 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 interface ServiceLogContextEntry {
+ id: string;
+ time: number;
+ level: string;
+ message: string;
+ fileName: string | null;
+ lineNumber: number | null;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
index 9536573..798a609 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
@@ -26,5 +26,6 @@
<span *ngIf="!hideCaret" class="caret"></span>
</button>
<ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"
- [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"></ul>
+ [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"
+ [actionArguments]="additionalArgs"></ul>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
index f7227b1..e795986 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
@@ -30,6 +30,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
@@ -56,7 +57,8 @@ describe('DropdownButtonComponent', () => {
auditLogsFields,
serviceLogs,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -71,6 +73,7 @@ describe('DropdownButtonComponent', () => {
ServiceLogsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
FilteringService,
UtilsService,
ComponentActionsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
index 316d3f9..5de78ad 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
@@ -26,7 +26,7 @@
</label>
</label>
<span class="list-item-label label-container" *ngIf="!isMultipleChoice"
- (click)="changeSelectedItem({value: item.value, label: item.label})">
+ (click)="changeSelectedItem(item)">
<span *ngIf="item.iconClass" [ngClass]="item.iconClass"></span>
{{item.label | translate}}
<div #additionalComponent></div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
index eacac04..759a0e1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
@@ -26,12 +26,15 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {ComponentGeneratorService} from '@app/services/component-generator.service';
import {LogsContainerService} from '@app/services/logs-container.service';
import {HttpClientService} from '@app/services/http-client.service';
import {FilteringService} from '@app/services/filtering.service';
+import {ComponentActionsService} from '@app/services/component-actions.service';
import {DropdownListComponent} from './dropdown-list.component';
@@ -60,8 +63,10 @@ describe('DropdownListComponent', () => {
serviceLogsFields,
serviceLogsHistogramData,
appSettings,
+ appState,
clusters,
- components
+ components,
+ serviceLogsTruncated
})
],
providers: [
@@ -72,6 +77,7 @@ describe('DropdownListComponent', () => {
useValue: httpClient
},
FilteringService,
+ ComponentActionsService,
HostsService,
AuditLogsService,
ServiceLogsService,
@@ -79,8 +85,10 @@ describe('DropdownListComponent', () => {
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
AppSettingsService,
+ AppStateService,
ClustersService,
- ComponentsService
+ ComponentsService,
+ ServiceLogsTruncatedService
]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
index 82656cf..656c901 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.ts
@@ -19,6 +19,7 @@
import {Component, AfterViewInit, Input, Output, EventEmitter, ViewChildren, ViewContainerRef, QueryList} from '@angular/core';
import {ListItem} from '@app/classes/list-item.class';
import {ComponentGeneratorService} from '@app/services/component-generator.service';
+import {ComponentActionsService} from '@app/services/component-actions.service';
@Component({
selector: 'ul[data-component="dropdown-list"]',
@@ -27,7 +28,7 @@ import {ComponentGeneratorService} from '@app/services/component-generator.servi
})
export class DropdownListComponent implements AfterViewInit {
- constructor(private componentGenerator: ComponentGeneratorService) {
+ constructor(private componentGenerator: ComponentGeneratorService, private actions: ComponentActionsService) {
}
ngAfterViewInit() {
@@ -49,6 +50,9 @@ export class DropdownListComponent implements AfterViewInit {
@Input()
additionalLabelComponentSetter?: string;
+ @Input()
+ actionArguments: any[] = [];
+
@Output()
selectedItemChange: EventEmitter<ListItem> = new EventEmitter();
@@ -58,6 +62,9 @@ export class DropdownListComponent implements AfterViewInit {
containers: QueryList<ViewContainerRef>;
changeSelectedItem(options: ListItem): void {
+ if (options.action) {
+ this.actions[options.action](...this.actionArguments);
+ }
this.selectedItemChange.emit(options);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
index a01a3f3..4e6f460 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
@@ -30,6 +30,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
@@ -56,7 +57,8 @@ describe('FilterButtonComponent', () => {
auditLogsFields,
serviceLogs,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -71,6 +73,7 @@ describe('FilterButtonComponent', () => {
ServiceLogsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
ComponentActionsService,
FilteringService,
UtilsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
index 85e7ecb..f5b9330 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
@@ -26,6 +26,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
@@ -65,7 +66,8 @@ describe('FilterDropdownComponent', () => {
auditLogsFields,
serviceLogs,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -77,6 +79,7 @@ describe('FilterDropdownComponent', () => {
ServiceLogsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
{
provide: FilteringService,
useValue: filtering
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
index ae5a4af..0643ea6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
@@ -30,6 +30,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {AppStateService, appState} from '@app/services/storage/app-state.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {UtilsService} from '@app/services/utils.service';
@@ -67,7 +68,8 @@ describe('FiltersPanelComponent', () => {
auditLogsFields,
serviceLogsFields,
serviceLogsHistogramData,
- appState
+ appState,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -82,6 +84,7 @@ describe('FiltersPanelComponent', () => {
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
AppStateService,
+ ServiceLogsTruncatedService,
FilteringService,
LogsContainerService,
{
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html
new file mode 100644
index 0000000..2e51e0b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.html
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<modal title="{{hostName}} -> {{componentName}}" submitButtonLabel="modal.close" [showCancelButton]="false"
+ [isLargeModal]="true" (init)="scrollToCurrentEntry()" (submit)="closeLogContext()" (close)="closeLogContext()">
+ <ng-template>
+ <button class="btn btn-primary" (click)="loadBefore()">
+ {{'logs.loadMore' | translate}} <span class="fa fa-arrow-up"></span>
+ </button>
+ <div class="logs">
+ <log-file-entry *ngFor="let log of logs | async" [ngClass]="log.id === id ? currentLogClassName : ''"
+ [time]="log.time" [level]="log.level" [fileName]="log.fileName" [lineNumber]="log.lineNumber"
+ [message]="log.message"></log-file-entry>
+ </div>
+ <button class="btn btn-primary" (click)="loadAfter()">
+ {{'logs.loadMore' | translate}} <span class="fa fa-arrow-down"></span>
+ </button>
+ </ng-template>
+</modal>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less
new file mode 100644
index 0000000..235853b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.less
@@ -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.
+ */
+
+@import '../variables';
+
+.logs {
+ max-height: @dropdown-max-height; // TODO implement actual styles
+ overflow-y: auto;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
new file mode 100644
index 0000000..c21750a
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
@@ -0,0 +1,108 @@
+/**
+ * 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 {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 {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.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 {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TranslationModules} from '@app/test-config.spec';
+import {ModalComponent} from '@app/components/modal/modal.component';
+import {LogsContainerService} from '@app/services/logs-container.service';
+import {HttpClientService} from '@app/services/http-client.service';
+import {FilteringService} from '@app/services/filtering.service';
+
+import {LogContextComponent} from './log-context.component';
+
+describe('LogContextComponent', () => {
+ let component: LogContextComponent;
+ let fixture: ComponentFixture<LogContextComponent>;
+
+ beforeEach(async(() => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ }
+ }
+ };
+ TestBed.configureTestingModule({
+ declarations: [
+ LogContextComponent,
+ ModalComponent
+ ],
+ imports: [
+ StoreModule.provideStore({
+ auditLogs,
+ serviceLogs,
+ auditLogsFields,
+ serviceLogsFields,
+ serviceLogsHistogramData,
+ appSettings,
+ appState,
+ clusters,
+ components,
+ hosts,
+ serviceLogsTruncated
+ }),
+ ...TranslationModules
+ ],
+ providers: [
+ AuditLogsService,
+ ServiceLogsService,
+ AuditLogsFieldsService,
+ ServiceLogsFieldsService,
+ ServiceLogsHistogramDataService,
+ AppSettingsService,
+ AppStateService,
+ ClustersService,
+ ComponentsService,
+ HostsService,
+ ServiceLogsTruncatedService,
+ LogsContainerService,
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ },
+ FilteringService
+ ],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LogContextComponent);
+ component = fixture.componentInstance;
+ component.scrollToCurrentEntry = () => {};
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts
new file mode 100644
index 0000000..467de98
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.ts
@@ -0,0 +1,91 @@
+/**
+ * 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 {Component, Input, ElementRef} from '@angular/core';
+import {Observable} from 'rxjs/Observable';
+import 'rxjs/add/operator/map';
+import {LogsContainerService} from '@app/services/logs-container.service';
+import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
+import {AppStateService} from '@app/services/storage/app-state.service';
+import {ServiceLog} from '@app/models/service-log.model';
+import {ServiceLogContextEntry} from '@app/classes/service-log-context-entry.class';
+
+@Component({
+ selector: 'log-context',
+ templateUrl: './log-context.component.html',
+ styleUrls: ['./log-context.component.less']
+})
+export class LogContextComponent {
+
+ constructor(private element: ElementRef, private logsContainer: LogsContainerService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService) {
+ }
+
+ @Input()
+ id: string;
+
+ @Input()
+ hostName: string;
+
+ @Input()
+ componentName: string;
+
+ readonly currentLogClassName: string = 'alert-warning'; // TODO implement custom class name with actual styles
+
+ firstEntryId: string;
+
+ lastEntryId: string;
+
+ logs: Observable<ServiceLogContextEntry[]> = this.serviceLogsTruncatedStorage.getAll().map((logs: ServiceLog[]): ServiceLogContextEntry[] => {
+ if (logs.length) {
+ this.firstEntryId = logs[0].id;
+ this.lastEntryId = logs[logs.length - 1].id;
+ }
+ return logs.map((log: ServiceLog): ServiceLogContextEntry => {
+ return {
+ id: log.id,
+ time: log.logtime,
+ level: log.level,
+ message: log.log_message,
+ fileName: log.file,
+ lineNumber: log.line_number
+ };
+ });
+ });
+
+ closeLogContext(): void {
+ this.appState.setParameters({
+ isServiceLogContextView: false,
+ activeLog: null
+ });
+ this.serviceLogsTruncatedStorage.clear();
+ this.firstEntryId = '';
+ this.lastEntryId = '';
+ }
+
+ scrollToCurrentEntry() {
+ this.element.nativeElement.getElementsByClassName(this.currentLogClassName).item(0).scrollIntoView();
+ }
+
+ loadBefore(): void {
+ this.logsContainer.loadLogContext(this.firstEntryId, this.hostName, this.componentName, 'before');
+ }
+
+ loadAfter(): void {
+ this.logsContainer.loadLogContext(this.lastEntryId, this.hostName, this.componentName, 'after');
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.html
new file mode 100644
index 0000000..7d4c296
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.html
@@ -0,0 +1,20 @@
+<!--
+ 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.
+-->
+
+<div class="log">{{time | amTz: timeZone |amDateFormat: timeFormat}} <span
+ class="{{'log-level ' + level.toLowerCase()}}">{{level}}</span><span *ngIf="fileName"> {{fileName}}<span
+ *ngIf="lineNumber">:{{lineNumber}}</span></span> - {{message}}</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.less
new file mode 100644
index 0000000..d3523d3
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.less
@@ -0,0 +1,31 @@
+/**
+ * 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 {
+ display: block;
+
+ .log {
+ font-family: monospace;
+ white-space: pre-wrap;
+
+ .log-level {
+ .log-colors;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.spec.ts
new file mode 100644
index 0000000..0ae7e67
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.spec.ts
@@ -0,0 +1,56 @@
+/**
+ * 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 {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {MomentModule} from 'angular2-moment';
+import {MomentTimezoneModule} from 'angular-moment-timezone';
+import {StoreModule} from '@ngrx/store';
+import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+
+import {LogFileEntryComponent} from './log-file-entry.component';
+
+describe('LogFileEntryComponent', () => {
+ let component: LogFileEntryComponent;
+ let fixture: ComponentFixture<LogFileEntryComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [LogFileEntryComponent],
+ imports: [
+ StoreModule.provideStore({
+ appSettings
+ }),
+ MomentModule,
+ MomentTimezoneModule
+ ],
+ providers: [
+ AppSettingsService
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LogFileEntryComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create component', () => {
+ expect(component).toBeTruthy();
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.ts
new file mode 100644
index 0000000..c0a7393
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-file-entry/log-file-entry.component.ts
@@ -0,0 +1,51 @@
+/**
+ * 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 {Component, Input} from '@angular/core';
+import {AppSettingsService} from '@app/services/storage/app-settings.service';
+
+@Component({
+ selector: 'log-file-entry',
+ templateUrl: './log-file-entry.component.html',
+ styleUrls: ['./log-file-entry.component.less']
+})
+export class LogFileEntryComponent {
+
+ constructor(private appSettings: AppSettingsService) {
+ appSettings.getParameter('timeZone').subscribe((value: string) => this.timeZone = value);
+ }
+
+ @Input()
+ time: string = '';
+
+ @Input()
+ level: string = '';
+
+ @Input()
+ fileName?: string;
+
+ @Input()
+ lineNumber?: string;
+
+ @Input()
+ message: string = '';
+
+ readonly timeFormat: string = 'YYYY-MM-DD HH:mm:ss,SSS';
+
+ timeZone: string;
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
index 5145b76..9c6c336 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
@@ -21,7 +21,9 @@
</div>
</div>
<time-histogram class="col-md-12" [data]="histogramData" [customOptions]="histogramOptions"></time-histogram>
-<dropdown-button class="pull-right" label="logs.columns" [options]="availableColumns | async" [isRightAlign]="true"
- isMultipleChoice="true" action="updateSelectedColumns"
- [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
+<dropdown-button *ngIf="!isServiceLogsFileView" class="pull-right" label="logs.columns"
+ [options]="availableColumns | async" [isRightAlign]="true" [isMultipleChoice]="true"
+ action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
<logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"></logs-list>
+<log-context *ngIf="isServiceLogContextView" [hostName]="activeLog.host_name" [componentName]="activeLog.component_name"
+ [id]="activeLog.id"></log-context>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
index 811c6e6..f3b28d1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
@@ -30,6 +30,7 @@ import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-log
import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {HttpClientService} from '@app/services/http-client.service';
import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
@@ -63,7 +64,8 @@ describe('LogsContainerComponent', () => {
serviceLogs,
serviceLogsFields,
serviceLogsHistogramData,
- hosts
+ hosts,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -82,6 +84,7 @@ describe('LogsContainerComponent', () => {
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
HostsService,
+ ServiceLogsTruncatedService,
FilteringService,
UtilsService,
LogsContainerService
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
index b1fad17..fd3a58b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
@@ -27,6 +27,7 @@ import {AppStateService} from '@app/services/storage/app-state.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';
+import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry.class';
@Component({
selector: 'logs-container',
@@ -37,12 +38,13 @@ export class LogsContainerComponent implements OnInit {
constructor(private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
serviceLogsHistogramStorage.getAll().subscribe(data => this.histogramData = this.logsContainer.getHistogramData(data));
+ appState.getParameter('isServiceLogContextView').subscribe((value: boolean) => this.isServiceLogContextView = value);
}
ngOnInit() {
const fieldsModel = this.logsTypeMapObject.fieldsModel,
logsModel = this.logsTypeMapObject.logsModel;
- this.appState.getParameter(this.logsTypeMapObject.isSetFlag).subscribe(value => this.isLogsSet = value);
+ this.appState.getParameter(this.logsTypeMapObject.isSetFlag).subscribe((value: boolean) => this.isLogsSet = value);
this.availableColumns = fieldsModel.getAll().map(fields => {
return fields.filter(field => field.isAvailable).map(field => {
return {
@@ -56,15 +58,13 @@ export class LogsContainerComponent implements OnInit {
const availableFields = columns.filter(field => field.isAvailable),
availableNames = availableFields.map(field => field.name);
if (availableNames.length && !this.isLogsSet) {
- this.logs = 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;
- }));
+ this.logs = logsModel.getAll().map((logs: (AuditLog | ServiceLog)[]): (AuditLog | ServiceLog)[] => {
+ return logs.map((log: AuditLog | ServiceLog): AuditLog | ServiceLog => {
+ return availableNames.reduce((obj, key) => Object.assign(obj, {
+ [key]: log[key]
+ }), {});
+ });
+ });
this.appState.setParameter(this.logsTypeMapObject.isSetFlag, true);
}
this.displayedColumns = columns.filter(column => column.isAvailable && column.isDisplayed);
@@ -112,4 +112,13 @@ export class LogsContainerComponent implements OnInit {
};
}
+ isServiceLogContextView: boolean = false;
+
+ get isServiceLogsFileView(): boolean {
+ return this.logsContainer.isServiceLogsFileView;
+ };
+
+ get activeLog(): ActiveServiceLogEntry | null {
+ return this.logsContainer.activeLog;
+ };
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 2942b20..b27eb69 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -19,20 +19,20 @@
<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 && logs.length">
- <div class="logs-header">
- <div class="col-md-1">{{'logs.status' | translate}}</div>
- <div class="col-md-11">{{'logs.details' | translate}}</div>
- </div>
-</div>
<div *ngFor="let log of logs; let i = index">
- <div *ngIf="i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime)" class="col-md-12">
+ <div *ngIf="!isServiceLogsFileView && (i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime))" class="col-md-12">
<div class="logs-header">{{log.logtime | amTz: timeZone | amDateFormat: dateFormat}}</div>
</div>
- <accordion-panel [toggleId]="'details-' + i" class="col-md-12">
+ <accordion-panel *ngIf="!isServiceLogsFileView" [toggleId]="'details-' + i" class="col-md-12">
<ng-template>
- <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('level')" [ngClass]="'hexagon ' + log.level.toLowerCase()"></div>
+ <div class="col-md-1">
+ <dropdown-button iconClass="fa fa-ellipsis-h" [hideCaret]="true" [options]="logActions"
+ [additionalArgs]="[log]"></dropdown-button>
+ </div>
+ <div *ngIf="isColumnDisplayed('level')" [ngClass]="'col-md-1 log-status ' + log.level.toLowerCase()">
+ {{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">
@@ -41,9 +41,7 @@
</div>
<div class="col-md-6 log-content-wrapper">
<div class="collapse log-actions" attr.id="details-{{i}}">
- <span class="action-icon fa fa-search"></span>
- <span class="action-icon fa fa-external-link"></span>
- <span class="action-icon fa fa-crosshairs"></span>
+ <!-- TODO remove after restyling the table -->
</div>
<div class="log-content-inner-wrapper">
<div class="log-content" *ngIf="isColumnDisplayed('log_message')"
@@ -58,8 +56,10 @@
</div>
</ng-template>
</accordion-panel>
+ <log-file-entry *ngIf="isServiceLogsFileView" class="col-md-12" [time]="log.logtime" [level]="log.level"
+ [fileName]="log.file" [lineNumber]="log.line_number" [message]="log.log_message"></log-file-entry>
</div>
-<ul #contextmenu data-component="dropdown-list" class="dropdown-menu context-menu" [items]="contextMenuItems"
- (selectedItemChange)="updateQuery($event)"></ul>
+<ul #contextmenu *ngIf="!isServiceLogsFileView" data-component="dropdown-list" class="dropdown-menu context-menu"
+ [items]="contextMenuItems" (selectedItemChange)="updateQuery($event)"></ul>
<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/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
index 577043f..0fded67 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
@@ -30,7 +30,7 @@
}
.hexagon {
- // TODO get rid of magic numbers, base on actual design
+ // TODO remove, since it's not a part of updated design
left: -7.5px;
&.fatal {
@@ -64,34 +64,7 @@
.log-status {
text-transform: uppercase;
-
- &.fatal {
- color: @fatal-color;
- }
-
- &.error {
- color: @error-color;
- }
-
- &.warn {
- color: @warning-color;
- }
-
- &.info {
- color: @info-color;
- }
-
- &.debug {
- color: @debug-color;
- }
-
- &.trace {
- color: @trace-color;
- }
-
- &.unknown {
- color: @unknown-color;
- }
+ .log-colors;
}
.log-type {
@@ -117,11 +90,6 @@
}
.log-actions {
- position: absolute;
- right: 40px;
- top: 0;
- border: @input-border;
-
&.collapsing + .log-content-inner-wrapper, &.collapse.in + .log-content-inner-wrapper {
min-height: 6em;
max-height: none;
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
index 8c67a13..8ee4ca3 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
@@ -24,6 +24,7 @@ import {MomentTimezoneModule} from 'angular-moment-timezone';
import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service';
import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
@@ -53,6 +54,7 @@ describe('LogsListComponent', () => {
auditLogs,
serviceLogs,
appSettings,
+ appState,
clusters,
components,
hosts
@@ -69,6 +71,7 @@ describe('LogsListComponent', () => {
AuditLogsService,
ServiceLogsService,
AppSettingsService,
+ AppStateService,
ClustersService,
ComponentsService,
HostsService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
index aeb55da..c94b967 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
@@ -15,28 +15,32 @@
* limitations under the License.
*/
-import {Component, OnInit, Input, ViewChild, ElementRef} from '@angular/core';
+import {Component, AfterViewInit, Input, ViewChild, ElementRef} from '@angular/core';
import {FormGroup} from '@angular/forms';
import 'rxjs/add/operator/map';
+import {AppStateService} from '@app/services/storage/app-state.service';
import {FilteringService} from '@app/services/filtering.service';
import {UtilsService} from '@app/services/utils.service';
+import {AuditLog} from '@app/models/audit-log.model';
+import {ServiceLog} from '@app/models/service-log.model';
@Component({
selector: 'logs-list',
templateUrl: './logs-list.component.html',
styleUrls: ['./logs-list.component.less']
})
-export class LogsListComponent implements OnInit {
+export class LogsListComponent implements AfterViewInit {
- constructor(private filtering: FilteringService, private utils: UtilsService) {
+ constructor(private filtering: FilteringService, private utils: UtilsService, private appState: AppStateService) {
+ appState.getParameter('isServiceLogsFileView').subscribe((value: boolean) => this.isServiceLogsFileView = value);
}
- ngOnInit() {
+ ngAfterViewInit() {
this.contextMenuElement = this.contextMenu.nativeElement;
}
@Input()
- logs: any[] = [];
+ logs: (AuditLog| ServiceLog)[] = [];
@Input()
totalCount: number = 0;
@@ -70,6 +74,24 @@ export class LogsListComponent implements OnInit {
}
];
+ readonly logActions = [
+ {
+ label: 'logs.copy',
+ iconClass: 'fa fa-files-o',
+ action: 'copyLog'
+ },
+ {
+ label: 'logs.open',
+ iconClass: 'fa fa-external-link',
+ action: 'openLog'
+ },
+ {
+ label: 'logs.context',
+ iconClass: 'fa fa-crosshairs',
+ action: 'openContext'
+ }
+ ];
+
readonly dateFormat: string = 'dddd, MMMM Do';
readonly timeFormat: string = 'h:mm:ss A';
@@ -86,6 +108,8 @@ export class LogsListComponent implements OnInit {
return this.filtering.filtersForm;
}
+ isServiceLogsFileView: boolean = false;
+
isDifferentDates(dateA, dateB): boolean {
return this.utils.isDifferentDates(dateA, dateB, this.timeZone);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
index 69b3887..7e3621a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
@@ -20,5 +20,12 @@
<span class="fa fa-spinner fa-spin"></span>
</div>
<login-form *ngIf="!isInitialLoading && !isAuthorized"></login-form>
+
+<!-- TODO implement tabs: Service Logs/Audit Logs/active file -->
+<div *ngIf="isServiceLogsFileView" class="col-md-12 logs-header">
+ {{activeLogHostName}} >> {{activeLogComponentName}}
+ <span class="fa fa-times close-icon" (click)="closeLog()"></span>
+</div>
+
<filters-panel *ngIf="isAuthorized" class="row"></filters-panel>
<logs-container *ngIf="isAuthorized" logsType="serviceLogs"></logs-container>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
index 9736628..f7dcc05 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.less
@@ -21,4 +21,8 @@
:host {
.full-size;
overflow-x: hidden;
+
+ .close-icon {
+ .clickable-item;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.spec.ts
index 42fba68..bbbebdf 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.spec.ts
@@ -32,6 +32,14 @@ describe('MainContainerComponent', () => {
let fixture: ComponentFixture<MainContainerComponent>;
beforeEach(async(() => {
+ const httpClient = {
+ get: () => {
+ return {
+ subscribe: () => {
+ }
+ }
+ }
+ };
TestBed.configureTestingModule({
declarations: [MainContainerComponent],
imports: [
@@ -47,7 +55,10 @@ describe('MainContainerComponent', () => {
AppStateService,
AuditLogsFieldsService,
ServiceLogsFieldsService,
- HttpClientService
+ {
+ provide: HttpClientService,
+ useValue: httpClient
+ }
]
})
.compileComponents();
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
index 53d58cf..32fe1cf 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.ts
@@ -23,6 +23,7 @@ import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.se
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';
+import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry.class';
@Component({
selector: 'main-container',
@@ -33,8 +34,18 @@ export class MainContainerComponent {
constructor(private httpClient: HttpClientService, private appState: AppStateService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService) {
this.loadColumnsNames();
- appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value);
- appState.getParameter('isInitialLoading').subscribe(value => this.isInitialLoading = value);
+ appState.getParameter('isAuthorized').subscribe((value: boolean) => this.isAuthorized = value);
+ appState.getParameter('isInitialLoading').subscribe((value: boolean) => this.isInitialLoading = value);
+ appState.getParameter('isServiceLogsFileView').subscribe((value: boolean) => this.isServiceLogsFileView = value);
+ appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => {
+ if (value) {
+ this.activeLogHostName = value.host_name;
+ this.activeLogComponentName = value.component_name;
+ } else {
+ this.activeLogHostName = '';
+ this.activeLogComponentName = '';
+ }
+ });
}
@ContentChild(TemplateRef)
@@ -44,6 +55,12 @@ export class MainContainerComponent {
isInitialLoading: boolean = false;
+ isServiceLogsFileView: boolean = false;
+
+ activeLogHostName: string = '';
+
+ activeLogComponentName: string = '';
+
private loadColumnsNames(): void {
this.httpClient.get('serviceLogsFields').subscribe(response => {
const jsonResponse = response.json();
@@ -63,4 +80,11 @@ export class MainContainerComponent {
return Object.keys(keysObject).map(key => new fieldClass(key));
}
+ closeLog(): void {
+ this.appState.setParameters({
+ isServiceLogsFileView: false,
+ activeLog: null
+ });
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
index f92961e..5414f4f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
@@ -30,6 +30,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
@@ -55,7 +56,8 @@ describe('MenuButtonComponent', () => {
auditLogsFields,
serviceLogs,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -70,6 +72,7 @@ describe('MenuButtonComponent', () => {
ServiceLogsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
ComponentActionsService,
FilteringService,
HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
index 7d1e907..7105624 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
@@ -29,6 +29,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud
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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {ComponentActionsService} from '@app/services/component-actions.service';
import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
@@ -60,7 +61,8 @@ describe('TimeZonePickerComponent', () => {
auditLogsFields,
serviceLogs,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
}),
...TranslationModules
],
@@ -75,6 +77,7 @@ describe('TimeZonePickerComponent', () => {
ServiceLogsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
ComponentActionsService,
FilteringService,
HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
index 88b0c91..2dc6278 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
@@ -138,3 +138,33 @@
background-color: #F5F5F5;
}
}
+
+.log-colors {
+ &.fatal {
+ color: @fatal-color;
+ }
+
+ &.error {
+ color: @error-color;
+ }
+
+ &.warn {
+ color: @warning-color;
+ }
+
+ &.info {
+ color: @info-color;
+ }
+
+ &.debug {
+ color: @debug-color;
+ }
+
+ &.trace {
+ color: @trace-color;
+ }
+
+ &.unknown {
+ color: @unknown-color;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
index 28ae763..267bf15 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/app-state.model.ts
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry.class';
+
export interface AppState {
isAuthorized: boolean;
isInitialLoading: boolean;
@@ -23,6 +25,9 @@ export interface AppState {
isAuditLogsSet: boolean;
isServiceLogsSet: boolean;
activeLogsType?: string;
+ isServiceLogsFileView: boolean;
+ isServiceLogContextView: boolean;
+ activeLog: ActiveServiceLogEntry | null;
}
export const initialState: AppState = {
@@ -31,5 +36,8 @@ export const initialState: AppState = {
isLoginInProgress: false,
isAuditLogsSet: false,
isServiceLogsSet: false,
- activeLogsType: 'serviceLogs' // TODO implement setting the parameter depending on user's navigation
+ activeLogsType: 'serviceLogs', // TODO implement setting the parameter depending on user's navigation
+ isServiceLogsFileView: false,
+ isServiceLogContextView: false,
+ activeLog: null
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/models/bar-graph.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/bar-graph.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/bar-graph.model.ts
index a197bf5..6c9a049 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/bar-graph.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/bar-graph.model.ts
@@ -19,6 +19,6 @@
import {CommonEntry} from '@app/models/common-entry.model';
export interface BarGraph {
- dataCount: CommonEntry[],
+ dataCount: CommonEntry[];
name: string;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/models/graph.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/graph.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/graph.model.ts
index 04966b2..be31f19 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/graph.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/graph.model.ts
@@ -19,5 +19,5 @@
export interface Graph {
name: string;
count: string;
- dataList?: Graph[]
+ dataList?: Graph[];
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/models/log.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/log.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/log.model.ts
index 188bbd2..c598e41 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/log.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/log.model.ts
@@ -26,6 +26,7 @@ export interface Log {
case_id?: string;
log_message: string;
logfile_line_number: number;
+ line_number?: number;
message_md5: string;
cluster: string;
event_count: number;
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/models/store.model.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/models/store.model.ts b/ambari-logsearch/ambari-logsearch-web/src/app/models/store.model.ts
index 31d52b3..a6a084f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/models/store.model.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/models/store.model.ts
@@ -32,6 +32,7 @@ import {ServiceLogField} from '@app/models/service-log-field.model';
export const storeActions = {
'ARRAY.ADD': 'ADD',
+ 'ARRAY.ADD.START': 'ADD_TO_START',
'ARRAY.DELETE.PRIMITIVE': 'DELETE_PRIMITIVE',
'ARRAY.DELETE.OBJECT': 'DELETE_OBJECT',
'ARRAY.CLEAR': 'CLEAR',
@@ -46,6 +47,7 @@ export interface AppStore {
auditLogs: AuditLog[];
serviceLogs: ServiceLog[];
serviceLogsHistogramData: BarGraph[];
+ serviceLogsTruncated: ServiceLog[];
graphs: Graph[];
hosts: Node[];
userConfigs: UserConfig[];
@@ -86,6 +88,13 @@ export class CollectionModelService extends ModelService {
});
}
+ addInstancesToStart(instances: any[]): void {
+ this.store.dispatch({
+ type: `${storeActions['ARRAY.ADD.START']}_${this.modelName}`,
+ payload: instances
+ });
+ }
+
deleteObjectInstance(instance: any): void {
this.store.dispatch({
type: `${storeActions['ARRAY.DELETE.OBJECT']}_${this.modelName}`,
@@ -143,6 +152,8 @@ export function getCollectionReducer(modelName: string, defaultState: any = []):
switch (action.type) {
case `${storeActions['ARRAY.ADD']}_${modelName}`:
return [...state, ...action.payload];
+ case `${storeActions['ARRAY.ADD.START']}_${modelName}`:
+ return [...action.payload, ...state];
case `${storeActions['ARRAY.DELETE.OBJECT']}_${modelName}`:
return state.filter(instance => instance.id !== action.payload.id);
case `${storeActions['ARRAY.DELETE.PRIMITIVE']}_${modelName}`:
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
index e737155..3dbd992 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
@@ -19,6 +19,7 @@
import {TestBed, inject} from '@angular/core/testing';
import {StoreModule} from '@ngrx/store';
import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
+import {AppStateService, appState} from '@app/services/storage/app-state.service';
import {ClustersService, clusters} from '@app/services/storage/clusters.service';
import {ComponentsService, components} from '@app/services/storage/components.service';
import {HostsService, hosts} from '@app/services/storage/hosts.service';
@@ -27,6 +28,7 @@ import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-log
import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.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 {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
import {FilteringService} from '@app/services/filtering.service';
import {HttpClientService} from '@app/services/http-client.service';
import {LogsContainerService} from '@app/services/logs-container.service';
@@ -48,6 +50,7 @@ describe('ComponentActionsService', () => {
imports: [
StoreModule.provideStore({
appSettings,
+ appState,
clusters,
components,
hosts,
@@ -55,12 +58,14 @@ describe('ComponentActionsService', () => {
serviceLogs,
auditLogsFields,
serviceLogsFields,
- serviceLogsHistogramData
+ serviceLogsHistogramData,
+ serviceLogsTruncated
})
],
providers: [
ComponentActionsService,
AppSettingsService,
+ AppStateService,
ClustersService,
ComponentsService,
HostsService,
@@ -69,6 +74,7 @@ describe('ComponentActionsService', () => {
AuditLogsFieldsService,
ServiceLogsFieldsService,
ServiceLogsHistogramDataService,
+ ServiceLogsTruncatedService,
FilteringService,
{
provide: HttpClientService,
http://git-wip-us.apache.org/repos/asf/ambari/blob/8852edd2/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
index dba0f8f..b3ff0b0 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
@@ -18,14 +18,16 @@
import {Injectable} from '@angular/core';
import {AppSettingsService} from '@app/services/storage/app-settings.service';
+import {AppStateService} from '@app/services/storage/app-state.service';
import {CollectionModelService} from '@app/models/store.model';
import {FilteringService} from '@app/services/filtering.service';
import {LogsContainerService} from '@app/services/logs-container.service';
+import {ServiceLog} from '@app/models/service-log.model';
@Injectable()
export class ComponentActionsService {
- constructor(private appSettings: AppSettingsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+ constructor(private appSettings: AppSettingsService, private appState: AppStateService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
}
//TODO implement actions
@@ -44,6 +46,52 @@ export class ComponentActionsService {
openHistory() {
}
+ copyLog(log: ServiceLog): void {
+ if (document.queryCommandSupported('copy')) {
+ const text = log.log_message,
+ node = document.createElement('textarea');
+ node.value = text;
+ Object.assign(node.style, {
+ position: 'fixed',
+ top: '0',
+ left: '0',
+ width: '1px',
+ height: '1px',
+ border: 'none',
+ outline: 'none',
+ boxShadow: 'none',
+ backgroundColor: 'transparent',
+ padding: '0'
+ });
+ document.body.appendChild(node);
+ node.select();
+ if (document.queryCommandEnabled('copy')) {
+ document.execCommand('copy');
+ } else {
+ // TODO open failed alert
+ }
+ // TODO success alert
+ document.body.removeChild(node);
+ } else {
+ // TODO failed alert
+ }
+ }
+
+ openLog(log: ServiceLog): void {
+ this.appState.setParameters({
+ isServiceLogsFileView: true,
+ activeLog: {
+ id: log.id,
+ host_name: log.host,
+ component_name: log.type
+ }
+ });
+ }
+
+ openContext(log: ServiceLog): void {
+ this.logsContainer.loadLogContext(log.id, log.host, log.type);
+ }
+
startCapture(): void {
this.filtering.startCaptureTimer();
}