【安卓笔记】崩溃日志收集

应用发布之后,总有人反馈说发生crash,但是由于拿不到log,我无法定位问题。后来发现,我们应该收集crash日志,并上传到服务器。

国内有很多的三方机构提供了崩溃收集的sdk,我们可以直接拿来使用,比如,我之前做的app使用的是bugHD(http://bughd.com/)提供的服务。

但是崩溃收集的原理是什么呢?搜索了一下,发现使用的是java中的uncaughtExceptionHandler,我们可以通过Thread.setDefautUncaughtExceptionHandler()设置我们自己的UncaughtExceptionHandler。它其实是一个接口,实现方法即可。

我写的一个demo:

import android.os.Looper;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
/**
 * Created by Rowandjj on 2015/5/19.
 *
 * 崩溃日志收集
 */
public class CrashHandler implements Thread.UncaughtExceptionHandler
{
    private static CrashHandler sInstance = null;
    private static Object lock = new Object();
    private Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
    private CrashHandler()
    {
    }
    public static CrashHandler getInstance()
    {
        if (sInstance == null)
        {
            synchronized (lock)
            {
                if (sInstance == null)
                    sInstance = new CrashHandler();
            }
        }
        return sInstance;
    }
    public void register()
    {
        mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    @Override
    public void uncaughtException(Thread thread, Throwable ex)
    {
        //生成日志
        final String filename = cacheLog(ex);
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                Looper.prepare();
                if(filename != null)
                    Toast.makeText(AppEnv.getAppContext(),"程序崩溃了:( \n崩溃日志已保存到"+filename+"",Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }).start();
        try
        {
            Thread.sleep(2000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        mDefaultExceptionHandler.uncaughtException(thread,ex);
    }
    private String cacheLog(Throwable ex)
    {
        if(ex == null)
            return null;
        Map<String, String> hardwareInfo = HardwareUtils.getHardwareInfo();
        StringBuilder buffer = new StringBuilder();
        for (Map.Entry<String, String> me : hardwareInfo.entrySet())
        {
            buffer.append(me.getKey() + ":" + me.getValue() + "\n");
        }
        buffer.append("packname:" + AppEnv.getPackageName() + "\n");
        buffer.append("versionname:" + AppEnv.getVersionName() + "\n");
        buffer.append("versioncode:" + AppEnv.getVersionCode() + "\n");
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null)
        {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        buffer.append(result);
        long timestamp = System.currentTimeMillis();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA);
        String time = formatter.format(new Date());
        String filename = "crash-" + time + "-" + timestamp + ".log";
        File file = new File(BasicUtils.getStoreDir(), filename);
        try
        {
            if (!file.exists())
                file.createNewFile();
            FileOutputStream out = new FileOutputStream(file);
            out.write(buffer.toString().getBytes());
            out.close();
            Logger.d(this,file.getAbsolutePath());
            return file.getAbsolutePath();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }
}

然后在你应用的Application中调用

CrashHandler.getInstance().register();

即可。

应用出现crash时,会把log保存到本地。如果希望上传到服务器,加上一个http上传模块即可。

部分代码没有贴出,大家自己脑补。

时间: 2024-11-09 22:13:03

【安卓笔记】崩溃日志收集的相关文章

android app崩溃日志收集以及上传

源码获取请到github:https://github.com/DrJia/AndroidLogCollector 已经做成sdk的形式,源码已公开,源码看不懂的请自行google. 如果想定制适应自己app的sdk请自行fork. AndroidLogCollector android app崩溃日志收集sdk 1.0 作者:贾博士 崩溃日志收集方法: 1.LogCollector是lib包,在需要添加崩溃日志sdk的工程中导入此包. 2.导入lib后,在自己的工程的AndroidManife

日志收集系统Flume调研笔记第1篇 - Flume简介

用户行为数据的收集无疑是构建推荐系统的先决条件,而Apache基金会下的Flume项目正是为分布式的日志收集量身打造的,本文是Flume调研笔记的第1篇,主要介绍Flume的基本架构,下篇笔记将会以实例说明Flume的部署和使用步骤. 本文所用的Flume版本为目前最新版的ver1.5.2,它属于Flume-NG,在系统架构上与Flume-OG有所区别,二者的不同可以参考FlumeWiki文档的说明. 1. Flume是什么 Flume是Apache基金会下的一个开源项目,它实现了一套分布式的.

分布式日志收集之Logstash 笔记(一)

(一)logstash是什么? logstash是一种分布式日志收集框架,开发语言是JRuby,当然是为了与Java平台对接,不过与Ruby语法兼容良好,非常简洁强大,经常与ElasticSearch,Kibana配置,组成著名的ELK技术栈,非常适合用来做日志数据的分析. 当然它可以单独出现,作为日志收集软件,你可以收集日志到多种存储系统或临时中转系统,如MySQL,redis,kakfa,HDFS, lucene,solr等并不一定是ElasticSearch. 官网下载地址:https:/

【Android应用开发】 Android 崩溃日志 本地存储 与 远程保存

示例代码下载 : http://download.csdn.net/detail/han1202012/8638801; 一. 崩溃日志本地存储 1. 保存原理解析 崩溃信息本地保存步骤 : -- 1. 自定义类实现 UncaughtExceptionHandler : public class CrashHandler implements UncaughtExceptionHandler; -- 2. 设置该自定义的 CrashHandler 类为单例模式 : // 单例模式 private

使用dSYM分析App崩溃日志

前言 我们在开发App过程中,因为连接到控制台,所以遇到问题会很容易找到问题代码.但是对于线上的App出现Crash的时候,我们不可能通过这种方式,也不现实,所以我们只能通过收集Crash信息,来解决Bug.而这种收集Crash信息并且分析定位到具体代码的第三方SDK很多.但是今天我们来自己实现一下. 收集 Crash 信息 Apple提供了NSException类来帮助我们收集异常信息. NSException is used to implement exception handling a

日志收集系统 ELK

查看日志一直都是一个很困扰的问题,登录到服务器上查看几百兆的txt文件,从中找到某个问题可能会留下的日志记录......   尤其是现在,在集群式部署的服务器原来越多的时候,找到一个异常记录几乎要翻遍每一台服务器,想想就崩溃了!这个时候就特别希望能有一个集中查看日志的方案来拯救我. 曾经找到一个名为log4Grid的项目,试用了一下.日志数据都保存到mssql数据库中,通过一个web项目来查询显示日志记录.只是实现了基本的日志数据收集和显示,项目没有持续更新,使用起来也不够稳定.不是一个成熟的日

iOS 应用崩溃日志分析

通过本教程,你将学习到一些常见的崩溃日志案例,以及如何从开发设备和iTunes Connect上获取崩溃日志文件.你还将学习到符号化( symbolication),从日志追踪到代码 .你还将学习调试一个在待定情况下会闪退的应用. 让我们开始动手吧! 什么是崩溃日志,从哪里能得它? iOS设备上的应用闪退时,操作系统会生成一个崩溃报告,也叫崩溃日志,保存在设备上. 崩溃日志上有很多有用的信息,包括应用是什么情况下闪退的.通常,上面有每个正在执行线程的完整堆栈跟踪信息,所以你能从中了解到闪退发生时

日志收集以及分析:Splunk

写代码的人都知道日志很重要,机器不多的时候,查看日志很简单,ssh 上去 grep + awk + perl 啥的 ad hoc 的搞几把就行,但面对上百台甚至上千台机器时,如何有效的收集和分析日志就成了个很头疼的事情.日志处理必然有如下过程: 从各个服务器读取日志 把日志存放到集中的地方 挖掘日志数据,用友好的 UI 展示出来,最好能做到实时的输入表达式做过滤.聚合 下面分三个方面聊聊,整个过程是需要多方配合的,包括写日志.读日志.转储日志.分析日志,注意聊这些的背景是互联网行业,机器多,日志

Rsyslog日志收集服务并结合Loganalyzer工具展示

一.日志概述 1.rsyslog简介 syslog是日志收集存储系统,负责记录遵守此服务的内核.程序的日志信息.一般记录为:"日期时间,主机,进程:事件".syslog不仅可以记录本地的系统日志,也可以通过tcp, udp协议记录远程主机的程序日志信息. syslog:系统日志,是一种服务,有两个进程 syslogd:记录应用程序相关的日志 klogd:记录内核相关的日志 rsyslog:是syslog的升级版,使用多线程并发记录本地或远程日志,支持存储日志信息在MySQL,PGSQL