Logging in JavaScript-Anwendungen: Best Practices in der Praxis
Logging ist nicht einfach das Aufzeichnen von Nachrichten in der Konsole. In einer Production-Umgebung wird richtig konfiguriertes Logging zum wichtigsten Werkzeug für Monitoring, Debugging und Audit. Ohne es arbeiten Sie im Blindflug. In diesem Artikel analysieren wir die Best Practices für das Logging von JavaScript-Anwendungen auf Node.js, von der Bibliotheksauswahl bis zur Konfiguration der Dateirotation. Alle Codebeispiele sind einsatzbereit.
1. Warum console.log schlecht ist
In der Entwicklungsphase verwenden wir alle console.log. Es ist schnell und bequem. Aber in der Produktion ist dieser Ansatz gefährlich:
- Keine Log-Level. Sie können Fehler nicht von Informationsmeldungen filtern.
- Synchroner Blockierungsvorgang. Der Standard-
console.logkann die Anwendung bei einem großen Anfrageaufkommen verlangsamen. - Fehlende Struktur. JSON-Logs können ohne zusätzliche Workarounds nicht geparst werden.
- Keine Rotation. Die Log-Datei wächst unbegrenzt, bis die Festplatte voll ist.
Verwenden Sie stattdessen professionelle Bibliotheken. Die beiden beliebtesten in Node.js sind Winston und Pino.
2. Bibliotheksauswahl: Winston vs Pino
Beide Bibliotheken lösen die gleiche Aufgabe, haben aber unterschiedliche Prioritäten.
Winston – universell und flexibel
Winston ist das „Schweizer Taschenmesser“ des Loggings. Es unterstützt zahlreiche Transports (Dateien, Konsole, HTTP, Datenbanken) und ist einfach konfigurierbar.
const winston = require('winston');
const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }), ],});
// In der Entwicklung fügen wir Konsolenausgabe hinzuif (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.simple(), }));}
logger.info('Server gestartet auf Port 3000');logger.error('Fehler bei der Datenbankverbindung', { db: 'postgres' });Pino – Geschwindigkeit an erster Stelle
Pino positioniert sich als der schnellste Logger für Node.js. Es ist 5-6x schneller als Winston dank der Verwendung von sonic-boom (asynchrones Schreiben). Ideal für High-Load-Projekte.
const pino = require('pino');
const logger = pino({ level: process.env.LOG_LEVEL || 'info', transport: { target: 'pino/file', options: { destination: './app.log' }, },});
logger.info({ user: 'admin' }, 'Benutzer hat sich angemeldet');logger.error({ err: new Error('Timeout') }, 'Anfrage hat das Limit überschritten');Tipp: Wählen Sie für Microservices und APIs mit hoher Last Pino. Für komplexe Konfigurationen mit mehreren Transports – Winston.
3. Log-Level: Schreiben Sie nicht alles in info
Verwenden Sie die Standard-Skala der Level (aufsteigend nach Wichtigkeit):
trace/debug– nur für die Entwicklung. Detailliertes Debugging.info– normaler Betrieb der Anwendung: Start, erfolgreiche Anfragen, Geschäftsereignisse.warn– potenzielle Probleme: langsame Anfragen, Speichermangel, veraltete Methoden.error– Ausnahmen, Fehler, Abstürze. Sollten immer in einer separaten Datei oder einem Monitoring-System sein.fatal– kritische Fehler, nach denen die Anwendung nicht weiterarbeiten kann.
Konfigurieren Sie die Umgebungsvariable LOG_LEVEL, um die Filterstufe ohne Neustart des Codes zu ändern:
// Beispiel mit Winstonconst logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', // ...});
// In