From 8060962b8a0cb4863f7d36d257f0e4ef7d702187 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Wed, 6 May 2026 23:41:56 +0200 Subject: [PATCH] Added polling into disk logs --- .../client-disk-logs-modal.component.css | 28 ++++++++++ .../client-disk-logs-modal.component.html | 13 ++++- .../client-disk-logs-modal.component.ts | 56 +++++++++++++++++-- ogWebconsole/src/locale/en.json | 2 + ogWebconsole/src/locale/es.json | 2 + 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.css b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.css index 974fbb6..637a776 100644 --- a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.css +++ b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.css @@ -95,6 +95,34 @@ word-break: break-all; } +.live-badge { + display: inline-flex; + align-items: center; + gap: 5px; + margin-left: 10px; + padding: 2px 8px; + background-color: #d32f2f; + color: #fff; + border-radius: 4px; + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.05em; + vertical-align: middle; +} + +.live-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background-color: #fff; + animation: blink 1s step-start infinite; +} + +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + .modal-actions { padding: 16px 24px; border-top: 1px solid #e0e0e0; diff --git a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.html b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.html index d1288db..30489d8 100644 --- a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.html +++ b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.html @@ -3,9 +3,18 @@

storage {{ 'diskLogs' | translate }} - {{ data.client.name }} + + LIVE +

- +
@@ -27,7 +36,7 @@ {{ error }} -
{{ content || ('noLogsAvailable' | translate) }}
+
{{ content || ('noLogsAvailable' | translate) }}
diff --git a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.ts b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.ts index 884adaf..aa1f5bb 100644 --- a/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.ts +++ b/ogWebconsole/src/app/components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit, OnDestroy } from '@angular/core'; +import { Component, Inject, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { HttpClient } from '@angular/common/http'; import { ConfigService } from '@services/config.service'; @@ -12,7 +12,14 @@ export class ClientDiskLogsModalComponent implements OnInit, OnDestroy { content: string = ''; loading: boolean = false; error: string | null = null; + isLive: boolean = false; + private apiUrl: string; + private pollInterval: ReturnType | null = null; + private readonly POLL_INTERVAL_MS = 3000; + private readonly LIVE_LINES = 200; + + @ViewChild('logContent') logContent!: ElementRef; constructor( public dialogRef: MatDialogRef, @@ -27,26 +34,67 @@ export class ClientDiskLogsModalComponent implements OnInit, OnDestroy { this.loadLogs(); } - ngOnDestroy(): void {} + ngOnDestroy(): void { + this.stopLive(); + } - loadLogs(): void { + loadLogs(lines: number = 0): void { this.loading = true; this.error = null; - this.http.get<{ content: string }>(`${this.apiUrl}/clients/${this.data.client.uuid}/disk-logs`).subscribe({ + const url = lines > 0 + ? `${this.apiUrl}/clients/${this.data.client.uuid}/disk-logs?lines=${lines}` + : `${this.apiUrl}/clients/${this.data.client.uuid}/disk-logs`; + + this.http.get<{ content: string }>(url).subscribe({ next: (response) => { this.content = response.content || ''; this.loading = false; + if (this.isLive) { + this.scrollToBottom(); + } }, error: (err) => { this.error = err.status === 404 ? 'No se encontró el archivo de logs para este cliente.' : 'Error al obtener los logs de disco.'; this.loading = false; + this.stopLive(); } }); } + toggleLive(): void { + if (this.isLive) { + this.stopLive(); + } else { + this.startLive(); + } + } + + private startLive(): void { + this.isLive = true; + this.loadLogs(this.LIVE_LINES); + this.pollInterval = setInterval(() => this.loadLogs(this.LIVE_LINES), this.POLL_INTERVAL_MS); + } + + private stopLive(): void { + this.isLive = false; + if (this.pollInterval !== null) { + clearInterval(this.pollInterval); + this.pollInterval = null; + } + } + + private scrollToBottom(): void { + setTimeout(() => { + const el = this.logContent?.nativeElement; + if (el) { + el.scrollTop = el.scrollHeight; + } + }, 50); + } + closeModal(): void { this.dialogRef.close(); } diff --git a/ogWebconsole/src/locale/en.json b/ogWebconsole/src/locale/en.json index 3857c4a..1b8ebe1 100644 --- a/ogWebconsole/src/locale/en.json +++ b/ogWebconsole/src/locale/en.json @@ -232,6 +232,8 @@ "clientListPartition": "List of clients where partitioning will be performed", "clientLogs": "Client Logs", "diskLogs": "Disk Logs", + "diskLogsStartLive": "Enable real-time mode", + "diskLogsStopLive": "Stop real-time mode", "clientMacOS": "MacOS client", "clientOff": "Client off", "clientOgLive": "OGLive client", diff --git a/ogWebconsole/src/locale/es.json b/ogWebconsole/src/locale/es.json index c1dce8f..47a8e3c 100644 --- a/ogWebconsole/src/locale/es.json +++ b/ogWebconsole/src/locale/es.json @@ -232,6 +232,8 @@ "clientListPartition": "Listado de clientes donde se realizará el particionado", "clientLogs": "Logs de cliente", "diskLogs": "Logs de disco", + "diskLogsStartLive": "Activar modo en tiempo real", + "diskLogsStopLive": "Detener modo en tiempo real", "clientMacOS": "Cliente MacOS", "clientOff": "Cliente apagado", "clientOgLive": "Cliente OGLive", -- 2.40.1