【Android】ログ出しをちょっとだけ楽にする

# 0. はじめに
Androidでログ出しをする際、個人的に幾つか思うことがあります。

1. ログのレベルってどういう順に高いのだったか？
2. リリース時にはレベルの低いログは消すべきだけど面倒
3. つーかタグを指定するのも面倒

この際、上記についてまとめておこうと思います。
なお、log4jなんかは使わないでAndroid標準のLogクラスで今回は対応します。
（場合によっては使えないこともあるかもしれないですし）

# 1. ログのレベルってどういう順に高いのだったか？
これは公式リファレンスをみれば載ってますが、アメリカ語はあんまり好きではないので表にまとめました。

|略 |アメリカ語|レベル|意味とか|
|:--|:-------|:----|:-----|
|v |VERBOSE  |最低 |冗長なログ<br>リリース時には消すべき|
|d |DEBUG    |低   |デバッグログ<br>リリース時には消すべき|
|i |INFO     |通常 |リリース時にも残すログ<br>アプリの状態とかみたいな残しておきたいこと|
|w |WARN     |高  |リリース時にも残すログ<br>警告|
|e |ERROR    |最高|リリース時にも残すログ<br>やべーやつ|
wとeの使い分けとしては、通常のオペレーションで入力値不正とか発生することが予想できるものがw、そうでないものがeって感じですかね。

# 2. リリース時にはレベルの低いログは消すべきだけど面倒
BuildConfig#DEBUGはリリースビルド時にfalseになってくれるようなので、これを利用します。
こんな感じ

```java
if (BuildConfig.DEBUG) {
    Log.d(LOG_TAG, "hage");
}
```

# 3. つーかタグを指定するのも面倒
2の方法はリリース時は楽ですが、一々書くのが面倒です。
タグを指定することすら面倒な私にはなおさらです。
なので、Logクラスを作ってしまいましょう。

```java:Log.java
import android.os.Build;

public class Log {
    private static final String TAG = "xxxxx";

    /**
     * 冗長なログ<br>
     *     リリースビルド時に出力されない<br>
     *     ログレベル：最低
     * @param msg log message
     */
    public static void v(String msg) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            v(tag, msg);
        } else {
            v(TAG, msg);
        }
    }

    /**
     * 冗長なログ<br>
     *     リリースビルド時に出力されない<br>
     *     ログレベル：最低
     * @param tag log tag
     * @param msg log message
     */
    public static void v(String tag, String msg) {
        if(BuildConfig.DEBUG) {
            android.util.Log.v(tag, msg);
        }
    }

    /**
     * デバッグログ<br>
     *     リリースビルド時に出力されない<br>
     *     ログレベル：低
     * @param msg log message
     */
    public static void d(String msg) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            d(tag, msg);
        } else {
            d(TAG, msg);
        }
    }

    /**
     * デバッグログ<br>
     *     リリースビルド時に出力されない<br>
     *     ログレベル：低
     * @param tag log tag
     * @param msg log message
     */
    public static void d(String tag, String msg) {
        if(BuildConfig.DEBUG) {
            android.util.Log.d(tag, msg);
        }
    }

    /**
     * インフォメーションログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：通常
     * @param msg log message
     */
    public static void i(String msg) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            i(tag, msg);
        } else {
            i(TAG, msg);
        }
    }

    /**
     * インフォメーションログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：通常
     * @param tag log tag
     * @param msg log message
     */
    public static void i(String tag, String msg) {
        android.util.Log.i(tag, msg);
    }

    /**
     * ワーニングログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：高
     * @param msg log message
     */
    public static void w(String msg) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            w(tag, msg);
        } else {
            w(TAG, msg);
        }
    }

    /**
     * ワーニングログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：高
     * @param e exception
     */
    public static void w(Exception e) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            w(tag, e);
        } else {
            w(TAG, e);
        }
    }

    /**
     * ワーニングログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：高
     * @param tag log tag
     * @param e exception
     */
    public static void w(String tag, Exception e) {
        w(tag, exception2String(e));
    }

    /**
     * ワーニングログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：高
     * @param tag log tag
     * @param msg log message
     */
    public static void w(String tag, String msg) {
        android.util.Log.w(tag, msg);
    }

    /**
     * エラーログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：最高
     * @param e exception
     */
    public static void e(Exception e) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            e(tag, e);
        } else {
            e(TAG, e);
        }
    }

    /**
     * エラーログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：最高
     * @param msg log message
     */
    public static void e(String msg) {
        StackTraceElement[] ste = new Throwable().getStackTrace();
        if(ste.length >= 2) {
            String tag = ste[1].getFileName();
            tag = tag.substring(0, tag.length()-5);
            if(tag.length() > 23 && Build.VERSION.SDK_INT <= 23) {
                tag = tag.substring(0, 23);
            }
            e(tag, msg);
        } else {
            e(TAG, msg);
        }
    }

    /**
     * エラーログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：最高
     * @param tag log tag
     * @param e exception
     */
    public static void e(String tag, Exception e) {
        e(tag, exception2String(e));
    }

    /**
     * エラーログ<br>
     *     リリースビルド時に出力される<br>
     *     ログレベル：最高
     * @param tag log tag
     * @param msg log message
     */
    public static void e(String tag, String msg) {
        android.util.Log.e(tag, msg);
    }

    private static String exception2String(Exception e) {
        StringBuilder sb = new StringBuilder();
        sb.append(e.toString());
        sb.append("\n");
        for(StackTraceElement ste : e.getStackTrace()) {
            sb.append("    ");
            sb.append(ste.toString());
            sb.append("\n");
        }
        return sb.toString();
    }
}
```

これにBuildConfigをimportすれば多少は楽できるはず。
（APIレベルが23以下だとタグに文字数制限があるのでちょっと不格好な気がする...）

# 98. 参考
Log | https://developer.android.com/reference/android/util/Log.html
AndroidのLogを使う時のちょっと便利な方法 | http://htomiyama.blogspot.jp/2013/01/androidlog.html
スタックトレースから呼び出し元の情報を取得する（java） | https://qiita.com/Qui/items/467bb09211772e343c59
AndroidOSのバージョン（APIレベル）によって処理を変える方法 | https://nobuo-create.net/api/

# 99. 更新履歴
|日付|変更内容|
|:--|:--|
|2018/03/06|投稿|