#连接库初步完成

This commit is contained in:
CC
2026-01-27 18:44:49 +08:00
parent 8c39f0daf8
commit 949743972c
82 changed files with 1187 additions and 650 deletions

View File

@@ -11,26 +11,31 @@ import 'package:intl/intl.dart';
class SentryLoggerImpl implements ILoggerService {
File? _localLogFile;
/// --- 临时控制开关 ---
/// true: 上传到 Sentry + 本地存储
/// false: 只进行本地存储 + 控制台打印
bool get _isRemoteEnabled => false;
@override
Future<void> init() async {
await SentryFlutter.init((options) {
options.dsn = EnvConfig.sentryDsn;
options.environment = EnvConfig.environment;
// 生产环境只采样 20% 的性能数据,测试环境全开
options.tracesSampleRate = EnvConfig.isProduction ? 0.2 : 1.0;
});
await _collectDeviceInfo();
// 只有在开启远程上传时才初始化 Sentry SDK
if (_isRemoteEnabled) {
await SentryFlutter.init((options) {
options.dsn = EnvConfig.sentryDsn;
options.environment = EnvConfig.environment;
options.tracesSampleRate = EnvConfig.isProduction ? 0.2 : 1.0;
});
await _collectDeviceInfo();
}
// 无论是否上传服务器,始终准备本地日志文件
await _prepareLocalFile();
}
// 准备本地文件路径
Future<void> _prepareLocalFile() async {
try {
final directory = await getApplicationDocumentsDirectory();
// 按天生成文件名,例如: 2024-05-20_logs.txt
final fileName =
"${DateFormat('yyyy-MM-dd').format(DateTime.now())}_logs.txt";
final fileName = "${DateFormat('yyyy-MM-dd').format(DateTime.now())}_logs.txt";
_localLogFile = File('${directory.path}/$fileName');
if (!await _localLogFile!.exists()) {
@@ -42,6 +47,8 @@ class SentryLoggerImpl implements ILoggerService {
}
Future<void> _collectDeviceInfo() async {
if (!_isRemoteEnabled) return;
final deviceInfo = DeviceInfoPlugin();
Sentry.configureScope((scope) async {
if (Platform.isAndroid) {
@@ -58,28 +65,45 @@ class SentryLoggerImpl implements ILoggerService {
@override
void captureException(dynamic exception, {dynamic stackTrace}) {
Sentry.captureException(exception, stackTrace: stackTrace);
final timestamp = DateTime.now().toIso8601String();
final logEntry = "[$timestamp] [ERROR] $exception\n$stackTrace\n";
// 1. 只有开启时上传
if (_isRemoteEnabled) {
Sentry.captureException(exception, stackTrace: stackTrace);
}
// 2. 始终写入本地
_writeToLocalFile(logEntry);
// 3. 始终控制台打印
if (kDebugMode) {
debugPrint(logEntry);
}
}
@override
void log(
String message, {
bool isWarning = false,
Map<String, dynamic>? data,
}) {
String message, {
bool isWarning = false,
Map<String, dynamic>? data,
}) {
final timestamp = DateTime.now().toIso8601String();
final level = isWarning ? 'WARNING' : 'INFO';
final logEntry = "[$timestamp] [$level] $message ${data ?? ''}\n";
// 1.发送日志到 Sentry
Sentry.captureMessage(
message,
level: isWarning ? SentryLevel.warning : SentryLevel.info,
);
// 1. 只有开启时上传到 Sentry
if (_isRemoteEnabled) {
Sentry.captureMessage(
message,
level: isWarning ? SentryLevel.warning : SentryLevel.info,
);
}
// 2.写入本地文件
// 2. 始终写入本地文件
_writeToLocalFile(logEntry);
// 3. 始终打印到控制台
if (kDebugMode) {
debugPrint(logEntry);
}
@@ -87,25 +111,29 @@ class SentryLoggerImpl implements ILoggerService {
Future<void> _writeToLocalFile(String entry) async {
try {
// 使用追加模式写入
await _localLogFile?.writeAsString(entry, mode: FileMode.append);
} catch (e) {
// 本地写入失败不应崩溃
// 这里的错误不再抛出,避免日志系统本身崩溃导致主业务中断
}
}
// 增加一个获取本地日志文件路径的方法,方便你以后做“导出日志”功能
Future<String?> getLocalLogPath() async {
return _localLogFile?.path;
}
@override
void addBreadcrumb(String message, {String? category}) {
Sentry.addBreadcrumb(Breadcrumb(message: message, category: category));
// 面包屑主要用于 Sentry 报错时的上下文,如果关闭了远程,记录本地即可(可选)
if (_isRemoteEnabled) {
Sentry.addBreadcrumb(Breadcrumb(message: message, category: category));
}
_writeToLocalFile("[BREADCRUMB] [$category] $message\n");
}
@override
void setUser(String userId) {
Sentry.configureScope((scope) => scope.setUser(SentryUser(id: userId)));
if (_isRemoteEnabled) {
Sentry.configureScope((scope) => scope.setUser(SentryUser(id: userId)));
}
}
}
}