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