Flutterプロジェクト開発のプロジェクトログとエラーキャプチャ
フレームワークの機能を使用して誤ったキャプチャを開発し、プロジェクトログを書くことができ、設備情報を記録することができ、コードは以下の通りである.
参照ドキュメント:ファイル操作異常取得ログ処理装置情報
import 'dart:io';
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_info/device_info.dart';
/// ### 、 、 、 、
/// * :
/// ```dart
/// ErrorLog.log = new ErrorLog(
/// reportZone: () async {
/// runApp(new MyApp());
/// },
/// debugMode: true,
/// uploadFile: (file) async {},
/// minutesWait: 30,
/// [fileName: 'error_log.txt']
/// );
/// ```
///
/// ###
/// ; 。
/// * :
/// ```dart
/// ErrorLog.log.debug('msg'*8);
/// ErrorLog.log.info('msg'*8);
/// ErrorLog.log.warn('msg'*8);
/// ErrorLog.log.error('msg'*8);
/// ErrorLog.log.fatal('msg'*8);
/// ErrorLog.log.collectLog('msg'*8, 'error'); //
/// ```
/// * :
/// #### [2019-04-18 11:50:29.844858][error] msgmsgmsgmsgmsgmsgmsgmsg
///
/// ###
/// , `report`。
/// * :
/// , `try/catch`, `print`。
/// * :
/// #### [2019-04-18 14:05:03.578755][report]
/// ####
///
/// ###
/// , `debugMode` , ;
/// `error_log.txt`, `fileName`。
/// * :
/// ```dart
/// ErrorLog.log.printBuffer(); //
/// ErrorLog.log.clearFile(); //
/// ErrorLog.log.printFile(); //
/// ```
///
/// ###
/// , , 30 。 , , 。
/// * :
/// `uploadFile` `minutesWait`, `ErrorLog.log.logFile`。
///
/// ###
/// [device_info](https://pub.dartlang.org/packages/device_info), 。
/// * :
/// ```dart
/// await ErrorLog.log.getDeviceInfo(); //
/// ```
/// * :
/// ,Future
/// #### [2019-04-24 10:05:11.413469][info] [device_info](https://pub.dartlang.org/packages/device_info)
/// #### [androidInfo] androidId: 1a08f53b320ccfef, ...
///
class ErrorLog {
/// ,
static ErrorLog log;
///
Function _reportZone;
///
bool _debugMode;
///
List _logBuffer;
///
File _logFile;
File get logFile => _logFile;
///
int _startIndex;
///
int _endIndex;
///
Function _uploadFile;
///
int _minutesWait;
///
bool _fileChange;
///
String fileName;
ErrorLog({
@required Function reportZone,
@required bool debugMode,
@required Function uploadFile,
@required int minutesWait,
this.fileName = 'error_log.txt'
}) {
_reportZone = reportZone;
_debugMode = debugMode;
_uploadFile = uploadFile;
_minutesWait = minutesWait;
init();
}
///
void init() async {
_logBuffer = [];
_startIndex = 0;
_endIndex = 0;
_fileChange = false;
FlutterError.onError = (FlutterErrorDetails details) {
reportError(details);
};
runZoned(
_reportZone,
onError: (Object obj, StackTrace stack) {
var details = makeDetails(obj, stack);
reportError(details);
}
);
_logFile = await _getLocalFile();
info(' 。');
getDeviceInfo();
if( !_debugMode ) _uploadFile(_logFile);
Timer.periodic(Duration(minutes: _minutesWait), (timer) async {
if ( _fileChange && !_debugMode ) {
await _uploadFile(_logFile);
_fileChange = false;
}
});
}
/// *
/// * [device_info](https://pub.dartlang.org/packages/device_info)
Future getDeviceInfo() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
String details = ' [device_info](https://pub.dartlang.org/packages/device_info)
';
try {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
details += '[iosInfo] identifierForVendor: ${iosInfo.identifierForVendor}, ';
details += 'isPhysicalDevice: ${iosInfo.isPhysicalDevice}, ';
details += 'localizedModel: ${iosInfo.localizedModel}, ';
details += 'model: ${iosInfo.model}, ';
details += 'name: ${iosInfo.name}, ';
details += 'systemName: ${iosInfo.systemName}, ';
details += 'systemVersion: ${iosInfo.systemVersion}. ';
details += '
[iosInfo.utsname] machine: ${iosInfo.utsname.machine}, ';
details += 'nodename: ${iosInfo.utsname.nodename}, ';
details += 'release: ${iosInfo.utsname.release}, ';
details += 'sysname: ${iosInfo.utsname.sysname}, ';
details += 'version: ${iosInfo.utsname.version}. ';
} catch(e) {
error(' ios 。');
}
try {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
details += '[androidInfo] androidId: ${androidInfo.androidId}, ';
details += 'board: ${androidInfo.board}, ';
details += 'bootloader: ${androidInfo.bootloader}, ';
details += 'brand: ${androidInfo.brand}, ';
details += 'device: ${androidInfo.device}, ';
details += 'display: ${androidInfo.display}, ';
details += 'fingerprint: ${androidInfo.fingerprint}, ';
details += 'hardware: ${androidInfo.hardware}, ';
details += 'host: ${androidInfo.host}, ';
details += 'id: ${androidInfo.id}, ';
details += 'isPhysicalDevice: ${androidInfo.isPhysicalDevice}, ';
details += 'manufacturer: ${androidInfo.manufacturer}, ';
details += 'model: ${androidInfo.model}, ';
details += 'product: ${androidInfo.product}, ';
details += 'supported32BitAbis: ${androidInfo.supported32BitAbis}, ';
details += 'supported64BitAbis: ${androidInfo.supported64BitAbis}, ';
details += 'supportedAbis: ${androidInfo.supportedAbis}, ';
details += 'tags: ${androidInfo.tags}, ';
details += 'type: ${androidInfo.type}. ';
details += '
[androidInfo.version] baseOS: ${androidInfo.version.baseOS}, ';
details += 'codename: ${androidInfo.version.codename}, ';
details += 'incremental: ${androidInfo.version.incremental}, ';
details += 'previewSdkInt: ${androidInfo.version.previewSdkInt}, ';
details += 'release: ${androidInfo.version.release}, ';
details += 'sdkInt: ${androidInfo.version.sdkInt}, ';
details += 'securityPatch: ${androidInfo.version.securityPatch}. ';
} catch(e) {
error(' android 。');
}
info(details);
return details;
}
///
void reportError(FlutterErrorDetails details) {
String errorMeta = '[' + (new DateTime.now().toString()) + '][report]';
_logBuffer.add(errorMeta + '
' + details.toString());
if (_debugMode) {
print(errorMeta);
print(details.toString());
} else {
_writeFile();
}
}
///
collectLog(String line, String label) {
String contents = '[' + (new DateTime.now().toString()) + '][' + label + '] ' + line;
_logBuffer.add(contents + '
');
if (_debugMode) {
print(contents);
} else {
_writeFile();
}
}
///
Future printFile() async {
_readLocalFile().then((contents) {
print(contents);
});
}
///
Future printBuffer() async {
print( _logBuffer.toString() );
}
///
Future clearFile() async {
await _logFile.writeAsString('', mode: FileMode.write);
}
/// ,
Future _writeFile() async {
int len = _logBuffer.length;
if (len > _endIndex) {
_startIndex = _endIndex;
_endIndex = len;
Iterable range = _logBuffer.getRange(_startIndex, _endIndex);
await _writeLocalFile( range.join('
') );
_fileChange = true;
}
}
///
Future _getLocalFile() async {
String dir = (await getApplicationDocumentsDirectory()).path;
return new File('$dir/' + fileName);
}
///
Future _readLocalFile() async {
String contents = await _logFile.readAsString();
return contents;
}
///
Future _writeLocalFile(String contents) async {
await _logFile.writeAsString(contents, mode: FileMode.append, flush: false);
}
///
FlutterErrorDetails makeDetails(Object obj, StackTrace stack) {
return FlutterErrorDetails(exception: obj, stack: stack);
}
///
void debug(String msg) {
collectLog(msg, 'debug');
}
///
void info(String msg) {
collectLog(msg, 'info');
}
///
void warn(String msg) {
collectLog(msg, 'warn');
}
///
void error(String msg) {
collectLog(msg, 'error');
}
///
void fatal(String msg) {
collectLog(msg, 'fatal');
}
}
参照ドキュメント:ファイル操作異常取得ログ処理装置情報