支持超長文本日誌打印的工具類

Demo源碼請點擊

1、背景

本日誌打印工具類支持超長文本信息打印,支持點擊日誌直接定位到對應代碼行。 我有借鑑com.orhanobut:logger這位兄弟的代碼。廢話不多說,直接上效果圖。
一般文本信息打印
網絡請求信息打印

2、類源碼

public class HLogger {
    public static boolean DEBUG = true;

    private static final int CHUNK_SIZE = 100;
    private static final char TOP_LEFT_CORNER = '┌';
    private static final char BOTTOM_LEFT_CORNER = '└';
    private static final char MIDDLE_CORNER = '├';
    private static final char HORIZONTAL_LINE = '│';
    private static final String DOUBLE_DIVIDER = "────────────────────────────────────────────────────────";
    private static final String SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄";
    private static final String TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
    private static final String BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
    private static final String MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER;

    private static String className;
    private static String methodName;
    private static int lineNumber;

    private static String createLog(String log) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(methodName);
        buffer.append("(").append(className).append(":").append(lineNumber).append(")");
        buffer.append(log);
        return buffer.toString();
    }
    private static String createLog() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("(").append(className).append(":").append(lineNumber).append(")");
        buffer.append(methodName);
        return buffer.toString();
    }

    private static void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[1].getFileName();
        methodName = sElements[1].getMethodName();
        lineNumber = sElements[1].getLineNumber();
    }

    //超長文本打印
    public static void longError(String message) {
        if (!DEBUG) return;
        if (!TextUtils.isEmpty(message)) {
            getMethodNames(new Throwable().getStackTrace());
            Log.e(className, TOP_BORDER);
            Log.i(className, HORIZONTAL_LINE + " " + createLog());
            Log.i(className, MIDDLE_BORDER + " ");
            byte[] bytes = message.getBytes();
            int length = bytes.length;
            if (length <= CHUNK_SIZE) {
                String[] lines = message.split(System.getProperty("line.separator"));
                for (String line : lines) {
                    Log.e(className, HORIZONTAL_LINE + " " + line);
                }
            } else {
                for (int i = 0; i < length; i += CHUNK_SIZE) {
                    int count = Math.min(length - i, CHUNK_SIZE);
                    String[] lines = new String(bytes, i, count).split(System.getProperty("line.separator"));
                    for (String line : lines) {
                        Log.e(className, HORIZONTAL_LINE + " " + line);
                    }
                }
            }
            Log.e(className, BOTTOM_BORDER);
        }
    }
    //超長文本打印
    public static void longInfo(String message) {
        if (!DEBUG) return;
        if (!TextUtils.isEmpty(message)) {
            getMethodNames(new Throwable().getStackTrace());
            Log.i(className, TOP_BORDER);
            Log.i(className, HORIZONTAL_LINE + " " + createLog());
            Log.i(className, MIDDLE_BORDER + " ");
            byte[] bytes = message.getBytes();
            int length = bytes.length;
            if (length <= CHUNK_SIZE) {
                String[] lines = message.split(System.getProperty("line.separator"));
                for (String line : lines) {
                    Log.i(className, HORIZONTAL_LINE + " " + line);
                }
            } else {
                for (int i = 0; i < length; i += CHUNK_SIZE) {
                    int count = Math.min(length - i, CHUNK_SIZE);
                    String[] lines = new String(bytes, i, count).split(System.getProperty("line.separator"));
                    for (String line : lines) {
                        Log.i(className, HORIZONTAL_LINE + " " + line);
                    }
                }
            }
            Log.i(className, BOTTOM_BORDER);
        }
    }

    public static void d(String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
                getMethodNames(new Throwable().getStackTrace());
                Log.d(className, createLog(msg));
            }
        }
    }

    public static void v(String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
                getMethodNames(new Throwable().getStackTrace());
                Log.d(className, createLog(msg));
            }
        }
    }

    public static void e(String msg) {
        if (!TextUtils.isEmpty(msg)) {
            getMethodNames(new Throwable().getStackTrace());
            Log.d(className, createLog(msg));
        }
    }

    public static void i(String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
                getMethodNames(new Throwable().getStackTrace());
                Log.d(className, createLog(msg));
            }
        }
    }

    public static void d(String tag, String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
//                Log.d(tag, msg);
                getMethodNames(new Throwable().getStackTrace());
                Log.d(className, createLog(msg));
            }
        }
    }

    public static void v(String tag, String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
                Log.d(tag, msg);
            }
        }
    }

    public static void e(String tag, String msg) {
        if (!TextUtils.isEmpty(msg)) {
            Log.d(tag, msg);
        }
    }

    public static void i(String tag, String msg) {
        if (DEBUG) {
            if (!TextUtils.isEmpty(msg)) {
                Log.d(tag, msg);
            }
        }
    }
}

3、代碼解析

3.1、調用方法

/**
     * 短文本打印調用方法
     * @param view
     */
    public void shortText(View view) {
        HLogger.d("這是一條測試信息。這是一條測試信息");
    }

    /**
     * 長文本打印調用方法
     * @param view
     */
    public void longText(View view) {
        HLogger.longInfo("545345343132121102045402.102135435412.121234564651313210210214541321shksjadhsdhaskjhdaskfhcask" +
                "dhaskdhakuhdoiauwdhaksncxkajsjhdkajshdaksjshdaksdhaskdhaskjdhaskjhdaksjhdaskjhdkahsfgbdajsfcnkjdanc," +
                "dsnbcsdhjkfgvsdkjhfhgaksudhaouisdqodhaksdnbcaskjcbnkadsfhdksafhgiudshgfsdkjfnakcbnkajsdhaksufghakfhdasjkfsakjdhfudhaoui" +
                "sdqodhaksdnbcaskjcbnkadsfhdksafhgiudshgfsdkjfnakcbnkajsdhaksufghakfhdasjkfsakjdhf" +
                "udhaouisdqodhaksdnbcaskjcbnkadsfhdksafhgiudshgfsdkjfnakcbnkajsdhaksufghakfhdasjkfsakjdhf" +
                "udhaouisdqodhaksdnbcaskjcbnkadsfhdksafhgiudshgfsdkjfnakcbnkajsdhaksufghakfhdasjkfsakjdhf" +
                "udhaouisdqodhaksdnbcaskjcbnkadsfhdksafhgiudshgfsdkjfnakcbnkajsdhaksufghakfhdasjkfsakjdhf");

    }

調用非常簡單,HLogger類支持的方法如下,可以傳入自己的TAG,也可以不傳入,代碼自動獲取打印日誌的類的類名作爲TAG。
HLogger支持的方法

  1. 網絡請求時,將請求信息及返回信息打印出來。會使用到長文本信息打印。以下是網絡請求攔截器中,我打印的請求信息。如效果圖中所示。
	//打印請求信息,正式項目中可以註釋掉
    RequestBody requestBody = request.body();
    String body = null;
    if (requestBody != null) {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);

        body = buffer.readString(Charset.forName("UTF-8"));
    }
    HLogUtil.longInfo(String.format("發送請求\nmethod:%s\nurl:%s\nheaders: %sbody:%s",
        request.method(), request.url(), request.headers(), body));

以下是返回信息

	String result = responseBody.string();
    HLogUtil.longInfo(result);

3.2、解析

  1. 通過Throwable的StackTrace,拿到當前類的類名、行號等信息。所以我們先通過這些信息封裝我們的log信息。
	private static String className;
    private static String methodName;
    private static int lineNumber;

	private static void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[1].getFileName();
        methodName = sElements[1].getMethodName();
        lineNumber = sElements[1].getLineNumber();
    }
    
    private static String createLog(String log) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(methodName);
        buffer.append("(").append(className).append(":").append(lineNumber).append(")");
        buffer.append(log);
        return buffer.toString();
    }

調用打印。

Log.d(className, createLog(msg));
  1. 長文本信息打印,其實就是在短文本基礎上進行了長文本內容的分割打印,及展示方式的封裝。
//超長文本打印
    public static void longInfo(String message) {
        if (!DEBUG) return;
        if (!TextUtils.isEmpty(message)) {
            getMethodNames(new Throwable().getStackTrace());
            //先打印橫線
            Log.i(className, TOP_BORDER);
            //再打印類名和行號及調用方法名
            Log.i(className, HORIZONTAL_LINE + " " + createLog());
            //再打印中間橫線
            Log.i(className, MIDDLE_BORDER + " ");
            byte[] bytes = message.getBytes();
            int length = bytes.length;
            //判斷文本內容長度
            if (length <= CHUNK_SIZE) {
                //短文本,再判斷文本內容是否有換行符
                String[] lines = message.split(System.getProperty("line.separator"));
                for (String line : lines) {
                    Log.i(className, HORIZONTAL_LINE + " " + line);
                }
            } else {
                //長文本循環打印,每一行中判斷是否有換行符
                for (int i = 0; i < length; i += CHUNK_SIZE) {
                    int count = Math.min(length - i, CHUNK_SIZE);
                    String[] lines = new String(bytes, i, count).split(System.getProperty("line.separator"));
                    for (String line : lines) {
                        Log.i(className, HORIZONTAL_LINE + " " + line);
                    }
                }
            }
            Log.i(className, BOTTOM_BORDER);
        }
    }

3.3、注意

  1. 長文本打印方法中,文本切割長度我是設置的100字節長度,這個可以自由調整。就是這個屬性:
private static final int CHUNK_SIZE = 100;
  1. 長文本打印方法 ,如果內容中有換行符,也會自動換行。

Demo源碼請點擊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章