Logging in Dart
プログラミングにおいてロギングはデバッグなどに欠かせません。Dartにおいても同様です。ではDartでのロギングはどのように行うのでしょうか。
基本のprint()
最も基本となるのがprint()でのログ出力です。
print('log by print');
標準出力に
flutter: log by print
と出力されます。この出力はAndroid StudioなどのIDEのコンソールでも確認できます。
直接標準出力に出力するには以下のように行います。
stdout.writeln('log by stdout'); // 標準出力
stderr.writeln('log by stderr'); // 標準エラー出力
これらは
log by stdout
log by stderr
がそれぞれ標準出力と標準エラー出力に出力されるのですが、IDEのコンソールでは確認できませんでした。一方、Dart DevToolsでは確認できました。
print()では不十分な場合はdebugPrint()
print()では長いログが途中から破棄されます。その場合はdebugPrint()を利用します。
debugPrint('log by debugPrint');
折り返しを指定することもできます。
debugPrint('log by debugPrint', wrapWidth: 2);
これは以下のように出力されます。
flutter: log
flutter: by
flutter: debugPrint
debugPrint()はDebugPrintCallback型の変数で、デフォルトの実装であるdebugPrintThrottledメソッドの動作はデータ損失を避けるための処理によってprint()と一緒に使うとログの順序が狂う可能性があります。
スロットルを行わないdebugPrintSynchronouslyというメソッドもあり、テストで利用されたりします。
debugPrint = debugPrintSynchronously;
のようにdebugPrintの実装を変更できます。また、
debugPrint = (String message, {int wrapWidth}) {...};
のように独自の実装に変更することもできます。
dart:developer log()でより多くの情報を出力
dart:developer log()でさらに多くの情報を出力できます。
import 'dart:developer' as developer;developer.log('log by developer.log');
dart:developerをインポートしてlogメソッドを実行すると以下のように出力されます。
[log] log by developer.log
以下のようにnameを付与すると
developer.log('log by developer.log', name: 'mylog');
[log]ではなく[mylog]として表示されます。ログの分類に利用できます。
[mylog] log by developer.log
さらに、エラー情報を追加することができます。
developer.log(
'log by developer.log',
error: FormatException('exception'),
);
出力は以下のようになります。エラーの部分はIDEコンソールでは赤で表示されます。
[log] log by developer.log
FormatException: exception
スタックトレースを表示することも可能です。
developer.log(
'log by developer.log',
stackTrace: StackTrace.current,
);
その他 DateTime time, int sequenceNumber, int level, Zone zone を渡すことができます。
より詳細なログを求めて
print, debugPrintにはファイル名や行番号などの情報が不足しています。, dart:developer log()ではスタックトレースを出力することでファイル名・行番号を得ることができますが、スタックトレースの表示が長大になってしまい、ロギングに支障が出ます。
Dartの公式loggingパッケージでもファイル名・行番号は出力されないようです。以下ロギング用パッケージであればファイル名や行番号を出力してくれます。
- loggerパッケージ
- simple_loggerパッケージ
どちらもログのファイル名をクリックするとそのファイルの行にジャンプすることができます。loggerはやや大仰な出力です(Android Studioではログのカラーリングはプラグインが必要なようです)ので、simple_loggerの方が私は好みです。loggerにはFlutter向けの拡張パッケージも存在しています。
Dartではprint(), debugPrint(), dart:developer log(), ロギング用パッケージを使うことでロギングを行うことができます。それぞれ長所・短所があるので使い分けていきましょう。