chore: complete update
This commit is contained in:
99
resources/js/core/secureLogger.js
Normal file
99
resources/js/core/secureLogger.js
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Erweiterter Logger mit Request-ID-Unterstützung und Server-Kommunikation.
|
||||
*/
|
||||
export class SecureLogger {
|
||||
static enabled = true;
|
||||
static apiEndpoint = '/api/log';
|
||||
static requestId = null;
|
||||
|
||||
static log(...args) {
|
||||
this._write('log', args);
|
||||
}
|
||||
|
||||
static warn(...args) {
|
||||
this._write('warn', args)
|
||||
}
|
||||
|
||||
static info(...args) {
|
||||
this._write('info', args);
|
||||
}
|
||||
|
||||
static error(...args) {
|
||||
this._write('error', args);
|
||||
}
|
||||
|
||||
static _write(level, args) {
|
||||
if(!this.enabled) return;
|
||||
|
||||
const date = new Date();
|
||||
const timestamp = date.toLocaleTimeString('de-DE');
|
||||
const requestIdStr = this.requestId ? `[${this.requestId}] ` : '';
|
||||
|
||||
const message = args.map(a => typeof a === 'object' ? JSON.stringify(a) : a).join(' ');
|
||||
const formattedMessage = `[${timestamp}] ${requestIdStr}[${level.toUpperCase()}] ${message}`;
|
||||
|
||||
// Lokales Logging in der Konsole
|
||||
console[level](formattedMessage);
|
||||
|
||||
// An den Server senden (wenn nicht in Produktion)
|
||||
this._sendToServer(level, message, args.find(a => typeof a === 'object'));
|
||||
}
|
||||
|
||||
static _sendToServer(level, message, context) {
|
||||
fetch(this.apiEndpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Request-ID': this.requestId || ''
|
||||
},
|
||||
body: JSON.stringify({
|
||||
level,
|
||||
message,
|
||||
context
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
// Request-ID aus dem Header extrahieren
|
||||
const requestId = response.headers.get('X-Request-ID');
|
||||
if (requestId) {
|
||||
// Nur den ID-Teil ohne Signatur speichern
|
||||
const idPart = requestId.split('.')[0];
|
||||
if (idPart) {
|
||||
this.requestId = idPart;
|
||||
}
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Fehler beim Senden des Logs:', err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Request-ID aus dem Document laden
|
||||
*/
|
||||
static initFromDocument() {
|
||||
// Versuche die Request-ID aus einem Meta-Tag zu lesen
|
||||
const meta = document.querySelector('meta[name="request-id"]');
|
||||
if (meta) {
|
||||
const fullRequestId = meta.getAttribute('content');
|
||||
// Nur den ID-Teil ohne Signatur verwenden
|
||||
this.requestId = fullRequestId.split('.')[0] || null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request-ID initialisieren, wenn das DOM geladen ist
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
SecureLogger.initFromDocument();
|
||||
|
||||
// Abfangen aller unbehandelten Fehler und Logging
|
||||
window.addEventListener('error', (event) => {
|
||||
SecureLogger.error('Unbehandelter Fehler:', event.error || event.message);
|
||||
});
|
||||
|
||||
// Abfangen aller unbehandelten Promise-Rejects
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
SecureLogger.error('Unbehandelte Promise-Ablehnung:', event.reason);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user