]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/logs/logs.component.ts
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cluster / logs / logs.component.ts
1 import { DatePipe } from '@angular/common';
2 import { Component, Input, NgZone, OnDestroy, OnInit } from '@angular/core';
3
4 import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
5 import { Observable } from 'rxjs';
6 import { map } from 'rxjs/operators';
7
8 import { CephServiceService } from '~/app/shared/api/ceph-service.service';
9 import { LogsService } from '~/app/shared/api/logs.service';
10 import { Icons } from '~/app/shared/enum/icons.enum';
11
12 @Component({
13 selector: 'cd-logs',
14 templateUrl: './logs.component.html',
15 styleUrls: ['./logs.component.scss']
16 })
17 export class LogsComponent implements OnInit, OnDestroy {
18 @Input()
19 showClusterLogs = true;
20 @Input()
21 showAuditLogs = true;
22 @Input()
23 showDaemonLogs = true;
24 @Input()
25 showNavLinks = true;
26 @Input()
27 showFilterTools = true;
28 @Input()
29 showDownloadCopyButton = true;
30 @Input()
31 defaultTab = '';
32 @Input()
33 scrollable = false;
34
35 contentData: any;
36 clog: Array<any>;
37 audit_log: Array<any>;
38 icons = Icons;
39 clogText: string;
40 auditLogText: string;
41 lokiServiceStatus$: Observable<boolean>;
42 promtailServiceStatus$: Observable<boolean>;
43
44 interval: number;
45 priorities: Array<{ name: string; value: string }> = [
46 { name: 'Debug', value: '[DBG]' },
47 { name: 'Info', value: '[INF]' },
48 { name: 'Warning', value: '[WRN]' },
49 { name: 'Error', value: '[ERR]' },
50 { name: 'All', value: 'All' }
51 ];
52 priority = 'All';
53 search = '';
54 selectedDate: NgbDateStruct;
55 startTime = { hour: 0, minute: 0 };
56 endTime = { hour: 23, minute: 59 };
57 maxDate = {
58 year: new Date().getFullYear(),
59 month: new Date().getMonth() + 1,
60 day: new Date().getDate()
61 };
62
63 constructor(
64 private logsService: LogsService,
65 private cephService: CephServiceService,
66 private datePipe: DatePipe,
67 private ngZone: NgZone
68 ) {}
69
70 ngOnInit() {
71 this.getInfo();
72 this.ngZone.runOutsideAngular(() => {
73 this.getDaemonDetails();
74 this.interval = window.setInterval(() => {
75 this.ngZone.run(() => {
76 this.getInfo();
77 });
78 }, 5000);
79 });
80 }
81
82 ngOnDestroy() {
83 clearInterval(this.interval);
84 }
85
86 getDaemonDetails() {
87 this.lokiServiceStatus$ = this.cephService.getDaemons('loki').pipe(
88 map((data: any) => {
89 return data.length > 0 && data[0].status === 1;
90 })
91 );
92 this.promtailServiceStatus$ = this.cephService.getDaemons('promtail').pipe(
93 map((data: any) => {
94 return data.length > 0 && data[0].status === 1;
95 })
96 );
97 }
98
99 getInfo() {
100 this.logsService.getLogs().subscribe((data: any) => {
101 this.contentData = data;
102 this.clogText = this.logToText(this.contentData.clog);
103 this.auditLogText = this.logToText(this.contentData.audit_log);
104 this.filterLogs();
105 });
106 }
107
108 abstractFilters(): any {
109 const priority = this.priority;
110 const key = this.search.toLowerCase();
111 let yearMonthDay: string;
112 if (this.selectedDate) {
113 const m = this.selectedDate.month;
114 const d = this.selectedDate.day;
115
116 const year = this.selectedDate.year;
117 const month = m <= 9 ? `0${m}` : `${m}`;
118 const day = d <= 9 ? `0${d}` : `${d}`;
119 yearMonthDay = `${year}-${month}-${day}`;
120 } else {
121 yearMonthDay = '';
122 }
123
124 const sHour = this.startTime?.hour ?? 0;
125 const sMinutes = this.startTime?.minute ?? 0;
126 const sTime = sHour * 60 + sMinutes;
127
128 const eHour = this.endTime?.hour ?? 23;
129 const eMinutes = this.endTime?.minute ?? 59;
130 const eTime = eHour * 60 + eMinutes;
131
132 return { priority, key, yearMonthDay, sTime, eTime };
133 }
134
135 filterExecutor(logs: Array<any>, filters: any): Array<any> {
136 return logs.filter((line) => {
137 const localDate = this.datePipe.transform(line.stamp, 'mediumTime');
138 const hour = parseInt(localDate.split(':')[0], 10);
139 const minutes = parseInt(localDate.split(':')[1], 10);
140 let prio: string, y_m_d: string, timeSpan: number;
141
142 prio = filters.priority === 'All' ? line.priority : filters.priority;
143 y_m_d = filters.yearMonthDay ? filters.yearMonthDay : line.stamp;
144 timeSpan = hour * 60 + minutes;
145 return (
146 line.priority === prio &&
147 line.message.toLowerCase().indexOf(filters.key) !== -1 &&
148 line.stamp.indexOf(y_m_d) !== -1 &&
149 timeSpan >= filters.sTime &&
150 timeSpan <= filters.eTime
151 );
152 });
153 }
154
155 filterLogs() {
156 const filters = this.abstractFilters();
157 this.clog = this.filterExecutor(this.contentData.clog, filters);
158 this.audit_log = this.filterExecutor(this.contentData.audit_log, filters);
159 }
160
161 clearSearchKey() {
162 this.search = '';
163 this.filterLogs();
164 }
165 clearDate() {
166 this.selectedDate = null;
167 this.filterLogs();
168 }
169 resetFilter() {
170 this.priority = 'All';
171 this.search = '';
172 this.selectedDate = null;
173 this.startTime = { hour: 0, minute: 0 };
174 this.endTime = { hour: 23, minute: 59 };
175 this.filterLogs();
176
177 return false;
178 }
179
180 logToText(log: object) {
181 let logText = '';
182 for (const line of Object.keys(log)) {
183 logText =
184 logText +
185 this.datePipe.transform(log[line].stamp, 'medium') +
186 '\t' +
187 log[line].priority +
188 '\t' +
189 log[line].message +
190 '\n';
191 }
192 return logText;
193 }
194 }