search
LoginSignup
11

More than 5 years have passed since last update.

posted at

updated at

Dartで始めるロギング生活

Dartでのログ出力方法

Dartでログ出力を行う方法としては、まずprint関数があります。これはdart:coreパッケージに入っており、import無しで使用可能で、クライアントとWebの両方で使用することができます。

printの例
main() {
  print('hoge');
}

次にWeb向けであればdart:htmlのconsoleを使うことができます。これはJavaScriptから使えるものと同じものです。

consoleの例
import 'dart:html';

main() {
  console.log('hoge');
  console.info('foo');
  console.debug('bar');
}

しかし、これらだけでは物足りないことがあります。例えば、

  • ログレベルをコントロールしたい
  • ログをまとめて保存したり送信したりしたい

これらをしようとすると、独自の仕組みを作ってあげる必要があります。

そんなときには、Dartチーム謹製の公式パッケージ Logging が役に立ちます。

Loggingを使ってログ出力

このパッケージは、始めに「ログをどう出力するか」を設定して上げる必要があります。

ログレベルの指定とログ出力方法の設定の例
import 'package:logging/logging.dart';

final log = new Logger('hoge');

main() {
  Logger.root.level = Level.All;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });
}

Logger.root.levelで、先に出力するログレベルを指定します。上の例では、すべてのログを出力するようになります。

そして、Logger.root.onRecord.listenによって、どのようにログ出力するか、を書く必要があります。上の例ではprintによって出力するようになっています。

Loggingの設計

このLoggingの設計は、Closure JSのLogger、java.util.logging.Loggerに似せて作られたようです。

用意されているログ出力用のメソッド、ログレベルの定義がほぼ同じになっています。

ログ出力

Loggerのインスタンスを作る

Loggerのインスタンスを作る例
import 'package:logging/logging.dart';

final log = new Logger('hoge');

main() {
  Logger.root.level = Level.All;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });
}

このサンプルコードではfinal log = new Logger('hoge')として、ログ出力用のLoggerのインスタンスを作成していました。これを使用してログ出力することができます。

このLoggerコンストラクタの第一引数にStringで名前をあてるのが必須になり、この名前はユニークな名前である必要があります。

ログ出力用メソッド

Loggerには、以下のログ出力用メソッドがあります。

ログ出力メソッド 説明
config(message, [Object error, StackTrace stackTrace]) → void Level.CONFIGのログを出力する
fine(message, [Object error, StackTrace stackTrace]) → void Level.FINEのログを出力する
finer(message, [Object error, StackTrace stackTrace]) → void Level.FINERのログを出力する
finest(message, [Object error, StackTrace stackTrace]) → void Level.FINESTのログを出力する
info(message, [Object error, StackTrace stackTrace]) → void Level.INFOのログを出力する
severe(message, [Object error, StackTrace stackTrace]) → void Level.SEVEREのログを出力する
shout(message, [Object error, StackTrace stackTrace]) → void Level.SHOUTのログを出力する
warning(message, [Object error, StackTrace stackTrace]) → void Level.CONFIGのログを出力する
log(Level logLevel, message, [Object error, StackTrace stackTrace, Zone zone]) → void ログレベルを指定してログを出力する
ログ出力の例
import 'package:logging/logging.dart';

final log = new Logger('hoge');

main() {
  Logger.root.level = Level.All;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });

  String result = '何らかの結果';
  log.fine('結果が得られました: $result');

  result = null;
  if (result == null) {
    log.severe('何の成果も得られませんでした!!');
  }
}

Loggerのインスタンスを複数作る

Loggerのインスタンスを複数作ることで、用途の違うログ出力を分けることができます。

ログ種類を分けた例
// レンダリング関連のログ
final renderLog = new Logger('render');

// ゲームロジックのログ
final gameLog = new Logger('game');

各Loggerインスタンスごとに出力するログレベルを変える場合は、hierarchicalLoggingEnabledtrueにする必要があります。

ログ種類ごとに出力するログレベルを設定する例
import 'package:logging/logging.dart';

// レンダリング関連のログ
final renderLog = new Logger('render');

// ゲームロジックのログ
final gameLog = new Logger('game');

main() {
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });

  hierarchicalLoggingEnabled = true;

  // レンダリング関連のログを出力しない
  renderLog.level = Level.OFF;
}

ログレベル

ログレベルは、LoggingパッケージのLevelクラスによって定義されていて、このログレベルはLogger.root.levelに設定することで、出力するログレベルをコントロールすることができます。

ログレベル 説明 Level.value
OFF 全てのログ無し 2000
SHOUT デバッグ時に目立つ騒がしいログ 1200
SEVERE 深刻な障害情報 1000
WARNING 問題の可能性があるログ 900
INFO 情報提供 800
CONFIG コンフィグ設定のメッセージ 700
FINE トレース用情報 500
FINER そこそこ詳細なトレース用情報 400
FINEST かなり詳細なトレース用情報 300
ALL すべてのログ 0

上記で設定したログレベルよりもLevel.valueが大きいログが出力されるようになります。

例えば、OFFに設定した場合は、2000より大きいログが無い場合、ログは何も出なくなります。

INFOに設定した場合は、INFO,SEVERE,SHOUTのログが出るようになります。

ログの出力レベルを変更する例
main() {
  Logger.root.level = Level.ALL; // すべてのログを出力する
  Logger.root.level = Level.OFF; // すべてのログを出力しない
  Logger.root.level = Level.INFO; // INFO以上のログを出力する
}

ログ出力先をカスタマイズする

上記の例では、ログを`print'で出力していました。

ログ出力方法の設定の例
import 'package:logging/logging.dart';

final log = new Logger('hoge');

main() {
  Logger.root.level = Level.All;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });
}

これを、例えばListに入れることによって、あとからログを送信する、などと言ったことも可能になります。

ログ出力をprintと合わせてListに入れる例
import 'package:logging/logging.dart';

final log = new Logger('hoge');
final logs = <String>[];

main() {
  Logger.root.level = Level.All;
  Logger.root.onRecord.listen((LogRecord rec) {
    var message = '${rec.level.name}: ${rec.time}: ${rec.message}';
    print(message);
    logs.add(message);
  });
}

ログはデバッグで役立つので、Loggingパッケージを活用していきたいです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
11