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