8.3 日志与调试
·
完善的日志体系和错误上报机制是生产级 App 的必备能力,有助于快速定位线上问题。
一、logger 包
dependencies:
logger: ^2.3.0
import 'package:logger/logger.dart';
class AppLogger {
static final Logger _logger = Logger(
printer: PrettyPrinter(
methodCount: 2, // 显示 2 层调用栈
errorMethodCount: 8, // 错误时显示 8 层调用栈
lineLength: 120,
colors: true,
printEmojis: true,
dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart,
),
filter: ProductionFilter(), // 生产环境过滤 debug 日志
level: AppConfig.isDevelopment ? Level.trace : Level.warning,
);
static void trace(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.t(message, error: error, stackTrace: stackTrace);
static void debug(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.d(message, error: error, stackTrace: stackTrace);
static void info(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.i(message, error: error, stackTrace: stackTrace);
static void warning(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.w(message, error: error, stackTrace: stackTrace);
static void error(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.e(message, error: error, stackTrace: stackTrace);
static void fatal(dynamic message, [Object? error, StackTrace? stackTrace]) =>
_logger.f(message, error: error, stackTrace: stackTrace);
}
// 使用
AppLogger.info('用户登录成功: ${user.name}');
AppLogger.error('API 请求失败', e, stackTrace);
二、Sentry 错误上报
dependencies:
sentry_flutter: ^7.19.0
// main.dart
Future<void> main() async {
await SentryFlutter.init(
(options) {
options.dsn = AppConfig.sentryDsn;
options.environment = AppConfig.appEnv;
options.release = 'my_app@1.0.0+1';
options.tracesSampleRate = 0.2; // 20% 性能追踪
options.profilesSampleRate = 0.1;
// 过滤不需要上报的错误
options.beforeSend = (event, hint) {
if (event.throwable is NetworkException) return null; // 不上报网络错误
return event;
};
},
appRunner: () => runApp(const MyApp()),
);
}
// 手动上报
try {
await riskyOperation();
} catch (e, stackTrace) {
await Sentry.captureException(e, stackTrace: stackTrace);
// 或附加额外信息
await Sentry.captureException(
e,
stackTrace: stackTrace,
withScope: (scope) {
scope.setTag('operation', 'checkout');
scope.setExtra('orderId', orderId);
scope.setUser(SentryUser(id: currentUser.id.toString()));
},
);
}
// 性能追踪
Future<void> loadProductList() async {
final transaction = Sentry.startTransaction('loadProductList', 'http.client');
try {
final products = await repository.fetchAll();
transaction.status = const SpanStatus.ok();
return products;
} catch (e) {
transaction.status = const SpanStatus.internalError();
rethrow;
} finally {
await transaction.finish();
}
}
三、全局异常捕获
Future<void> main() async {
// 捕获 Flutter 框架内的错误
FlutterError.onError = (details) {
AppLogger.error(
'Flutter Error: ${details.exception}',
details.exception,
details.stack,
);
Sentry.captureException(details.exception, stackTrace: details.stack);
};
// 捕获 Dart 异步错误(未被 try-catch 捕获的)
PlatformDispatcher.instance.onError = (error, stack) {
AppLogger.fatal('Uncaught Error: $error', error, stack);
Sentry.captureException(error, stackTrace: stack);
return true; // 返回 true 表示已处理
};
// 确保 Flutter 绑定初始化完成后再捕获错误
runApp(
const ProviderScope(child: MyApp()),
);
}
四、调试技巧
// 仅在 Debug 模式下执行
assert(() {
print('Debug only: $data');
return true;
}());
// kDebugMode / kReleaseMode / kProfileMode
if (kDebugMode) {
print('Debug mode log');
}
// debugger():在代码中设置断点(需 Debug 模式)
import 'dart:developer';
debugger(when: condition, message: 'Break here');
// inspect():在 DevTools Inspector 中查看对象
inspect(myObject);
小结
| 工具 | 用途 |
|---|---|
| logger | 分级日志,开发调试 |
| Sentry | 生产错误上报,性能追踪 |
| FlutterError.onError | 捕获 Flutter 框架错误 |
| PlatformDispatcher.onError | 捕获未处理的 Dart 异步错误 |
👉 下一章:九、平台交互(Platform Integration)
更多推荐
所有评论(0)