import 'dart:async'; import 'dart:developer' as developer; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; /// Zentrales Logger-Utility (Wrapper um `package:logging`). /// /// Regeln: kein `print`, keine personenbezogenen Daten (E-Mail, Namen, /// Passwörter, Tokens) in Nachrichten oder Fehlerobjekten. class AppLogger { AppLogger(String name) : _logger = Logger(name); final Logger _logger; void debug(String message) => _logger.fine(message); void info(String message) => _logger.info(message); void warning(String message, {Object? error, StackTrace? stackTrace}) => _logger.warning(message, error, stackTrace); void error(String message, {Object? error, StackTrace? stackTrace}) => _logger.severe(message, error, stackTrace); static StreamSubscription? _subscription; /// Richtet die Ausgabe ein. Release: ab INFO, sonst alles. /// /// Idempotent: Wiederholte Aufrufe aktualisieren nur den Level und /// registrieren keinen weiteren Listener. /// /// Hinweis: `developer.log` hat in Release-Builds praktisch keine sichtbare /// Wirkung; produktives Crash-/Error-Reporting folgt in einem eigenen Task. static void configure({Level? level}) { Logger.root.level = level ?? (kReleaseMode ? Level.INFO : Level.ALL); _subscription ??= Logger.root.onRecord.listen(_write); } /// Aktiver Listener (nur für Tests). @visibleForTesting static StreamSubscription? get subscription => _subscription; /// Entfernt den Listener wieder (nur für Tests). @visibleForTesting static Future resetForTesting() async { await _subscription?.cancel(); _subscription = null; } static void _write(LogRecord record) { developer.log( record.message, time: record.time, level: record.level.value, name: record.loggerName, error: record.error, stackTrace: record.stackTrace, ); } }