Einführung in die Protokollierung von TypeScript-Anwendungen
\n\nProtokollierung ist der Prozess der Aufzeichnung von Ereignissen, die während der Ausführung eines Programms auftreten. Für TypeScript-Anwendungen, insbesondere solche, die in der Node.js-Umgebung laufen, ist eine gut konfigurierte Protokollierung nicht nur guter Stil, sondern ein kritisch wichtiges Werkzeug für die Fehlersuche, Überwachung und Fehleranalyse.
\n\nViele Anfänger beschränken sich auf die Verwendung von console.log(). In einer Produktionsumgebung ist dieser Ansatz jedoch ineffizient: Er erlaubt keine flexible Steuerung der Wichtigkeitsstufen, das Filtern von Nachrichten oder das Speichern in Dateien. In diesem Artikel werden wir besprechen, wie man von Grund auf ein professionelles Protokollierungssystem in TypeScript erstellt.
Warum sollte man console.log in der Produktion nicht verwenden?
\n\nBetrachten wir ein typisches Beispiel:
\n\n// Schlechter Ansatz – wir verwenden console.log direkt\nfunction processOrder(orderId: string): void {\n console.log(`Processing order ${orderId}`);\n try {\n // Geschäftslogik\n } catch (error) {\n console.error(`Error processing order: ${error}`);\n }\n}\n\n\nProbleme dieses Ansatzes:
\n- \n
- Fehlende Protokollierungsstufen: Debug-Nachrichten können nicht von kritischen Fehlern getrennt werden. \n
- Keine Formatierung: Große Datenmengen sind schwer zu lesen. \n
- Keine Umleitung möglich: Alle Nachrichten gehen nur an stdout/stderr. \n
- Leistungsprobleme: Synchrone Konsolenausgabe kann die Anwendung verlangsamen. \n
Best Practices für die Protokollierung in TypeScript
\n\n1. Auswahl einer Protokollierungsbibliothek
\n\nFür TypeScript wird empfohlen, eine der beiden beliebten Bibliotheken zu verwenden:
\n- \n
- Winston – ein leistungsstarker und flexibler Logger mit Unterstützung für Transports (Datei, Konsole, Datenbanken). \n
- Pino – ein extrem schneller Logger, ideal für High-Load-Anwendungen. \n
Installieren wir Winston:
\nnpm install winston\nnpm install @types/winston --save-dev\n\n\n2. Erstellung eines konfigurierbaren Loggers
\n\nErstellen wir ein Modul logger.ts:
import winston from 'winston';\n\nconst logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple()\n )\n }),\n new winston.transports.File({ \n filename: 'logs/error.log', \n level: 'error' \n }),\n new winston.transports.File({ \n filename: 'logs/combined.log' \n })\n ]\n});\n\nexport default logger;\n\n\nJetzt kann der Logger in jedem Modul verwendet werden:
\nimport logger from './logger';\n\nfunction getUser(id: string) {\n logger.info(`Fetching user with ID: ${id}`);\n try {\n // Logik zum Abrufen des Benutzers\n logger.debug('User data retrieved successfully');\n } catch (error) {\n logger.error('Failed to fetch user', { userId: id, error });\n }\n}\n\n\n3. Verwendung von Protokollierungsstufen
\n\nStandardstufen (von der geringsten zur höchsten Wichtigkeit):
\n- \n
- debug – detaillierte Debug-Informationen (nur für die Entwicklung). \n
- info – Standard-Informationsmeldungen. \n
- warn – Warnungen vor potenziellen Problemen. \n
- error – Fehler, die Aufmerksamkeit erfordern. \n
Konfigurieren Sie die Protokollierungsstufe über Umgebungsvariablen:
\n// In der .env-Datei\nLOG_LEVEL=debug # für die Entwicklung\nLOG_LEVEL=warn # für die Produktion\n\n\n4. Strukturierte Protokollierung
\n\nÜbergeben Sie zusätzliche