feat(oggui): soporte de múltiples SYSLOG_IDENTIFIER en visor de logs de disco
- StatusLogsComponent: @Input identifiers[] en lugar de identifier string, parseo de entries JSON estructurado con formato [timestamp] ID: mensaje - Templates ogboot, ogdhcp, ogrepository, ogcore-status: identifiers correctos por componente y host basado en IP en lugar de nombre del servidor - Añadidos métodos getSelectedXxxIp() en ogboot, ogdhcp y ogrepository statuspull/93/head^2
parent
59067ee94c
commit
647fa5079e
|
|
@ -45,8 +45,8 @@
|
|||
<div id="ogboot-logs-section">
|
||||
<app-status-logs
|
||||
[title]="'ogbootLogs'"
|
||||
[identifier]="'ogboot'"
|
||||
[host]="getSelectedBootServerName()"
|
||||
[identifiers]="['ogboot', 'tftpd-hpa']"
|
||||
[host]="getSelectedBootServerIp()"
|
||||
[oglogUrl]="getBootServerIframeUrl()">
|
||||
</app-status-logs>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -101,6 +101,11 @@ export class GlobalOgbootStatusComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
getSelectedBootServerIp(): string {
|
||||
const s = this.bootServers.find(s => s.uuid === this.selectedBootServerUuid);
|
||||
return s ? s.ip : '';
|
||||
}
|
||||
|
||||
getSelectedBootServerName(): string {
|
||||
const selectedBootServer = this.bootServers.find(server => server.uuid === this.selectedBootServerUuid);
|
||||
return selectedBootServer ? selectedBootServer.name : '';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div id="ogcore-logs-section">
|
||||
<app-status-logs
|
||||
[title]="'ogcoreLogs'"
|
||||
[identifier]="'ogcore'"
|
||||
[identifiers]="['ogcore']"
|
||||
[host]="''"
|
||||
[oglogUrl]="getOgCoreIframeUrl()">
|
||||
</app-status-logs>
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
<div id="dhcp-logs-section">
|
||||
<app-status-logs
|
||||
[title]="'dhcpLogs'"
|
||||
[identifier]="'ogdhcp'"
|
||||
[host]="getSelectedDhcpName()"
|
||||
[identifiers]="['ogdhcp', 'kea-dhcp4', 'kea-ctrl-agent', 'DhcpLFC']"
|
||||
[host]="getSelectedDhcpIp()"
|
||||
[oglogUrl]="getDhcpIframeUrl()">
|
||||
</app-status-logs>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -104,6 +104,11 @@ export class OgdhcpStatusComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
getSelectedDhcpIp(): string {
|
||||
const d = this.dhcps.find(d => d.uuid === this.selectedDhcpUuid);
|
||||
return d ? d.ip : '';
|
||||
}
|
||||
|
||||
getSelectedDhcpName(): string {
|
||||
const selectedDhcp = this.dhcps.find(dhcp => dhcp.uuid === this.selectedDhcpUuid);
|
||||
return selectedDhcp ? selectedDhcp.name : '';
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@
|
|||
<div id="repository-logs-section">
|
||||
<app-status-logs
|
||||
[title]="'ogrepositoryLogs'"
|
||||
[identifier]="'ogrepo-api'"
|
||||
[host]="getSelectedRepositoryName()"
|
||||
[identifiers]="['ogrepo-api', 'ogrepo-api_DEBUG', '(smbd)', '(nmbd)']"
|
||||
[host]="getSelectedRepositoryIp()"
|
||||
[oglogUrl]="getRepositoryIframeUrl()">
|
||||
</app-status-logs>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -103,6 +103,11 @@ export class OgrepositoryStatusComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
getSelectedRepositoryIp(): string {
|
||||
const r = this.repositories.find(r => r.uuid === this.selectedRepositoryUuid);
|
||||
return r ? r.ip : '';
|
||||
}
|
||||
|
||||
getSelectedRepositoryName(): string {
|
||||
const selectedRepo = this.repositories.find(repo => repo.uuid === this.selectedRepositoryUuid);
|
||||
return selectedRepo ? selectedRepo.name : '';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@ import { ConfigService } from '@services/config.service';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatTabChangeEvent } from '@angular/material/tabs';
|
||||
|
||||
interface JournalEntry {
|
||||
MESSAGE: string;
|
||||
SYSLOG_IDENTIFIER?: string;
|
||||
_HOSTNAME?: string;
|
||||
__REALTIME_TIMESTAMP?: string;
|
||||
PRIORITY?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-logs',
|
||||
templateUrl: './status-logs.component.html',
|
||||
|
|
@ -12,7 +20,7 @@ import { MatTabChangeEvent } from '@angular/material/tabs';
|
|||
})
|
||||
export class StatusLogsComponent implements OnInit, OnDestroy, AfterViewChecked {
|
||||
@ViewChild('logContent') private logContainer!: ElementRef;
|
||||
@Input() identifier: string = '';
|
||||
@Input() identifiers: string[] = [];
|
||||
@Input() host: string = '';
|
||||
@Input() oglogUrl: SafeResourceUrl | null = null;
|
||||
@Input() title: string = '';
|
||||
|
|
@ -53,12 +61,12 @@ export class StatusLogsComponent implements OnInit, OnDestroy, AfterViewChecked
|
|||
}
|
||||
|
||||
onTabChange(event: MatTabChangeEvent): void {
|
||||
if (event.index === 0) { // Disk Logs tab
|
||||
if (event.index === 0) {
|
||||
if (this.isLive) {
|
||||
this.loadDiskLogs();
|
||||
this.startPolling();
|
||||
}
|
||||
} else { // oglog Logs tab or others
|
||||
} else {
|
||||
this.stopPolling();
|
||||
}
|
||||
}
|
||||
|
|
@ -68,27 +76,39 @@ export class StatusLogsComponent implements OnInit, OnDestroy, AfterViewChecked
|
|||
}
|
||||
|
||||
loadDiskLogs(): void {
|
||||
if (!this.identifier) return;
|
||||
if (!this.identifiers.length) return;
|
||||
|
||||
if (!this.isLive) {
|
||||
this.loadingDiskLogs = true;
|
||||
}
|
||||
|
||||
const url = `${this.configService.apiUrl}/opengnsys/system/disk-logs?SYSLOG_IDENTIFIER=${this.identifier}&host=${this.host}&lines=200`;
|
||||
|
||||
this.http.get<{ content: string }>(url).subscribe({
|
||||
const idParam = this.identifiers.join(',');
|
||||
const hostParam = this.host ? `&host=${encodeURIComponent(this.host)}` : '';
|
||||
const url = `${this.configService.apiUrl}/opengnsys/system/disk-logs?SYSLOG_IDENTIFIER=${encodeURIComponent(idParam)}${hostParam}&lines=200`;
|
||||
|
||||
this.http.get<{ entries: JournalEntry[] }>(url).subscribe({
|
||||
next: (response) => {
|
||||
this.diskLogsContent = response.content || '';
|
||||
this.diskLogsContent = this.formatEntries(response.entries || []);
|
||||
this.loadingDiskLogs = false;
|
||||
this.errorDiskLogs = null;
|
||||
},
|
||||
error: (err) => {
|
||||
error: () => {
|
||||
this.errorDiskLogs = 'Error al cargar logs de disco';
|
||||
this.loadingDiskLogs = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private formatEntries(entries: JournalEntry[]): string {
|
||||
return entries.map(entry => {
|
||||
const ts = entry.__REALTIME_TIMESTAMP
|
||||
? new Date(parseInt(entry.__REALTIME_TIMESTAMP, 10) / 1000).toISOString().replace('T', ' ').substring(0, 23)
|
||||
: ' ';
|
||||
const id = entry.SYSLOG_IDENTIFIER ?? '';
|
||||
return `[${ts}] ${id}: ${entry.MESSAGE ?? ''}`;
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
private startPolling(): void {
|
||||
this.stopPolling();
|
||||
this.pollInterval = setInterval(() => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue