app一些重要步骤 比如支付 需要把用户每一步日志写入到本地,如果有异常,可以服务端下发一个字段,让设备自动上传日志, 或者用户某个操作主动触发上传本地日志.
我写了一个可以写入文件的类,自动删除超过7天的文件
每天生成一个文件 ,每次启动有标识
每个log都有时间
上传时候调用showFileList()打印出来所有文件列表
调用接口上传文件就行
尤其对ios内购很必要,内购逻辑都在客户端,如果你的逻辑不完善 再没有日志,出现丢单的话 就没法排查了.有了日志 出现问题你能找到问题原因 解决问题
使用时候要提前一个地方 调用下FileWriteLog.instance提前生成目录
打印时候 FileWriteLog.log('xxxx');
每天第一次打印时候 会生成一个文件 文件名字是当天日期
class FileWriteLog {
FileWriteLog._() {
createDirectory();
}
static FileWriteLog? _instance;
static FileWriteLog get instance => _getOrCreateInstance();
static FileWriteLog _getOrCreateInstance() {
if (_instance != null) {
return _instance!;
} else {
_instance = FileWriteLog._();
return _instance!;
}
}
File? currentFile;
static bool isFirst = true;
static log(String content) {
if (isFirst) {
isFirst = false;
FileWriteLog.instance
.writeFile('-----------------app启动 日志开始-----------------------\n '
'UserId--->${LoginTool.getUserId}\n $content');
} else {
FileWriteLog.instance.writeFile(content);
}
}
// 写入一次 文件才会生成
writeFile(String content) async {
if (fileName.isNotEmpty) {
try {
jdLog('写入文件内容---->$content');
IOSink sink = currentFile!.openWrite(mode: FileMode.append);
sink.writeln(
'$content ---- 时间 ${TimeTool.formatFullInfo(DateTime.now())}');
await sink.flush();
await sink.close();
} catch (e) {
jdLog('写入异常----> $e');
}
}
}
String fileType = '.txt';
Future<String> readFile() async {
try {
bool exist = await FileTool.fileExists(fileName);
if (!exist) {
jdLog('文件不存在');
return '';
}
File file = File(fileName);
String contents = await file.readAsString();
jdLog('read 内容----> $contents');
return contents;
} catch (e) {
return '';
}
}
String fileName = '';
createFileName() {
if (fileName.isNotEmptyNullAble) {
return fileName;
}
var time = DateTime.now();
// 一天创建一个日志文件 半个月前的日志文件删除
String name =formatDateTime(time);
fileName = '$currentDirectory/$name$fileType';
currentFile = File(fileName);
return fileName;
}
String formatDateTime(DateTime dateTime,
[String format = 'yyyy-MM-dd']) {
return DateFormat(format).format(dateTime);
}
String currentDirectory = '';
void createDirectory() async {
// 创建Directory对象
Directory documentPath = await getApplicationDocumentsDirectory();
currentDirectory = '${documentPath.path}/jdLog';
Directory directory = Directory(currentDirectory);
// 检查目录是否存在,如果不存在,则创建目录
if (!await directory.exists()) {
// 设置recursive为true以确保创建任何必要的父目录
await directory.create(recursive: true);
jdLog('Directory created successfully!');
} else {
jdLog('Directory already exists.');
}
createFileName();
deleteOldFiles();
}
showFileList() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
jdLog('当前文件列表----$value');
});
}
deleteAllFiles() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
value.mapIndex((index, element) {
FileTool.deleteFile(element);
});
});
}
deleteOldFiles() {
FileTool.listFilesInDirectory(currentDirectory).then((List<String> value) {
var nowTime = DateTime.now();
value.mapIndex((index, element) {
try {
List<String> parts = element.split('/'); // 使用 '/' 分割路径
// 获取最后一段路径
String lastSegment = parts.isNotEmpty ? parts.last : '';
if (lastSegment.endsWith(fileType)) {
lastSegment = lastSegment.substring(0, lastSegment.length - 4);
}
// jdLog('获取的文件名字22------$lastSegment');
DateTime? time = TimeTool.parse(lastSegment);
if (time is DateTime) {
Duration difference = time.difference(nowTime);
int days = difference.inDays;
if (days > 7) {
// 删除超过7天的文件
jdLog('离现在差距$days天 删除了-------->');
FileTool.deleteFile(element);
}
}
} catch (onError) {
jdLog('转换后的onError--------> $onError');
}
});
});
}
}