Flutterプロジェクト開発のプロジェクトログとエラーキャプチャ

9331 ワード

フレームワークの機能を使用して誤ったキャプチャを開発し、プロジェクトログを書くことができ、設備情報を記録することができ、コードは以下の通りである.

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'); } }

参照ドキュメント:ファイル操作異常取得ログ処理装置情報