ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android 日志工具

2021-03-12 18:02:20  阅读:177  来源: 互联网

标签:String 工具 TAG static msg Android 日志 Log


目标实现功能

  • 打印日志到控制台和文件中
  • 日志支持在logcat 窗口 有链接跳转到对应的位置,文件中就直接拷贝内容到logcat 窗口 也支持链接
  • 文件支持设置文件大小和最大数量

使用方法:

LogUtil.d("process------------>");

一共有两个文件LogUtil和LogFileUtil,代码如下:

import android.util.Log;
/**
 * 输出各种级别的log到控制台
 * msg字符长度不受限制,默认的Log是受限制的,超过的部分不输出
 * 输出的log头有链接,可以点击链接到执行代码文件位置
 * 可以直接输出msg,使用默认Tag
 * 支持设置 LEVEL,小于LEVEL级别以下不再打印log
 */
public class LogUtil {
    private static final String TAG = "LogUtil";
    public static int LEVEL = Log.VERBOSE;
    public static void v(String TAG, String msg) {
        if (LEVEL <= Log.VERBOSE) {
            logWithLink(Log.VERBOSE, TAG, msg);
        }
    }
    public static void d(String TAG, String msg) {
        if (LEVEL <= Log.DEBUG) {
            logWithLink(Log.DEBUG, TAG, msg);
        }
    }
    public static void i(String TAG, String msg) {
        if (LEVEL <= Log.INFO) {
            logWithLink(Log.INFO, TAG, msg);
        }
    }
    public static void w(String TAG, String msg) {
        if (LEVEL <= Log.WARN) {
            logWithLink(Log.WARN, TAG, msg);
        }
    }
    public static void e(String TAG, String msg) {
        if (LEVEL <= Log.ERROR) {
            logWithLink(Log.ERROR, TAG, msg);
        }
    }
    public static void v(String msg) {
        if (LEVEL <= Log.VERBOSE) {
            logWithLink(Log.VERBOSE, TAG, msg);
        }
    }
    public static void d(String msg) {
        if (LEVEL <= Log.DEBUG) {
            logWithLink(Log.DEBUG, TAG, msg);
        }
    }
    public static void i(String msg) {
        if (LEVEL <= Log.INFO) {
            logWithLink(Log.INFO, TAG, msg);
        }
    }
    public static void w(String msg) {
        if (LEVEL <= Log.WARN) {
            logWithLink(Log.WARN, TAG, msg);
        }
    }
    public static void e(String msg) {
        if (LEVEL <= Log.ERROR) {
            logWithLink(Log.ERROR, TAG, msg);
        }
    }
    //Log输出的最大长度
    private static int LOG_MAX_LENGTH = 2000;//2000
    /**
     * 循环打印log,解决msg过长不打印问题
     */
    private static void LogWrapperLoop(int logPriority, String TAG, String msg) {
        int msgLength = msg.length();
        /**
         * adb  lgh=3
         *  ^
         *  |   index=1
         * print a
         */
        int index = 0;//输出字符的位置
        while (index < msgLength) {
            if (index + LOG_MAX_LENGTH > msgLength) {
                LogWrapper(logPriority, TAG, msg.substring(index, msgLength));
            } else {
                LogWrapper(logPriority, TAG, msg.substring(index, index + LOG_MAX_LENGTH));
            }
            index += LOG_MAX_LENGTH;
        }
    }
    private static void LogWrapper(int logPriority, String TAG, String msg) {
        switch (logPriority) {
            case Log.VERBOSE:
                LogFileUtil.v(TAG, msg);
                Log.v(TAG, msg);
                break;
            case Log.DEBUG:
                LogFileUtil.d(TAG, msg);
                Log.d(TAG, msg);
                break;
            case Log.INFO:
                LogFileUtil.i(TAG, msg);
                Log.i(TAG, msg);
                break;
            case Log.WARN:
                LogFileUtil.w(TAG, msg);
                Log.w(TAG, msg);
                break;
            case Log.ERROR:
                LogFileUtil.e(TAG, msg);
                Log.e(TAG, msg);
                break;
            case Log.ASSERT:
                break;
            default:
                break;
        }
    }
    /**
     * 带有链接的log打印
     */
    private static void logWithLink(int logPriority, String TAG, String msg) {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        int index = 4;
        String className = stackTrace[index].getFileName();
        String methodName = stackTrace[index].getMethodName();
        int lineNumber = stackTrace[index].getLineNumber();
        methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[ (").append(className).append(":").append(lineNumber).append(")#").append(methodName).append(" ] ");
        stringBuilder.append(msg);
        String logStr = stringBuilder.toString();
        LogWrapperLoop(logPriority, TAG, logStr);
    }
}
import android.util.Log;

import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.concurrent.Executors;

/**
 * 将日志打印到文件:
 * <p>
 * 支持设置文件最大大小LOG_SIZE_MAX  KB,超过大小重新创建文件(由于文件名是以毫秒为维度理论不会重复)
 * 支持文件总个数LOG_FILE_TOTAL,超过总个数删除最先创建的文件
 * 支持设置日志文件输出目录LOG_FILE_PRINT_DIR
 */
public class LogFileUtil {
    // 日志文件总数
    private static final int LOG_FILE_TOTAL = 10;
    // 单日志文件大小上限 KB
    private static final long LOG_SIZE_MAX = 5 * 1024;
    // 日志文件输出文件夹
    private static final String LOG_FILE_PRINT_DIR = "/sdcard/MyProject/log/info/";
    // 文件名格式
    private static final SimpleDateFormat FILE_NAME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss-SSS");
    //创建一个可重用固定线程数的线程池
    private static java.util.concurrent.ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

    public static final void v(String TAG, String msg) {
        printLog("VERBOSE", TAG, msg);
    }
    public static final void d(String TAG, String msg) {
        printLog("DEBUG", TAG, msg);
    }
    public static final void i(String TAG, String msg) {
        printLog("INFO ", TAG, msg);
    }
    public static final void w(String TAG, String msg) {
        printLog("WARN ", TAG, msg);
    }
    public static final void e(String TAG, String msg) {
        printLog("ERROR", TAG, msg);
    }
    private static void printLog(final String level, final String TAG, final String msg) {
        singleThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    FileWriter fileWriter = new FileWriter(getFile(), true);
                    fileWriter.write(formatLog(level, TAG, msg));
                    fileWriter.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

    }

    //格式化日志
    private static String formatLog(String level, String TAG, String msg) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        StringBuilder builder = new StringBuilder();
        builder.append(dateFormat.format(new Date(System.currentTimeMillis())) + " ");
        builder.append("[" + level + "] ");
        builder.append("[" + TAG + "] ");
        builder.append(msg);
        builder.append("\n");
        return builder.toString();
    }

    // 获取需要输出的日志文件
    private static File getFile() {
        // 确认文件夹是否存在
        File fileDir = new File(LOG_FILE_PRINT_DIR);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        // 获取文件夹下的日志文件
        File[] fileList = fileDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".log");
            }
        });
        int fileCount = fileList == null ? 0 : fileList.length;

        // 没有日志文件时,直接创建新文件
        if (fileCount == 0) {
            return createLogFile();
        }
        // 只有一个日志文件时
        if (fileCount == 1) {
            return isCreateLogFile(fileList[0]);
        }
        // 对日志排序,排序结果为升序
        Arrays.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File file1, File file2) {
                String file1Name = "";
                String file2Name = "";
                try {
                    file1Name = file1.getName().split(".log")[0];
                    file2Name = file2.getName().split(".log")[0];

                    Date dateFile1 = FILE_NAME_FORMAT.parse(file1Name);
                    Date dateFile2 = FILE_NAME_FORMAT.parse(file2Name);
                    return dateFile1.getTime() < dateFile2.getTime() ? -1 : 1;
                } catch (Exception e) {
                    Log.i("LogUtil", "file1Name:" + file1Name + ",   file2Name:" + file2Name);
                    e.printStackTrace();

                }
                return 0;
            }
        });
        File lastFile = fileList[fileCount - 1];
        // 日志文件未超过最大控制个数
        if (fileCount < LOG_FILE_TOTAL) {
            return isCreateLogFile(lastFile);
        }
        if (sizeOf(lastFile) >= LOG_SIZE_MAX) {
            // 删除时间最早的一个文件
            fileList[0].delete();
        }
        return isCreateLogFile(lastFile);
    }

    // 确认是否需要创建新日志文件
    private static File isCreateLogFile(File file) {
        // 超过日志文件大小上限,需要创建新日志文件
        if (sizeOf(file) >= LOG_SIZE_MAX) {
            return createLogFile();
        }
        return file;
    }

    // 创建一个新的日志文件
    private static File createLogFile() {
        return new File(LOG_FILE_PRINT_DIR + FILE_NAME_FORMAT.format(new Date(System.currentTimeMillis())) + ".log");
    }
    // 计算文件大小,返回单位 KB
    private static long sizeOf(File file) {
        long length = file.length();
        return length / 1024;
    }

}

标签:String,工具,TAG,static,msg,Android,日志,Log
来源: https://blog.csdn.net/kingyc123456789/article/details/114702101

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有