import 'dart:convert'; import 'package:logger/logger.dart'; class SimpleLogPrinter extends LogPrinter { SimpleLogPrinter(this.className); final String className; static final _deviceStackTraceRegex = RegExp(r'#[0-9]+[\s]+(.+) \(([^\s]+)\)'); static final _webStackTraceRegex = RegExp(r'^((packages|dart-sdk)\/[^\s]+\/)'); @override List log(LogEvent event) { final Level level = event.level; final String message = stringifyMessage(event.message); final String error = event.error?.toString() ?? ''; final color = PrettyPrinter.levelColors[level]; final emoji = PrettyPrinter.levelEmojis[level]; String? stack; if (event.stackTrace == null) { stack = formatStackTrace(StackTrace.current, 2); } else { stack = formatStackTrace(event.stackTrace!, 1); } // ignore: avoid_print print(color!(' $emoji $message $error -> $stack ')); return []; } String stringifyMessage(dynamic message) { if (message is Map || message is Iterable) { const encoder = JsonEncoder.withIndent(' '); return encoder.convert(message); } else { return message.toString(); } } String? formatStackTrace(StackTrace stackTrace, int methodPosition) { final lines = stackTrace.toString().split('\n'); final formatted = []; var count = 0; for (final line in lines) { if (_discardDeviceStacktraceLine(line) || _discardWebStacktraceLine(line)) { continue; } formatted.add(line.replaceFirst(RegExp(r'#\d+\s+'), '')); if (++count == methodPosition) { break; } } if (formatted.isEmpty) { return null; } else { //return formatted.join('\n'); return formatted.last; } } bool _discardDeviceStacktraceLine(String line) { final match = _deviceStackTraceRegex.matchAsPrefix(line); if (match == null) { return false; } return match.group(2)!.startsWith('package:logger'); } bool _discardWebStacktraceLine(String line) { final match = _webStackTraceRegex.matchAsPrefix(line); if (match == null) { return false; } return match.group(1)!.startsWith('packages/logger') || match.group(1)!.startsWith('dart-sdk/lib'); } } Logger getLogger(String className) { return Logger(printer: SimpleLogPrinter(className)); }