# 📊 Logging System Dokumentation ## Oversigt Dette system leverer **centraliseret logging til databasen** med brugervenlige fejlbeskeder på dansk. Alle fejl, warnings og info-beskeder gemmes struktureret, så de nemt kan søges og analyseres. --- ## 🎯 Funktioner ✅ **Database logging** - Alle logs gemmes i MySQL i stedet for filer ✅ **Strukturerede logs** - Kontekst, kategori, fejlkoder, request info, osv. ✅ **Brugervenlige fejlbeskeder** - Danske beskeder med unikke fejlkoder ✅ **Performance tracking** - Logger response time for alle requests ✅ **Admin dashboard** - API endpoints til at se og analysere logs ✅ **Automatisk cleanup** - Gamle logs slettes automatisk (90/180 dage) --- ## 🗄️ Database Tabeller ### `system_logs` Hovedtabel til alle log-indgange: ```sql - id, created_at, level (ERROR/WARNING/INFO/DEBUG) - context, category, message, error_code - stack_trace, sql_query, sql_state - request_method, request_url, request_ip, user_agent - user_id, user_email - metadata (JSON) - resolved, resolved_at, resolved_by, resolution_notes ``` ### `request_logs` Performance tracking: ```sql - id, created_at, method, url, status_code - response_time_ms - user_id, ip_address, user_agent - metadata (JSON) ``` **Setup:** Kør SQL filen for at oprette tabellerne: ```bash mysql -u tilbuduser -p tilbudgivern < database/schema_system_logs.sql ``` --- ## 💻 Brug i Koden ### 1. Logger Funktioner ```javascript const logger = require('../src/utils/logger'); // Log en fejl med komplet kontekst logger.logError('MyContext', error, { category: 'API', errorCode: 'MY_ERROR_001', req: req, // Express request object userId: user.id, userMessage: 'Denne besked vises til brugeren', metadata: { additionalInfo: 'whatever' } }); // Log en warning logger.logWarning('MyContext', 'Dette er en advarsel', { category: 'BUSINESS', req: req, metadata: { someData: 'value' } }); // Log info logger.logInfo('MyContext', 'Dette gik godt', { category: 'INFO', req: req }); ``` ### 2. Error Handler Middleware Bruges automatisk i routes når du wrapper med `asyncHandler`: ```javascript const { asyncHandler, ERROR_CODES } = require('../src/middleware/errorHandler'); router.get('/my-endpoint', asyncHandler(async (req, res) => { // Hvis der kastes en fejl her, fanges den automatisk // og logges med komplet kontekst const data = await someAsyncFunction(); if (!data) { // Kast en 404 fejl const error = new Error('Ressource ikke fundet'); error.status = 404; throw error; } // Tag eksterne API fejl try { await externalAPI.call(); } catch (error) { error.name = 'OrdrestyringError'; // Klassificerer fejlen throw error; } res.json({ success: true, data }); })); ``` ### 3. Request Logger Middleware Logger automatisk alle API requests (allerede aktiveret i unified-server.js): ```javascript // Dette er allerede sat op! app.use('/api', requestLogger); ``` Logger: - Response time - Status codes - Langsomme requests (>1000ms) - Request/response størrelse --- ## 🔍 Fejlkoder Alle fejl har en **unik fejlkode** brugere kan referere til: | Kode | Beskrivelse | Brugerbesked | |------|-------------|--------------| | **DB_001** | Database connection fejl | "Kunne ikke oprette forbindelse til databasen" | | **DB_002** | Database query fejl | "Der opstod en fejl ved hentning af data" | | **VAL_001** | Validation fejl | "De indtastede data er ikke gyldige" | | **AUTH_001** | Login fejl | "Login fejlede. Tjek brugernavn og adgangskode" | | **API_001** | Ordrestyring API fejl | "Kunne ikke forbinde til Ordrestyring" | | **API_002** | OpenAI API fejl | "AI-tjenesten er midlertidigt utilgængelig" | | **BIZ_001** | Ressource ikke fundet | "Den ønskede ressource blev ikke fundet" | | **SYS_001** | Intern fejl | "Der opstod en intern fejl" | *Se `backend/src/middleware/errorHandler.js` for alle fejlkoder* --- ## 📡 Admin API Endpoints ### Hent logs ``` GET /api/admin/logs?level=ERROR&startDate=2024-01-01&limit=100 ``` Query params: - `level` - ERROR, WARNING, INFO, DEBUG - `context` - Kontekst filtrering - `category` - Kategori filtrering - `errorCode` - Specifik fejlkode - `startDate` / `endDate` - Dato range - `resolved` - true/false - `limit` / `offset` - Paginering ### Hent specifik log ``` GET /api/admin/logs/:id ``` ### Log statistik ``` GET /api/admin/logs/stats/summary?startDate=2024-01-01 ``` Returnerer: - Antal logs per niveau - Antal logs per kategori - Top 10 hyppigste fejl - Antal uløste fejl ### Marker log som løst ``` PATCH /api/admin/logs/:id/resolve Body: { "resolvedBy": "admin", "notes": "Fixed the bug" } ``` ### Langsomme requests ``` GET /api/admin/logs/performance/slow-requests?minResponseTime=1000 ``` ### Endpoint statistik ``` GET /api/admin/logs/performance/endpoint-stats ``` --- ## 🎨 Eksempel Fejl Response Development mode: ```json { "success": false, "error": { "code": "DB_002", "message": "Der opstod en fejl ved hentning af data. Kontakt support hvis problemet fortsætter.", "timestamp": "2024-11-14T12:34:56.789Z", "technicalMessage": "ER_BAD_FIELD_ERROR: Unknown column 'xyz'", "stack": "Error: ER_BAD_FIELD_ERROR..." } } ``` Production mode: ```json { "success": false, "error": { "code": "DB_002", "message": "Der opstod en fejl ved hentning af data. Kontakt support hvis problemet fortsætter.", "timestamp": "2024-11-14T12:34:56.789Z" } } ``` --- ## 🧹 Automatisk Cleanup Database event kører hver dag og sletter: - INFO/WARNING/DEBUG logs ældre end **90 dage** - ERROR logs ældre end **180 dage** - Request logs ældre end **30 dage** For at aktivere (kræves kun én gang): ```sql SET GLOBAL event_scheduler = ON; ``` --- ## 🚀 Best Practices ### ✅ GØR: - Brug `asyncHandler` til alle async route handlers - Tag fejl specifikt (`error.name = 'OrdrestyringError'`) - Log vigtige operationer med `logger.logInfo()` - Tilføj kontekst og metadata til logs - Brug kategori til at gruppere logs (API, DATABASE, BUSINESS, etc.) ### ❌ UNDGÅ: - `console.log()` direkte (brug logger i stedet) - At sende stack traces til frontend i production - At logge følsomme data (passwords, tokens) - For mange INFO logs (kun vigtige operationer) --- ## 🔐 Sikkerhed ⚠️ **VIGTIGT:** Admin endpoints er IKKE beskyttede endnu! I production skal du tilføje authentication: ```javascript const authMiddleware = require('./src/middleware/auth'); app.use('/api/admin/logs', authMiddleware.requireAdmin, require('./routes/adminLogs')); ``` --- ## 📈 Monitoring ### Tjek system health: ```bash # Antal fejl i dag SELECT COUNT(*) FROM system_logs WHERE level='ERROR' AND DATE(created_at) = CURDATE(); # Langsomme endpoints SELECT url, AVG(response_time_ms) as avg_time FROM request_logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY url HAVING avg_time > 1000 ORDER BY avg_time DESC; # Uløste fejl SELECT error_code, COUNT(*) as count FROM system_logs WHERE level='ERROR' AND resolved=FALSE GROUP BY error_code ORDER BY count DESC; ``` --- ## 🐛 Fejlsøgning ### Log vises ikke i databasen? 1. Tjek at tabellerne er oprettet: `SHOW TABLES LIKE 'system_logs';` 2. Tjek database connection i logger.js 3. Tjek console for "Failed to log to database" fejl ### Får stadig gamle fejlbeskeder? 1. Sørg for at du bruger `asyncHandler` i routes 2. Tjek at `errorHandler` middleware er aktiveret 3. Restart serveren ### Performance problemer? 1. Tjek antal logs: `SELECT COUNT(*) FROM system_logs;` 2. Kør cleanup manuelt hvis nødvendigt 3. Overvej at øge cleanup frekvens --- ## 📝 Opdatering af Eksisterende Routes For at opdatere en eksisterende route til at bruge det nye logging system: ```javascript // FØR router.get('/my-route', async (req, res) => { try { const data = await getData(); res.json({ success: true, data }); } catch (error) { console.error('Error:', error); res.status(500).json({ error: error.message }); } }); // EFTER const logger = require('../src/utils/logger'); const { asyncHandler } = require('../src/middleware/errorHandler'); router.get('/my-route', asyncHandler(async (req, res) => { logger.logInfo('MyRoute.Get', 'Fetching data', { category: 'API', req }); const data = await getData(); logger.logInfo('MyRoute.Get', 'Data fetched successfully', { category: 'API', req, metadata: { count: data.length } }); res.json({ success: true, data }); })); ``` --- **Lavet af:** GitHub Copilot **Dato:** 14. november 2024