はじめに

こんにちは、Rerurate_514と申します。

今回はログをとるのに、mixinが便利だった話をしようと思います。mixinは普段のOOPには向いていませんが(ゲーム以外)、ロギングなどには便利かと思います。

やり方

まず、任意のロガーパッケージを追加します。

  • logger
  • talker
  • logging
    などありますが、今回はloggerを使用します。

おそらく、これが最も簡単なロギングですかね。

dart pub add logger

まず、このloggingを使用するインスタンスを追加します。

import 'package:logger/logger.dart';
 
final logger = Logger(
  printer: PrettyPrinter(
    methodCount: 2,
    errorMethodCount: 8,
    lineLength: 120,
    colors: true,
    printEmojis: true,
  ),
);

プロパティの説明は面倒くさいので、AIに投げます。

プロパティ名設定値説明
methodCount2通常時のログに表示するスタックトレース(呼び出し元)の数。
errorMethodCount8エラー発生時に表示するスタックトレースの数。より深く原因を追える。
lineLength120ログを囲む枠線の幅(文字数)。120は広めの設定。
colorstrueログレベル(Info, Error等)に応じてコンソールの文字に色を付ける。
printEmojistrueログの先頭に絵文字(💡, ⚠️, ⛔など)を表示し、視認性を高める。

そして実際にmixinするクラスを追加します。

mixin MyLogger {
  void debug(dynamic message) {
    logger.d(message);
  }
 
  void info(dynamic message) {
    logger.i(message);
  }
 
  void warning(dynamic message) {
    logger.w(message);
  }
 
  void error(dynamic message, [dynamic error, StackTrace? stackTrace]) {
    logger.e(message, error: error, stackTrace: stackTrace);
  }
 
  void fatal(dynamic message) {
    logger.f(message);
  }
}

mixinをするクラスはclassキーワードの代わりに、mixinと書きます。

これを実際のクラスで使用するときは、

class ApiRepositoryImpl extends IApiRepository with MyLogger { 
	Future<void> fetchData() async {
		try { 
			info('API通信を開始します'); 
		} catch (e) {
			error('データの取得に失敗しました: $e'); 
		}
	}
}

のように書きます。こうすることで、ログをとるためだけにloggerインスタンスのDIをしないで、ロガーが簡単になります。

DIをしないということは、mockitoなどを使用してテストを行うときに、書き方が簡単になります。まあ、mock化しなくていいってだけですが。。