解析 - デバッグ ログ android




Androidアプリケーションからクラッシュデータを取得するにはどうすればよいですか? (20)

Android 2.2では、Androidマーケットアプリケーションからクラッシュレポートを自動的に取得できるようになりました:

Androidマーケットアプリの新しいバグレポート機能により、開発者はクラッシュやユーザーからのレポートのフリーズを受けることができます。 レポートは、サイト運営者のアカウントにログインすると利用できるようになります。

http://developer.android.com/sdk/android-2.2-highlights.html

Androidアプリケーションからクラッシュデータ(少なくともスタックトレース)を取得するにはどうすればよいですか? 少なくとも私自身のデバイスをケーブルで取り込んで作業しているが、理想的には私のアプリケーションを野生で実行しているので、それを改善してより強固にすることができます。


Google Playデベロッパーコンソールでは、実際にクラッシュしてレポートを送信したアプリからスタックトレースを得ることができます。また、その情報を表示するのに役立つグラフもあります。下記の例をご覧ください。


BugSenseを試すこともできます。 BugSenseはすべてのクラッシュレポートを収集して分析し、意味のある視覚的なレポートを提供します。 それは無料で、統合するには1行のコードしかありません。

免責事項:私は共同設立者です



Sherlockというアンドロイドライブラリがあります。 それは、デバイスとアプリケーションの情報と一緒にクラッシュの完全なレポートを提供します。 クラッシュが発生するたびに、通知バーに通知が表示され、通知がクリックされるとクラッシュの詳細が表示されます。 電子メールやその他の共有オプションを使用して、クラッシュの詳細を他のユーザーと共有することもできます。

インストール

android {
    dataBinding {
      enabled = true
    }
}

compile('com.github.ajitsing:sherlock:[email protected]') {
    transitive = true
}

デモ


あなたのアプリが他の人によってダウンロードされていて、リモートデバイスでクラッシュしている場合は、Androidのエラー報告ライブラリ( このSOの記事で参照されています)を調べるとよいでしょう。 自分のローカルデバイス上にある場合は、LogCatを使用できます。 クラッシュが発生したときにデバイスがホストマシンに接続されていなくても、デバイスを接続してadb logcatコマンドを実行すると、ログデータの履歴がバッファされます、それはちょうど無限ではない)。 これらのオプションのいずれかがあなたの質問に答えていますか? そうでない場合は、もう少し探しているものを明確にしようとすることができますか?


このページの回答の多くは便利ですが、古くなってしまうのは簡単です。 AppBrainのWebサイトには、最新の最も一般的なクラッシュレポートソリューションを見つけるための統計が集約されています。

Androidクラッシュレポートライブラリ

この画像を投稿した時点で、Crashlyticsはアプリの5.24%とインストールの12.38%で使用されていることがわかります。


この回答を見つけるのを助けてくれたリソースをありがとう。

リモートのAndroidクラッシュレポートは、電子メールに直接表示されますあなたの電子メールをCustomExceptionHandlerクラスの中入れなければならないことを思い出してください。

public static String sendErrorLogsTo = "[email protected]" ;

必要な手順:

第1回)あなたの活動のonCreateであなたのコードのこのセクションを使用してください。

    if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
    }   

2nd)私のphpscriptによると、(rrainn)のCustomExceptionHandlerクラスのこのオーバーライドされたバージョンを使用します。

package com.vxmobilecomm.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;
    public static String sendErrorLogsTo = "[email protected]" ;

    Activity activity;

    public CustomExceptionHandler(Activity activity) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.activity = activity;
    }

    public void uncaughtException(Thread t, Throwable e) {

        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = "error" + System.nanoTime() + ".stacktrace";

        Log.e("Hi", "url != null");
        sendToServer(stacktrace, filename);

        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString() + "\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i = 0; i < arr.length; i++) {
            report += "    " + arr[i].toString() + "\n";
        }
        report += "-------------------------------\n\n";

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if (cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i = 0; i < arr.length; i++) {
                report += "    " + arr[i].toString() + "\n";
            }
        }
        report += "-------------------------------\n\n";

        defaultUEH.uncaughtException(t, e);
    }

    private void sendToServer(String stacktrace, String filename) {
        AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
                getAppLable(activity));
        async.execute("");
    }

    public String getAppLable(Context pContext) {
        PackageManager lPackageManager = pContext.getPackageManager();
        ApplicationInfo lApplicationInfo = null;
        try {
            lApplicationInfo = lPackageManager.getApplicationInfo(
                    pContext.getApplicationInfo().packageName, 0);
        } catch (final NameNotFoundException e) {
        }
        return (String) (lApplicationInfo != null ? lPackageManager
                .getApplicationLabel(lApplicationInfo) : "Unknown");
    }

    public class AsyncTaskClass extends AsyncTask<String, String, InputStream> {
        InputStream is = null;
        String stacktrace;
        final String filename;
        String applicationName;

        AsyncTaskClass(final String stacktrace, final String filename,
                String applicationName) {
            this.applicationName = applicationName;
            this.stacktrace = stacktrace;
            this.filename = filename;
        }

        @Override
        protected InputStream doInBackground(String... params) 
        { 
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(
                    "http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php?");

            Log.i("Error", stacktrace);

            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                        6);

                nameValuePairs.add(new BasicNameValuePair("data", stacktrace));
                nameValuePairs.add(new BasicNameValuePair("to",sendErrorLogsTo));
                nameValuePairs.add(new BasicNameValuePair("subject",applicationName));

                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                HttpResponse response = httpclient.execute(httppost);

                HttpEntity entity1 = response.getEntity();

                BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
                        entity1);

                is = bufHttpEntity.getContent();

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return is;
        }

        @Override
        protected void onPostExecute(InputStream result) {
            super.onPostExecute(result);

            Log.e("Stream Data", getStringFromInputStream(is));
        }
    }

    // convert InputStream to String
    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

これは非常にまじめですが、どこでもlogcatを実行することができます。したがって、 getRuntime().exec("logcat >> /sdcard/logcat.log");キャッチブロックにgetRuntime().exec("logcat >> /sdcard/logcat.log");に追加することができgetRuntime().exec("logcat >> /sdcard/logcat.log");


これらの例外をThread.setDefaultUncaughtExceptionHandler()で処理することは可能ですが、これはAndroidの例外処理メソッドを混乱させるようです。 私はこの性質のハンドラを使用しようとしました:

private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable ex){
        Log.e(Constants.TAG, "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);

        //hack to rethrow unchecked exceptions
        if(ex instanceof RuntimeException)
            throw (RuntimeException)ex;
        if(ex instanceof Error)
            throw (Error)ex;

        //this should really never happen
        Log.e(Constants.TAG, "uncaught_exception handler: unable to rethrow checked exception");
    }
}

しかし、例外を再発行しても、目的の動作を得ることができませんでした。つまり、Androidでのコンポーネントのシャットダウンを許可しながら例外をログに記録しました。


さて、私はrrainnとSoonilから提供されたサンプルを調べました。エラー処理を混乱させない解決策を見つけました。

CustomExceptionHandlerを変更して、新しいものを関連付けるスレッドから元のUncaughtExceptionHandlerを保存するようにしました。 新しい "uncaughtException"の最後に - メソッド私はちょうど格納されているUncaughtExceptionHandlerを使って古い関数を呼び出します。

DefaultExceptionHandlerクラスでは、sthが必要です。 このような:

public class DefaultExceptionHandler implements UncaughtExceptionHandler{
  private UncaughtExceptionHandler mDefaultExceptionHandler;

  //constructor
  public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)
  {
       mDefaultExceptionHandler= pDefaultExceptionHandler;
  }
  public void uncaughtException(Thread t, Throwable e) {       
        //do some action like writing to file or upload somewhere         

        //call original handler  
        mStandardEH.uncaughtException(t, e);        

        // cleanup, don't know if really required
        t.getThreadGroup().destroy();
  }
}

このコードをhttp://code.google.com/p/android-remote-stacktraceのコードに変更すると、WebサーバーまたはSDカードにフィールドにログインするための良い作業基盤が得られます。


すぐに回答が必要な場合は、 logcat

$adb shell logcat -f /sdcard/logoutput.txt *:E

あなたのログにあまりにも多くの迷惑メールがある場合は、最初にクリアしてみてください。

$adb shell logcat -c

その後、あなたのアプリを実行してから再度ログインしてみてください。


また、ライブラリだけでなく、全体(単純な)サービスを使用することもできます。 当社はちょうどそれのためのサービスをリリースしました: http : //apphance.com

それはあなたが追加して5分で統合する単純な.jarライブラリ(Android用)を持っています。そして、ライブラリはクラッシュ情報だけでなく実行中のアプリケーションからのログも収集します。全体のコンテキスト(デバイスの回転、無線LANに接続されているかどうかなど) 非常に便利なWebパネルを使用してログを見ることができます。ここでは、アプリケーション、クラッシュ、ログ、統計などのセッションを追跡できます。 このサービスは現在クローズドベータテスト段階にありますが、アクセスをリクエストすることができ、非常に迅速に対応します。

免責事項:私はPolideaのCTOであり、サービスの共同制作者です。


エラーレポートを追跡するための素晴らしいWebアプリケーションを見つけました。

https://mint.splunk.com/

構成するための少数のステップ。

  1. 上記のリンクを使用してログインまたはサインアップして設定してください。 アプリケーションの作成が完了したら、以下のように構成する行を提供します。
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. アプリケーションのbuild.gradlに次を追加します。
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. 上記でコピーしたコードを追加し、すべてのアクティビティに追加します。

    Mint.initAndStartSession(YourActivity.this、 "api_key");

それでおしまい。 ログインしてアプリケーションダッシュボードにアクセスすると、すべてのエラーレポートが表示されます。

誰かを助けることを願っています。


ファブリックと呼ばれるツールがあります。これはクラッシュ解析ツールで、アプリケーションのライブデプロイメントや開発中にクラッシュレポートを取得できます。 このツールをアプリケーションに追加するのは簡単でした。アプリケーションがクラッシュした場合、クラッシュのレポートはfabric.ioダッシュボードから表示できます。 レポートは自動的にキャッチされました。ユーザーに許可を求めることはありません。 彼/彼女がバグ/クラッシュレポートを送信するかどうか。 これは完全に無料です... https://get.fabric.io/


今のFirebaseのクラッシュレポートは非​​常に人気があり、使いやすくなっています。 詳細については、次のリンクを参照してください。Firebaseクラッシュレポート

それがあなたを助けることを願っています。


私たちは自社製のシステムを社内で使用しています。 レポートを受け取って分析を行うサーバーやサーバーにクラッシュレポートを送信するアンドロイドライブラリです。 サーバーは、例外名、スタックトレース、メッセージで例外をグループ化します。 修正が必要な最も重要な問題を特定するのに役立ちます。 私たちのサービスは誰でも試すことができるように公開されています。 http://watchcat.coでアカウントを作成するか、デモアクセスhttp://watchcat.co/reports/index.php?demoを使ってどのように動作するかを見てhttp://watchcat.co/reports/index.php?demo


私はAndroidとiOSのアプリにCrittercismを使っています。彼らはtechcrunchについて聞いています。 これまでのところとても幸せです!


私はこの目的のために設計したBugsnagの創設者の一人です。 Bugsnagは、Androidアプリで未処理の例外を自動的にキャプチャし、Googleのダッシュボードに送信します。ダッシュボードでは、修正を優先して診断情報を得ることができます。

クラッシュ報告システムを選択または構築する際に考慮すべきいくつかの重要な事項と、いくつかのコードスニペットがあります。

  • 未処理の例外を自動的に検出する( サンプルコード
  • メモリ使用量、デバイス情報などの診断データを収集します( サンプルコード )。
  • 根本的な原因による効果的なグループ分け
  • 再現を助けるために各クラッシュ前にユーザーが取ったアクションを追跡できます( サンプルコード

Androidでクラッシュ処理/レポートに関するいくつかのベストプラクティスを見たい場合は、完全にオープンソースのBugsnagのクラッシュレポートライブラリの完全なソースコードをチェックしてください。自由に気を付けて、独自のアプリケーションで使用してください!


私はその質問が古すぎることを知り、私の答えが同じ問題を抱えている他の人にとって有益であることを願っています...

Crashlyticsを試してみてください。 それはあなたのアプリケーションを持っているすべてのデバイス上のすべてのクラッシュに精通した洞察力を与え、電子メールを介して通知を送信します..そして、最高の部分は完全に無料です..





stack-trace