File size: 3,926 Bytes
eb846d0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
import { useEffect, useState } from 'react';
import { getToken } from './authService'; // Import getToken function
import { getApiUrl } from '../utils/runtime';
export interface LogEntry {
timestamp: number;
type: 'info' | 'error' | 'warn' | 'debug';
source: string;
message: string;
processId?: string;
}
// Fetch all logs
export const fetchLogs = async (): Promise<LogEntry[]> => {
try {
// Get authentication token
const token = getToken();
if (!token) {
throw new Error('Authentication token not found. Please log in.');
}
const response = await fetch(getApiUrl('/logs'), {
headers: {
'x-auth-token': token,
},
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error || 'Failed to fetch logs');
}
return result.data;
} catch (error) {
console.error('Error fetching logs:', error);
throw error;
}
};
// Clear all logs
export const clearLogs = async (): Promise<void> => {
try {
// Get authentication token
const token = getToken();
if (!token) {
throw new Error('Authentication token not found. Please log in.');
}
const response = await fetch(getApiUrl('/logs'), {
method: 'DELETE',
headers: {
'x-auth-token': token,
},
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error || 'Failed to clear logs');
}
} catch (error) {
console.error('Error clearing logs:', error);
throw error;
}
};
// Hook to use logs with SSE streaming
export const useLogs = () => {
const [logs, setLogs] = useState<LogEntry[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
let eventSource: EventSource | null = null;
let isMounted = true;
const connectToLogStream = () => {
try {
// Close existing connection if any
if (eventSource) {
eventSource.close();
}
// Get the authentication token
const token = getToken();
if (!token) {
setError(new Error('Authentication token not found. Please log in.'));
setLoading(false);
return;
}
// Connect to SSE endpoint with auth token in URL
eventSource = new EventSource(getApiUrl(`/logs/stream?token=${token}`));
eventSource.onmessage = (event) => {
if (!isMounted) return;
try {
const data = JSON.parse(event.data);
if (data.type === 'initial') {
setLogs(data.logs);
setLoading(false);
} else if (data.type === 'log') {
setLogs((prevLogs) => [...prevLogs, data.log]);
}
} catch (err) {
console.error('Error parsing SSE message:', err);
}
};
eventSource.onerror = () => {
if (!isMounted) return;
if (eventSource) {
eventSource.close();
// Attempt to reconnect after a delay
setTimeout(connectToLogStream, 5000);
}
setError(new Error('Connection to log stream lost, attempting to reconnect...'));
};
} catch (err) {
if (!isMounted) return;
setError(err instanceof Error ? err : new Error('Failed to connect to log stream'));
setLoading(false);
}
};
// Initial connection
connectToLogStream();
// Cleanup on unmount
return () => {
isMounted = false;
if (eventSource) {
eventSource.close();
}
};
}, []);
const clearAllLogs = async () => {
try {
await clearLogs();
setLogs([]);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to clear logs'));
}
};
return { logs, loading, error, clearLogs: clearAllLogs };
};
|