Android--日志工具类

添加crash日志收集功能

package com.example.myapplication.utils;

import android.os.Build;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LogUtils {

    //日志级别
    public static final int VERBOSE = 1;
    public static final int DEBUG = 2;
    public static final int INFO = 3;
    public static final int WARN = 4;
    public static final int ERROR = 5;
    public static final int ASSERT = 6;

    //默认TAG,logcat中的TAG
    private static final String DEFAULT_TAG = "LogUtils";
    //日志最大长度
    private static final int MAX_LENGTH = 1024 * 3;
    //缓冲区队列大小
    private static final int BUFFER_SIZE = 1024;
    //日志文件名
    private static String sLogFileName;
    //本地日志保存路径
    private static String sLogFilePath;
    //线程池
    private static ExecutorService sExecutorService;

    /**
     * 日志初始化,设置日志文件路径和文件名
     * 需要在application的onCreate方法中调用
     *
     * @param path     日志文件路径
     * @param fileName 日志文件名称
     */
    public static void init(String path, String fileName) {
        sLogFileName = fileName;
        sLogFilePath = path;
        checkFilePath();
        //创建一个大小固定为3的线程池
        sExecutorService = Executors.newFixedThreadPool(3);
    }

    /**
     * 检查日志文件目录是否存在,不存在则创建新目录
     */
    private static void checkFilePath() {
        File logFile = new File(sLogFilePath);
        if (!logFile.exists()) {
            boolean isSuccess = logFile.mkdirs();
            if (!isSuccess) {
                Log.e(DEFAULT_TAG, "create log file directory failed.");
            }
        }
    }

    /**
     * 输出VERBOSE日志
     *
     * @param msg 日志内容
     */
    public static void v(String msg) {
        printLog(VERBOSE, DEFAULT_TAG, msg);
    }

    /**
     * 输出VERBOSE日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void v(String tag, String msg) {
        printLog(VERBOSE, tag, msg);
    }

    /**
     * 输出DEBUG日志
     *
     * @param msg 日志内容
     */
    public static void d(String msg) {
        printLog(DEBUG, DEFAULT_TAG, msg);
    }

    /**
     * 输出DEBUG日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void d(String tag, String msg) {
        printLog(DEBUG, tag, msg);
    }

    /**
     * 输出INFO日志
     *
     * @param msg 日志内容
     */
    public static void i(String msg) {
        printLog(INFO, DEFAULT_TAG, msg);
    }

    /**
     * 输出INFO日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void i(String tag, String msg) {
        printLog(INFO, tag, msg);
    }

    /**
     * 输出WARN日志
     *
     * @param msg 日志内容
     */
    public static void w(String msg) {
        printLog(WARN, DEFAULT_TAG, msg);
    }

    /**
     * 输出WARN日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void w(String tag, String msg) {
        printLog(WARN, tag, msg);
    }

    /**
     * 输出ERROR日志
     *
     * @param msg 日志内容
     */
    public static void e(String msg) {
        printLog(ERROR, DEFAULT_TAG, msg);
    }

    /**
     * 输出ERROR日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void e(String tag, String msg) {
        printLog(ERROR, tag, msg);
    }

    /**
     * 输出ASSERT日志
     *
     * @param msg 日志内容
     */
    public static void a(String msg) {
        printLog(ASSERT, DEFAULT_TAG, msg);
    }

    /**
     * 输出ASSERT日志
     *
     * @param tag logcat中TAG
     * @param msg 日志内容
     */
    public static void a(String tag, String msg) {
        printLog(ASSERT, tag, msg);
    }

    /**
     * 打印日志,并写入到本地
     *
     * @param level 日志级别
     * @param tag   logcat中TAG
     * @param msg   日志内容
     */
    private synchronized static void printLog(final int level, final String tag, final String msg) {
        String threadName = Thread.currentThread().getName();
        String logStr = getLogStr(level, tag, msg, threadName);
        Log.println(level, tag, logStr);
        writeLog2File(logStr);
    }

    /**
     * 将日志写入到本地文件
     *
     * @param logStr 日志内容
     */
    private synchronized static void writeLog2File(final String logStr) {
        if (sExecutorService.isShutdown()) {
            sExecutorService = Executors.newFixedThreadPool(3);
        }
        sExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    // 检测日志文件大小是否超出阈值,若超出则清空文件
                    File logFile = new File(sLogFilePath + File.separator + sLogFileName);
                    if (logFile.length() >= MAX_LENGTH) {
                        logFile.delete();
                    }
                    BufferedWriter bw = new BufferedWriter(new FileWriter(logFile, true));
                    bw.write(logStr);
                    bw.flush();
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取完整的日志信息
     *
     * @param level      日志级别
     * @param tag        logcat中TAG
     * @param msg        日志内容
     * @param threadName 线程名
     * @return 完整的日志信息
     */
    private static String getLogStr(int level, String tag, String msg, String threadName) {
        String levelStr = "";
        switch (level) {
            case VERBOSE:
                levelStr = "[V]";
                break;
            case DEBUG:
                levelStr = "[D]";
                break;
            case INFO:
                levelStr = "[I]";
                break;
            case WARN:
                levelStr = "[W]";
                break;
            case ERROR:
                levelStr = "[E]";
                break;
            case ASSERT:
                levelStr = "[A]";
                break;
        }
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
                .format(new Date(System.currentTimeMillis()));
        return "[" + time + "] " + levelStr + " " + tag
                + " [" + threadName + "] " + msg + "\n";
    }

    /**
     * 输出应用崩溃日志到本地文件
     *
     * @param e 异常信息
     */
    public static void writeCrashLog(Throwable e) {
        File file = new File(sLogFilePath + File.separator + "crash.log");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream outputStream = new FileOutputStream(file, true);
            outputStream.write(getThrowableInfo(e).getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }

    /**
     * 获取异常的堆栈信息
     *
     * @param throwable 异常信息
     * @return 异常的堆栈信息
     */
    private synchronized static String getThrowableInfo(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);

        pw.println("-------------------start-------------------");
        pw.println("Time:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
                .format(new Date(System.currentTimeMillis())));
        pw.println("Model:" + Build.MODEL);
        pw.println("Version:" + Build.VERSION.RELEASE);

        throwable.printStackTrace(pw);
        pw.println("--------------------end--------------------");
        return sw.toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值