All checks were successful
Word limit and no-retry state for rejected input, nested /catalog route for system back, logger filter for supabase libs, more mutation-proof tests, doc fix, umlaut-aware term sorting, thousands separators. Refs #3 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
71 lines
2.3 KiB
Dart
71 lines
2.3 KiB
Dart
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<LogRecord>? _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<LogRecord>? get subscription => _subscription;
|
|
|
|
/// Entfernt den Listener wieder (nur für Tests).
|
|
@visibleForTesting
|
|
static Future<void> resetForTesting() async {
|
|
await _subscription?.cancel();
|
|
_subscription = null;
|
|
}
|
|
|
|
/// Whether a record is written. Records of the Supabase libraries below
|
|
/// INFO are dropped: postgrest logs `'$error from request'` at FINE, and the
|
|
/// error text can echo request parameters (search terms, QUE-04).
|
|
@visibleForTesting
|
|
static bool shouldWrite(LogRecord record) =>
|
|
!(record.loggerName.startsWith('supabase') && record.level < Level.INFO);
|
|
|
|
static void _write(LogRecord record) {
|
|
if (!shouldWrite(record)) {
|
|
return;
|
|
}
|
|
developer.log(
|
|
record.message,
|
|
time: record.time,
|
|
level: record.level.value,
|
|
name: record.loggerName,
|
|
error: record.error,
|
|
stackTrace: record.stackTrace,
|
|
);
|
|
}
|
|
}
|