AndroidのLogクラスをカスタマイズ

Androidでアプリ開発を使用する場合、ログ出力機能としてLogクラスのdメソッドやeメソッドを使用します。Logクラスはパッケージ名、タグ、メッセージを保存します。
Logクラスをフィルタリング等を使用できるようにカスタマイズしてみます。

githubにコードを置きました。

 

1. Logのラッパークラス

Logクラスは自動でimportされないようになっています。そこで内部でLogクラ スを呼び出すラッパークラスを作成します。

+ public class SampleLog {
+ 
+   public static void d(String tag, String msg) {
+     Log.d(tag, msg);
+   }
+ 
+ }

2. タグの自動生成

Logクラスを使用していると引数のタグを逐一用意する必要があります。タグ はフィルタリングで有用なので、ぜひ使いたいところですが、逐一用意するの が少々面倒です。
通常、タグはクラス名が使われると思います。そこで、スタック領域からファ イル名とコードの行数を取得し、タグとして使用するようにします。 d(String msg)メソッドではタグにファイル名とコードの行数を設定します。

public class SampleLog {
+ 
+   private static String getTag() {
+     Throwable throwable = new Throwable();
+     StackTraceElement[] stack = throwable.getStackTrace();
+     return stack[2].getFileName() + "[" + stack[2].getLineNumber() + "]";
+   }
  
  public static void d(String tag, String msg) {
    Log.d(tag, msg);
  }
+ 
+   public static void d(String str) {
+     d(getTag(), str);
+   }
  
}

3. ログ出力を抑制するフラグ

ログは処理が重くなりがちな為、リリースビルドやリファクタリングでデバッ グで用いていたLogクラスを取り除くことになるでしょう。 しかし、実際に問題が起こった場合に困ることがあります。そこで重要な箇所 にはLogクラスを埋めておき、外部からのフラグ操作によってログ出力を制御 するのが良いでしょう。

public class SampleLog {
+ 
+   private boolean mDebug;
+ 
+   static {
+     mDebug = true;
+   }
+
+   public void setDebug(boolean enable) {
+     mDebug = enable;
+   }
 
  private static String getTag() {
    Throwable throwable = new Throwable();
    StackTraceElement[] stack = throwable.getStackTrace();
    return stack[2].getFileName() + "[" + stack[2].getLineNumber() + "]";
  }
  
  public static void d(String tag, String msg) {
+     if (mDebug)
+       Log.d(tag, msg);
-     Log.d(tag, msg);
  }
 
  public static void d(String str) {
    d(getTag(), str);
  }
  
}

上記のsetDebug(boolean enable)をActivityのメニューから呼び出すようにす れば、スマートフォン上の操作でログ出力を制御できます。

4. ログ出力のフィルタリング

eclipseやandroid-mode.elでlogcatの出力のフィルタリングが可能です。 ここではそもそものLogクラスへの出力をフィルタリングするようにします。 フィルタリングはタグとメッセージにフィルタリング文字列が含まれるか含ま れないかで判定します。

public class SampleLog {
 
  private boolean mDebug;
  private static String mFilter;
 
  static {
    mDebug = true;
+    mFilter = null;
  }
+ 
+   private static boolean isFiltered(String tag, String str) {
+     if (mFilter == null)
+       return true;
+     if (tag.indexOf(mFilter) != -1)
+       return true;
+     return str.indexOf(mFilter) != -1;
+   }
  
  public void setDebug(boolean enable) {
    mDebug = enable;
  }
 
  private static String getTag() {
    Throwable throwable = new Throwable();
    StackTraceElement[] stack = throwable.getStackTrace();
    return stack[2].getFileName() + "[" + stack[2].getLineNumber() + "]";
  }
  
  public static void d(String tag, String msg) {
+     if (mDebug && isFiltered(tag, str))
-     if (mDebug)
      Log.d(tag, msg);
  }
 
  public static void d(String str) {
    d(getTag(), str);
  }
  
}

フィルタリング文字列のUIを用意すれば、スマートフォン上でログ出力のフィ ルタリングを制御できます。 タグとメッセージのフィルタリング文字列を別々すればさらに詳細なフィルタ リングが可能になります。