refactor: remove CrashReporter and related logging components
- Removed CrashReporter interface and its implementation, SentryCrashReporter. - Deleted log buffering functionality and associated LogBuffer class. - Updated LoggerAppLogger to eliminate dependencies on removed components. - Simplified logging structure to focus on AppLogger and sensitive data scrubbing. - Adjusted AppEnv to remove Sentry-related configurations. - Refactored tests to align with the new logging architecture.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
/// 随 App 打包的环境配置加载器。
|
||||
library;
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:core_foundation/core_foundation.dart';
|
||||
import 'package:flutter/foundation.dart' show FlutterError;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// 根据 Flutter 的 flavor 加载对应环境配置;未指定时默认开发环境。
|
||||
Future<AppEnv> loadBundledAppEnv({String? flavor}) async {
|
||||
final String selectedFlavor = flavor ?? AppFlavor.dev.name;
|
||||
final String assetPath = 'env/$selectedFlavor.json';
|
||||
|
||||
try {
|
||||
final String jsonObj = await rootBundle.loadString(assetPath);
|
||||
final decoded = jsonDecode(jsonObj);
|
||||
if (decoded is! Map<String, dynamic>) {
|
||||
throw const FormatException('根节点必须是 JSON 对象');
|
||||
}
|
||||
return AppEnv.fromConfig(flavor: selectedFlavor, values: decoded.cast<String, Object?>());
|
||||
} on StateError {
|
||||
rethrow;
|
||||
} on FormatException catch (error) {
|
||||
throw StateError('环境配置 $assetPath 格式错误:${error.message}');
|
||||
} on FlutterError catch (error) {
|
||||
throw StateError('无法加载环境配置 $assetPath:${error.message}');
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
///
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// 它是**兜底**,不是主路径:UI 该显示的错误由 `AsyncValueView` 负责,这里只
|
||||
/// 负责"这个异常有没有人处理过"之外的另一件事——落日志和上报。
|
||||
/// 负责"这个异常有没有人处理过"之外的另一件事——落日志。
|
||||
///
|
||||
/// 三类要**主动排除**,否则线上告警会被噪音淹没:
|
||||
/// - [BusinessException]:后端明确告诉我们"这个操作不允许",是预期内的流程
|
||||
@@ -20,14 +20,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
/// ---------------------------------------------------------------------------
|
||||
final class ErrorObserver extends ProviderObserver {
|
||||
/// 构造。
|
||||
ErrorObserver({required this.logger, required this.reporter});
|
||||
ErrorObserver({required this.logger});
|
||||
|
||||
/// 日志出口。
|
||||
final AppLogger logger;
|
||||
|
||||
/// 崩溃上报出口。
|
||||
final CrashReporter reporter;
|
||||
|
||||
@override
|
||||
void providerDidFail(ProviderObserverContext context, Object error, StackTrace stackTrace) {
|
||||
final String name = context.provider.name ?? context.provider.runtimeType.toString();
|
||||
@@ -42,6 +39,5 @@ final class ErrorObserver extends ProviderObserver {
|
||||
}
|
||||
|
||||
logger.e('provider 失败 $name', error: error, stackTrace: stackTrace);
|
||||
reporter.report(error, stackTrace, extra: <String, String>{'provider': name});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// 会话事件的旁路接线:埋点身份、崩溃上报的用户上下文、路由错误上报。
|
||||
/// 会话事件的旁路接线:埋点身份与路由错误日志。
|
||||
///
|
||||
/// 这些都是 core_auth 声明的端口(`session_ports.dart` / `core_router/ports.dart`)
|
||||
/// 的实现——core_auth 不能依赖 core_analytics / core_logging,所以实现落在这里。
|
||||
@@ -9,26 +9,20 @@ import 'package:core_auth/core_auth.dart';
|
||||
import 'package:core_logging/core_logging.dart';
|
||||
import 'package:core_router/core_router.dart';
|
||||
|
||||
/// 把会话变化广播给埋点和崩溃上报。
|
||||
/// 把会话变化广播给埋点。
|
||||
class AppSessionObserver implements SessionObserver {
|
||||
/// 构造。
|
||||
const AppSessionObserver({required this.analytics, required this.reporter});
|
||||
const AppSessionObserver({required this.analytics});
|
||||
|
||||
/// 埋点。
|
||||
final Analytics analytics;
|
||||
|
||||
/// 崩溃上报。
|
||||
final CrashReporter reporter;
|
||||
|
||||
@override
|
||||
void onUserIdentified(UserContext user) {
|
||||
analytics.identify(user.userId);
|
||||
analytics.registerSuperProperties(<String, Object?>{
|
||||
AnalyticsSuperProperty.roleCode: user.roleCode,
|
||||
});
|
||||
// 只传 userId,不传手机号——Sentry 侧 sendDefaultPii = false 的前提就是
|
||||
// 我们自己也不往里塞 PII。
|
||||
reporter.setUser(user.userId);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -37,7 +31,6 @@ class AppSessionObserver implements SessionObserver {
|
||||
analytics.registerSuperProperties(<String, Object?>{
|
||||
AnalyticsSuperProperty.storeId: store.storeId,
|
||||
});
|
||||
reporter.setTag('storeId', '${store.storeId}');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -46,7 +39,6 @@ class AppSessionObserver implements SessionObserver {
|
||||
analytics.track(AnalyticsEvent.logout, <String, Object?>{AnalyticsParam.reason: reason.name});
|
||||
// 门店设备是共用的:不 reset,下一个人的数据会串到上一个人身上。
|
||||
analytics.reset();
|
||||
reporter.clearUser();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -57,26 +49,18 @@ class AppSessionObserver implements SessionObserver {
|
||||
}
|
||||
}
|
||||
|
||||
/// 路由未命中时上报。
|
||||
/// 路由未命中时记录日志。
|
||||
class AppRouteReporter implements RouteReporter {
|
||||
/// 构造。
|
||||
const AppRouteReporter({required this.logger, required this.reporter});
|
||||
const AppRouteReporter({required this.logger});
|
||||
|
||||
/// 日志。
|
||||
final AppLogger logger;
|
||||
|
||||
/// 崩溃上报。
|
||||
final CrashReporter reporter;
|
||||
|
||||
@override
|
||||
void onRouteNotFound(String location) {
|
||||
// 记路径不记 query——H5 相关路径的 query 里带票据(13 §脱敏)。
|
||||
final String path = Uri.tryParse(location)?.path ?? location;
|
||||
logger.w('路由未命中: $path');
|
||||
reporter.report(
|
||||
StateError('route not found'),
|
||||
StackTrace.current,
|
||||
extra: <String, String>{AnalyticsParam.path: path},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user