feat(logs): replace API polling with WebSocket for real-time updates
Implement WebSocket connection to receive live log updates instead of periodic API polling. The changes include: - Add WebSocket connection management with token authentication - Implement computed property for log filtering - Maintain only the latest 100 logs in memory - Handle WebSocket events and errors appropriately
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<div class="page-header">
|
||||
<h2>System Logs</h2>
|
||||
<div class="filter-controls">
|
||||
<select v-model="selectedLevel" @change="loadLogs">
|
||||
<select v-model="selectedLevel" @change="filterLogs">
|
||||
<option value="">All Levels</option>
|
||||
<option value="DEBUG">DEBUG</option>
|
||||
<option value="INFO">INFO</option>
|
||||
@@ -14,8 +14,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="logs-container">
|
||||
<div v-if="logs.length > 0" class="log-list">
|
||||
<div v-for="(log, index) in logs" :key="index" class="log-item">
|
||||
<div v-if="filteredLogs.length > 0" class="log-list">
|
||||
<div v-for="(log, index) in filteredLogs" :key="index" class="log-item">
|
||||
<span class="log-time">{{ log.time }}</span>
|
||||
<span :class="['log-level', log.level]">{{ log.level }}</span>
|
||||
<span class="log-message">{{ log.message }}</span>
|
||||
@@ -29,37 +29,93 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { logApi } from '../api/index.js';
|
||||
import { showNotification, formatDate } from '../utils/functions.js';
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import { showNotification, formatDate, getCookie } from '../utils/functions.js';
|
||||
|
||||
export default {
|
||||
name: 'Logs',
|
||||
setup() {
|
||||
const logs = ref([]);
|
||||
const selectedLevel = ref('');
|
||||
const socket = ref(null);
|
||||
|
||||
const loadLogs = async () => {
|
||||
try {
|
||||
const result = await logApi.getLogs(selectedLevel.value);
|
||||
logs.value = result.data.map(log => ({
|
||||
time: formatDate(log.timestamp),
|
||||
level: log.level,
|
||||
message: log.message
|
||||
}));
|
||||
} catch (error) {
|
||||
showNotification('Failed to load logs', 'error');
|
||||
const levelMap = {
|
||||
0: 'DEBUG',
|
||||
1: 'INFO',
|
||||
2: 'WARN',
|
||||
3: 'ERROR',
|
||||
4: 'FATAL'
|
||||
};
|
||||
|
||||
const filteredLogs = computed(() => {
|
||||
if (!selectedLevel.value) {
|
||||
return logs.value;
|
||||
}
|
||||
return logs.value.filter(log => log.level === selectedLevel.value);
|
||||
});
|
||||
|
||||
const filterLogs = () => {
|
||||
// Filtering is handled by computed property
|
||||
};
|
||||
|
||||
const connectWebSocket = () => {
|
||||
const token = getCookie('token');
|
||||
const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsUrl = `${wsProtocol}//localhost:8080/system/getLogs?token=${token}`;
|
||||
|
||||
socket.value = new WebSocket(wsUrl);
|
||||
|
||||
socket.value.onopen = () => {
|
||||
console.log('Connected to log server');
|
||||
};
|
||||
|
||||
socket.value.onmessage = (event) => {
|
||||
try {
|
||||
const log = JSON.parse(event.data);
|
||||
logs.value.push({
|
||||
time: log.timestamp,
|
||||
level: levelMap[log.level],
|
||||
message: log.content
|
||||
});
|
||||
// Keep only the latest 100 logs
|
||||
if (logs.value.length > 100) {
|
||||
logs.value.shift();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing log message:', error);
|
||||
}
|
||||
};
|
||||
|
||||
socket.value.onclose = () => {
|
||||
console.log('Disconnected from log server');
|
||||
};
|
||||
|
||||
socket.value.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
showNotification('Failed to connect to log server', 'error');
|
||||
};
|
||||
};
|
||||
|
||||
const disconnectWebSocket = () => {
|
||||
if (socket.value) {
|
||||
socket.value.close();
|
||||
socket.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadLogs();
|
||||
connectWebSocket();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
disconnectWebSocket();
|
||||
});
|
||||
|
||||
return {
|
||||
logs,
|
||||
filteredLogs,
|
||||
selectedLevel,
|
||||
loadLogs
|
||||
filterLogs
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user