web-dev-qa-db-ja.com

通常、ログエントリにどのようにタグを付けますか? (アンドロイド)

ほとんどの人がAn​​droid.util.Logを認識していると思います。すべてのロギングメソッドは、最初の引数として「Stringタグ」を受け入れます。

そして私の質問はアプリケーションでログをどのようにタグ付けするのですか?私はこのようなハードコードを見ました:

public class MyActivity extends Activity {
    private static final String TAG = "MyActivity";
    //...
    public void method () {
        //...
        Log.d(TAG, "Some logging");
    }
}

これは多くの理由で見栄えがよくありません:

  • このコードにはハードコードはありませんが、あります。
  • 私のアプリケーションは、同じ名前の異なるパッケージに任意の数のクラスを持つことができます。そのため、ログを読むのは難しいでしょう。
  • 柔軟ではありません。クラスには常にプライベートフィールドTAGを配置しています。

クラスのTAGを取得する適切な方法はありますか?

80
andrii

TAGを使用しますが、次のように初期化します。

private static final String TAG = MyActivity.class.getName();

この方法でコードをリファクタリングすると、タグもそれに応じて変更されます。

162
gianpi

通常、別のパッケージに配置され、有用な静的メソッドを含むAppクラスを作成します。メソッドの1つはgetTag()メソッドです。これにより、どこでもTAGを取得できます。
Appクラスは次のようになります。

[〜#〜] edit [〜#〜]:br mobコメントごとに改善(ありがとう:))

public class App {

    public static String getTag() {
        String tag = "";
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        for (int i = 0; i < ste.length; i++) {
            if (ste[i].getMethodName().equals("getTag")) {
                tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
            }
        }
        return tag;
    }

}

そして、私がそれを使いたいとき:

Log.i(App.getTag(), "Your message here");

getTagメソッドの出力は、簡単にデバッグできるように、呼び出し元クラスの名前(パッケージ名付き)、およびgetTagの呼び出し元の行番号です。

13
Yaniv

Android Studio->設定->ライブテンプレート-> AndroidLogに移動し、Log.d(TAG、String )

InTemplate textreplace

Android.util.Log.d(TAG, "$METHOD_NAME$: $content$");

Android.util.Log.d("$className$", "$METHOD_NAME$: $content$");

Image of Android menu

次に、変数の編集をクリックし、次にExpression列にclassName()を入力しますclassNameName列に追加します。 image of Android menu 2

ショートカットlogdを入力すると、

Log.d("CurrentClassName", "currentMethodName: ");

もうTAGを定義する必要はありません。

11
Nicolas Manzini

ログがこの形式(filename.Java:XX)xx行番号である場合、エラーが発生したときに同じ方法でショートカットをリンクできるYanivの回答を改善するのが好きですlogcatをクリックするだけで

これを拡張アプリケーションに入れて、他のすべてのファイルで使用できるようにします

public static String getTag() {
    String tag = "";
    final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    for (int i = 0; i < ste.length; i++) {
        if (ste[i].getMethodName().equals("getTag")) {
            tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
        }
    }
    return tag;
}

スクリーンショット:

7
br mob

Sという名前の静的変数、メソッド、クラスのクラスを作成しました。

ロギング方法は次のとおりです。

public static void L(Context ctx, Object s) {
    Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}

任意のクラスでS.L(this, whaterver_object);として呼び出されます。getClass().getName()はパッケージ名も追加するため、タグを不必要に長くしないように削除しています。

利点:

  1. Log.d(TAG,より短い
  2. Int値を文字列に変換する必要はありません。実際にはtoStringと入力する必要はありません
  3. Log.dを削除することを忘れないでください。メソッドを削除するだけで、すべてのログの場所が赤でマークされます。
  4. クラスの名前を取得するため、アクティビティの上部でTAGを定義する必要はありません。
  5. TAGにはCCC(短い、入力しやすい文字列)というプレフィックスが付いているため、Android monitor in Android Studio。サービスまたは他のクラスを同時に実行している場合があります。アクティビティ名だけで検索する必要がある場合、サービス応答が取得され、アクティビティからのアクションがいつ発生したかを正確に確認できません。発生したアクティビティを時系列に記録するので役立ちます
3
suku

メソッド間でコードを移動したり、メソッドの名前を変更したりするときに、これらの文字列を更新することを犠牲にして、次のことをするのが好きです。哲学的には、メッセージではなくタグに「場所」または「コンテキスト」を保持する方が良いようです。

_public class MyClass {

    // note this is ALWAYS private...subclasses should define their own
    private static final LOG_TAG = MyClass.class.getName();

    public void f() {
        Log.i(LOG_TAG + ".f", "Merry Christmas!");
    }

}
_

ここでの利点は、コンテンツが静的ではない場合でも、単一のメソッドを除外できることです。

_Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));
_

唯一の欠点は、f()の名前をg()に変更するとき、その文字列を覚えておく必要があることです。また、自動IDEリファクタリングはこれらをキャッチしません。

しばらくの間、短いクラス名を使用するのが好きでした。つまり、LOG_TAG = MyClass.class.getSimpleName()を意味します。続行するログが少ないため、ログでフィルタリングするのが難しいことがわかりました。

2
tar

AndroidStudioには、デフォルトでlogtテンプレートがあります(logtと入力してTabキーを押すと、コードのコードに展開できます)。これを使用して、別のクラスからTAG定義をコピーペーストし、参照しているクラスの変更を忘れないようにすることをお勧めします。テンプレートはデフォルトで展開されます

_private static final String TAG = "$CLASS_NAME$"_

リファクタリング後に古いクラス名を使用しないようにするには、それを次のように変更できます。

private static final String TAG = $CLASS_NAME$.class.getSimpleName();

[変数の編集]ボタンを確認し、className()式を使用するように_CLASS_NAME_変数が定義され、[定義時にスキップ]がオンになっていることを確認してください。

2
Hemaolle

これは非常に古い質問ですが、2018年7月の更新された回答でさえ、Timberを使用する方が望ましいと考えられています。正しいログを記録するために、FirebaseやCrashlyticsなどのサードパーティのクラッシュライブラリにエラーと警告を送信できます。

Applicationを実装するクラスでは、これを追加する必要があります。

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.DEBUG) {
        Timber.plant(new Timber.DebugTree());
    } else {
        Timber.plant(new CrashReportingTree());
    }
}

/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
    @Override protected void log(int priority, String tag, String message, Throwable t) {
        if (priority == Log.VERBOSE || priority == Log.DEBUG) {
            return;
        }

        FakeCrashLibrary.log(priority, tag, message);

        if (t != null) {
            if (priority == Log.ERROR) {
                FakeCrashLibrary.logError(t);
            } else if (priority == Log.WARN) {
                FakeCrashLibrary.logWarning(t);
            }
        }
    }
}

Timberの依存関係を忘れないでください。

implementation 'com.jakewharton.timber:timber:4.7.1'
1
aleksandrbel

this.toString()を使用して、ログに出力する特定のクラスの一意の識別子を取得できます。

1
kaspermoerch

iOschedアプリ2019にTimberを使用してデバッグ情報を表示します。

implementation 'com.jakewharton.timber:timber:4.7.1'

class ApplicationController: Application() {

override fun onCreate() {  
    super.onCreate()
    if(BuildConfig.DEBUG){
        Timber.plant(Timber.DebugTree())
    }
}   
// enables logs for every activity and service of the application
// needs to be registered in manifest like:  
 <application
    Android:label="@string/app_name"
    Android:name=".ApplicationController"
    ... >

使用法

  Timber.e("Error Message") 
  // will print ->  D/MainActivity: Error Message

  Timber.d("Debug Message");
  Timber.tag("new tag").e("error message");

これにより、ログはDEBUG状態でのみ使用可能になり、Google Playでの起動のためにログを手動で削除するタスクが容易になります-

playストアでアプリをリリースすると、アプリからすべてのLogステートメントを削除する必要があります。これにより、ユーザー情報、非表示のアプリケーションデータ、認証トークンなどのアプリケーションデータがプレーンテキストとしてlogcatでユーザーに利用できなくなります。

この記事をご覧ください https://medium.com/mindorks/better-logging-in-Android-using-timber-72e40cc2293d

0
Dan Alboteanu

この質問にアクセスするユーザーの場合:

private val TAG:String = this.javaClass.simpleName;
0
Pamirzameen