|
export default class Logger {
|
|
constructor(config = {}) {
|
|
this.levels = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
this.currentLevel = config.level || 'info';
|
|
this.maxLogs = config.maxLogs || 100;
|
|
this.enableRemote = config.enableRemote || false;
|
|
this.remoteEndpoint = config.remoteEndpoint || '/api/logs';
|
|
this._setupGlobalHandlers();
|
|
}
|
|
|
|
log(level, message, data = null) {
|
|
const levelIndex = this.levels[level];
|
|
const currentIndex = this.levels[this.currentLevel];
|
|
|
|
if (levelIndex < currentIndex) return;
|
|
|
|
const timestamp = new Date().toISOString();
|
|
const entry = {
|
|
timestamp,
|
|
level,
|
|
message,
|
|
data,
|
|
url: window.location.href,
|
|
userAgent: navigator.userAgent
|
|
};
|
|
|
|
this._console(level, message, data);
|
|
this._persistLog(entry);
|
|
|
|
if (this.enableRemote && level === 'error') {
|
|
this._sendRemote(entry);
|
|
}
|
|
}
|
|
|
|
debug(message, data) { this.log('debug', message, data); }
|
|
info(message, data) { this.log('info', message, data); }
|
|
warn(message, data) { this.log('warn', message, data); }
|
|
error(message, data) { this.log('error', message, data); }
|
|
|
|
_console(level, message, data) {
|
|
const logFn = console[level] || console.log;
|
|
const timestamp = new Date().toISOString();
|
|
const prefix = `[${timestamp}] [${level.toUpperCase()}]`;
|
|
logFn(`${prefix} ${message}`, data || '');
|
|
}
|
|
|
|
_persistLog(entry) {
|
|
if (typeof localStorage === 'undefined') return;
|
|
|
|
try {
|
|
const logs = JSON.parse(localStorage.getItem('app_logs') || '[]');
|
|
logs.push(entry);
|
|
|
|
if (logs.length > this.maxLogs) {
|
|
logs.splice(0, logs.length - this.maxLogs);
|
|
}
|
|
|
|
localStorage.setItem('app_logs', JSON.stringify(logs));
|
|
} catch (err) {
|
|
console.error('Failed to persist log:', err);
|
|
}
|
|
}
|
|
|
|
_sendRemote(entry) {
|
|
fetch(this.remoteEndpoint, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(entry)
|
|
}).catch(err => console.error('Remote logging failed:', err));
|
|
}
|
|
|
|
_setupGlobalHandlers() {
|
|
window.addEventListener('error', (event) => {
|
|
this.error(`JavaScript Error: ${event.message}`, {
|
|
file: event.filename,
|
|
line: event.lineno,
|
|
column: event.colno,
|
|
stack: event.error?.stack
|
|
});
|
|
});
|
|
|
|
window.addEventListener('unhandledrejection', (event) => {
|
|
this.error(`Unhandled Promise Rejection: ${event.reason}`, {
|
|
stack: event.reason?.stack
|
|
});
|
|
});
|
|
}
|
|
|
|
exportLogs() {
|
|
if (typeof localStorage === 'undefined') return [];
|
|
return JSON.parse(localStorage.getItem('app_logs') || '[]');
|
|
}
|
|
|
|
clearLogs() {
|
|
if (typeof localStorage !== 'undefined') {
|
|
localStorage.removeItem('app_logs');
|
|
}
|
|
}
|
|
}
|