Java log 如何獲取Line、File等信息

今天在Android 開發中Java 調用Native C++實現的 SDK 庫log 模塊功能時遇到一個問題:Native 代碼本身使用LINE, FILE等C++ 宏可以精確定位log 記錄位置信息, 但Java 調用處卻無法正確體現具體文件、行數等信息,轉化爲Native log 實現體的信息。於是就準備用Java 封裝一層Native log 代碼, 實現增加FILE,LINE,FUNCTION等基本信息。那麼問題來了:Java 如何實現獲取log 發生處的位置信息?

鑑於之前用過著名的log4j 開源庫, 既然開源,看看源代碼又何妨?! 基本瞭解了log4j 實現原理: 通過創建一個Throwable 對象, 獲取堆棧信息,進一步提取堆棧信息確定log發生的FILE,LINE,FUNCTION , 於是產生了對Native 代碼的封裝的log:

public final class NLogger {
    private static INLogger s_logger = null;
    private static boolean  debug = false;  //NOTICE: debug mode will decrease performance.  

    static {
        if(s_logger ==null)
            s_logger = XXX.getNativeLogger(); //獲取Native log 實例
    }

    public staticvoid enableDebug(){
        debug = true;
    }

    public staticvoid disableDebug(){
        debug = false;
    }

    public static void info(String msg){
        if(s_logger != null){
            if(debug){
                StackTraceElement traceElement = (new Throwable()).getStackTrace()[1];
                s_logger.info(traceElement.getFileName() +":" + traceElement.getLineNumber() + " " + traceElement.getMethodName() +" " + msg);
            }
            else{
                s_logger.info(msg);
            }
        }
    }

    public static void warn(String msg){
        if(s_logger != null){
            if(debug){
                StackTraceElement traceElement = (new Throwable()).getStackTrace()[1];
                s_logger.warning(traceElement.getFileName() +":" + traceElement.getLineNumber() + " " + traceElement.getMethodName() +" " + msg);
            }
            else {
                s_logger.warning(msg);
            }
        }
    }

    public static void error(String msg){
        if(s_logger !=null){
            if(debug) {
                StackTraceElement traceElement = (new Throwable()).getStackTrace()[1];
                s_logger.error(traceElement.getFileName() +":" + traceElement.getLineNumber() + " " + traceElement.getMethodName() +" " + msg);
            }
            else {
                s_logger.error(msg);
            }
        }
    }
}

請注意: 該方法雖然解決了問題, 對於長期寫C++代碼的人員, 不免覺得效率低下,每條log 都要額外創建一個Throwable對象, 因此log 封裝時增加debug 選項開關,正常情況下還是關閉爲好。

在未找到更合適的方法前, 不失爲解決問題的一種方案。

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