File
Implements
Metadata
selector |
cd-logs |
styleUrls |
./logs.component.scss |
templateUrl |
./logs.component.html |
Methods
abstractfilters
|
abstractfilters()
|
|
|
clearSearchKey
|
clearSearchKey()
|
|
|
filterExecutor
|
filterExecutor(logs: Array, filters: any)
|
|
Parameters :
Name |
Type |
Optional |
logs |
Array<any>
|
No
|
filters |
any
|
No
|
Returns : Array<any>
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
audit_log
|
Type : Array<any>
|
|
bsConfig
|
Type : object
|
Default value : {
dateInputFormat: 'YYYY-MM-DD',
containerClass: 'theme-default'
}
|
|
endTime
|
Type : Date
|
Default value : new Date()
|
|
priority
|
Type : string
|
Default value : 'All'
|
|
prioritys
|
Type : Array<literal type>
|
Default value : [
{ name: 'Info', value: '[INF]' },
{ name: 'Warning', value: '[WRN]' },
{ name: 'Error', value: '[ERR]' },
{ name: 'All', value: 'All' }
]
|
|
search
|
Type : string
|
Default value : ''
|
|
startTime
|
Type : Date
|
Default value : new Date()
|
|
import { Component, OnDestroy, OnInit } from '@angular/core';
import { LogsService } from '../../../shared/api/logs.service';
@Component({
selector: 'cd-logs',
templateUrl: './logs.component.html',
styleUrls: ['./logs.component.scss']
})
export class LogsComponent implements OnInit, OnDestroy {
contentData: any;
clog: Array<any>;
audit_log: Array<any>;
interval: number;
bsConfig = {
dateInputFormat: 'YYYY-MM-DD',
containerClass: 'theme-default'
};
prioritys: Array<{ name: string; value: string }> = [
{ name: 'Info', value: '[INF]' },
{ name: 'Warning', value: '[WRN]' },
{ name: 'Error', value: '[ERR]' },
{ name: 'All', value: 'All' }
];
priority = 'All';
search = '';
selectedDate: Date;
startTime: Date = new Date();
endTime: Date = new Date();
constructor(private logsService: LogsService) {
this.startTime.setHours(0, 0);
this.endTime.setHours(23, 59);
}
ngOnInit() {
this.getInfo();
this.interval = window.setInterval(() => {
this.getInfo();
}, 5000);
}
ngOnDestroy() {
clearInterval(this.interval);
}
getInfo() {
this.logsService.getLogs().subscribe((data: any) => {
this.contentData = data;
this.filterLogs();
});
}
abstractfilters(): any {
const priority = this.priority;
const key = this.search.toLowerCase().replace(/,/g, '');
let yearMonthDay: string;
if (this.selectedDate) {
const m = this.selectedDate.getMonth() + 1;
const d = this.selectedDate.getDate();
const year = this.selectedDate.getFullYear().toString();
const month = m <= 9 ? `0${m}` : `${m}`;
const day = d <= 9 ? `0${d}` : `${d}`;
yearMonthDay = `${year}-${month}-${day}`;
} else {
yearMonthDay = '';
}
const sHour = this.startTime ? this.startTime.getHours() : 0;
const sMinutes = this.startTime ? this.startTime.getMinutes() : 0;
const sTime = sHour * 60 + sMinutes;
const eHour = this.endTime ? this.endTime.getHours() : 23;
const eMinutes = this.endTime ? this.endTime.getMinutes() : 59;
const eTime = eHour * 60 + eMinutes;
return { priority, key, yearMonthDay, sTime, eTime };
}
filterExecutor(logs: Array<any>, filters: any): Array<any> {
return logs.filter((line) => {
const hour = parseInt(line.stamp.slice(11, 13), 10);
const minutes = parseInt(line.stamp.slice(14, 16), 10);
let prio: string, y_m_d: string, timeSpan: number;
prio = filters.priority === 'All' ? line.priority : filters.priority;
y_m_d = filters.yearMonthDay ? filters.yearMonthDay : line.stamp;
timeSpan = hour * 60 + minutes;
return (
line.priority === prio &&
line.message.toLowerCase().indexOf(filters.key) !== -1 &&
line.stamp.indexOf(y_m_d) !== -1 &&
timeSpan >= filters.sTime &&
timeSpan <= filters.eTime
);
});
}
filterLogs() {
const filters = this.abstractfilters();
this.clog = this.filterExecutor(this.contentData.clog, filters);
this.audit_log = this.filterExecutor(this.contentData.audit_log, filters);
}
clearSearchKey() {
this.search = '';
this.filterLogs();
}
clearDate() {
this.selectedDate = null;
this.filterLogs();
}
}
<div *ngIf="contentData">
<ng-container *ngTemplateOutlet="logFiltersTpl"></ng-container>
<tabset>
<tab i18n-heading
heading="Cluster Logs">
<div class="well">
<div *ngIf="clog">
<p *ngFor="let line of clog">
<span class="timestamp">{{ line.stamp }}</span>
<span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
<span class="message">{{ line.message }}</span>
</p>
</div>
<div *ngIf="contentData.clog.length === 0">
<p i18n>No entries found</p>
</div>
</div>
</tab>
<tab i18n-heading
heading="Audit Logs">
<div class="well">
<div *ngIf="audit_log">
<p *ngFor="let line of audit_log">
<span class="timestamp">{{ line.stamp }}</span>
<span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
<span class="message">{{ line.message }}</span>
</p>
</div>
<div *ngIf="contentData.audit_log.length === 0">
<p i18n>No entries found</p>
</div>
</div>
</tab>
</tabset>
</div>
<ng-template #logFiltersTpl>
<div class="row log-filters">
<div class="col-xs-4 col-md-2 cd-col-1 filter-box">
<label i18n>Priority:</label>
<select class="form-control"
[(ngModel)]="priority"
(ngModelChange)="filterLogs()">
<option class="form-control"
*ngFor="let prio of prioritys"
[value]="prio.value">{{ prio.name }}</option>
</select>
</div>
<div class="col-xs-4 col-md-3 cd-col-3 filter-box">
<label i18n>Keyword:</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-search"></i>
</span>
<input class="form-control"
type="text"
[(ngModel)]="search"
(keyup)="filterLogs()">
<span class="input-group-btn">
<button type="button"
class="btn btn-default clear-input tc_clearInputBtn"
(click)="clearSearchKey()">
<i class="icon-prepend fa fa-remove"></i>
</button>
</span>
</div>
</div>
<div class="col-xs-4 col-md-3 cd-col-2 filter-box">
<label i18n>Date:</label>
<div class="input-group">
<input type="text"
class="form-control"
i18n-placeholder
placeholder="Datepicker"
[bsConfig]="bsConfig"
bsDatepicker
[(ngModel)]="selectedDate"
(ngModelChange)="filterLogs()">
<span class="input-group-btn">
<button type="button"
class="btn btn-default clear-input tc_clearInputBtn"
(click)="clearDate()">
<i class="icon-prepend fa fa-remove"></i>
</button>
</span>
</div>
</div>
<div class="clearfix visible-xs-block"></div>
<div class="col-xs-8 col-md-4 cd-col-4 filter-box time-box">
<label i18n>Time range:</label>
<timepicker [showMeridian]="false"
[showSpinners]="showSpinners"
[minuteStep]="1"
[(ngModel)]="startTime"
(ngModelChange)="filterLogs()">
</timepicker>
<span> — </span>
<timepicker [showMeridian]="false"
[showSpinners]="showSpinners"
[minuteStep]="1"
[(ngModel)]="endTime"
(ngModelChange)="filterLogs()">
</timepicker>
</div>
</div>
</ng-template>
@import '../../../../defaults';
p {
font-family: monospace;
color: black;
}
.well {
div p {
display: flex;
&:last-child {
margin-bottom: 0;
}
}
.timestamp {
font-weight: bold;
flex-shrink: 0;
}
.priority {
margin-left: 0.5rem;
}
.message {
margin-left: 1rem;
}
.err {
color: $color-pink;
}
.warn {
color: $color-bright-yellow;
}
.info {
color: $color-brand-teal;
}
}
::ng-deep timepicker table tbody tr td {
.bs-timepicker-field {
width: 3.5rem;
font-size: 1rem;
padding: 4px 6px;
}
.btn {
font-size: 1rem;
}
}
.log-filters {
margin-bottom: 5px;
padding: 0 30px;
* {
box-sizing: border-box;
}
.filter-box {
margin: 0;
padding: 0 15px 5px 0;
display: -webkit-flex;
display: flex;
justify-content: flex-start;
align-items: center;
label {
padding-top: 5px;
padding-right: 5px;
}
}
@media (max-width: 991px) {
.time-box {
margin-top: 20px;
}
}
@media (min-width: 1200px) {
.cd-col-4 {
width: 28vw;
}
.cd-col-3 {
width: 20vw;
}
.cd-col-2 {
width: 16vw;
}
.cd-col-1 {
width: 14vw;
}
}
@media (min-width: 1400px) {
.cd-col-4 {
width: 24vw;
}
.cd-col-3 {
width: 18vw;
}
.cd-col-2 {
width: 14vw;
}
.cd-col-1 {
width: 12vw;
}
}
@media (min-width: 1600px) {
.cd-col-4 {
width: 22vw;
}
.cd-col-3 {
width: 16vw;
}
.cd-col-2 {
width: 12vw;
}
.cd-col-1 {
width: 10vw;
}
}
@media (min-width: 1800px) {
.cd-col-3 {
width: 14vw;
}
.cd-col-2 {
width: 11vw;
}
.cd-col-1 {
width: 9vw;
}
}
}
Legend
Html element with directive