android log輸出控制


1. java層

java層打印log由類android.util.Log類實現,該類定義於文件:
frameworks/base/core/java/android/util/Log.java (APP 框架層)

對應的JNI層代碼在文件:frameworks/base/core/jni/android_util_Log.cpp (本地框架層)
這個層次主要調用了HAL層的liblog庫中的函數__android_log_buf_write() --> write_to_log() -->
 __write_to_log_kernel() --> log_writev() (這些函數都處於庫liblog中: system/core/liblog)。
 
這樣在上層java中只要包含了類android.util.Log,都可以使用Log.v, Log.d, Log.i來打印log。


其實,android編譯版本可以根據TARGET_BUILD_TYPE等於debug或者release來打開和屏蔽掉log信息,但是這必須得有個前提,
就是我們在上層調用Log.d等函數的時候需要按照如下格式來寫即可:

static boolean DEBUG = true && Config.DEBUG;
if(DEBUG)
 Log.d(TAG, "storeMessage " + this.toString());

這里實際上是可以直接用if(Config.DEBUG)的,但是為了能夠我們自己控制這個log的輸出的話,建議使用上面的方式。比如在debug版本
的時候,我們就可以通過flase && Config.DEBUG來去掉這些log輸出。

Config類的實現在文件:frameworks/base/core/java/android/util/Config.java,其中將會引用類ConfigBuildFlags,這個類是在
目錄:frameworks/base/core/config/  - debug、ndebug、sdk目錄,到底使用哪一個目錄下的ConfigBuildFlags定義,需要取決於
TARGET_BUILD_TYPE的定義:(這個config目錄下還有一個readme文件,可以讀讀,會有幫助的)
One of the subdirectories {debug, ndebug} is included in framework.jar by http://www.cnblogs.com/Android.mk depending on the value of
$(TARGET_BUILD_TYPE).

那就來看一下http://www.cnblogs.com/Android.mk這個文件中如何決定的:
frameworks/base/Android.mk
# Include a different set of source files when building a debug build.
# TODO: Maybe build these into a separate .jar and put it on the classpath
#       in front of framework.jar.
# NOTE: Do not use this as an example; this is a very special situation.
#       Do not modify LOCAL_SRC_FILES based on any variable other
#       than TARGET_BUILD_TYPE, otherwise builds can become inconsistent.
ifeq ($(TARGET_BUILD_TYPE),debug)
  LOCAL_SRC_FILES += $(call find-other-java-files,core/config/debug)
else
  LOCAL_SRC_FILES += $(call find-other-java-files,core/config/ndebug)
endif
這里就是通過TARGET_BUILD_TYPE來選擇將那個目錄下的ConfigBuildFlags定義編譯進framework.jar。


編譯android的時候可以通過這兩個宏來進行組合:TARGET_BUILD_VARIANT 和TARGET_BUILD_TYPE
TARGET_BUILD_VARIANT: user userdebug eng tests (默認eng)
TARGET_BUILD_TYPE: debug release (默認release)

這兩個宏可以定義在文件buildspec.mk下,也可以直接加載make命令中,也可以使用. build/envsetup.sh之后使用choosevariant來選擇。

對java層log輸出的實現修改:
lizhiguo@informax-ui1:~/new_hope/alps/frameworks/base/core/jni$ svn diff android_util_Log.cpp
Index: android_util_Log.cpp
===================================================================
--- android_util_Log.cpp        (revision 510)
+++ android_util_Log.cpp        (working copy)
@@ -79,9 +79,12 @@
 static int toLevel(const char* value)
 {
     switch (value[0]) {
-        case 'V': return levels.verbose;
-        case 'D': return levels.debug;
-        case 'I': return levels.info;
+               case 'V': return -1;  // lizhiguo 2011-07-19
+        //case 'V': return levels.verbose;
+        //case 'D': return levels.debug;
+        //case 'I': return levels.info;
+        case 'D': return -1;
+        case 'I': return -1;
         case 'W': return levels.warn;
         case 'E': return levels.error;
         case 'A': return levels.assert;
@@ -165,7 +168,9 @@
         tag = env->GetStringUTFChars(tagObj, NULL);
     msg = env->GetStringUTFChars(msgObj, NULL);

-    int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
+    int res = 1;   /* lizhiguo 2011-07-19, for release sofe */
+    if( (priority != 2) && (priority != 3) && (priority != 4) )
+        res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);

     if (tag != NULL)
         env->ReleaseStringUTFChars(tagObj, tag);


2. 中間層(HAL+JNI)
 JNI層代碼需包含頭文件frameworks/base/include/utils/Log.h,實際上這個頭文件include了HAL層代碼使用的頭文件system/core/include/cutils/log.h
 在相應的中間層代碼中包含log TAG的地方,使用如下形式:
    //#define  NDEBUG
    #define  LOG_NDEBUG  1
    #define  LOG_TAG  "RFID_HAL"
    #include <cutils/log.h>
    
下面是關於HAL層log的屏蔽代碼:主要是去掉V、D、I等級的log輸出:
lizhiguo@informax-ui1:~/new_hope/alps$ svn diff system/core/include/cutils/log.h
Index: system/core/include/cutils/log.h
===================================================================
--- system/core/include/cutils/log.h    (revision 510)
+++ system/core/include/cutils/log.h    (working copy)
@@ -51,6 +51,8 @@
  * You can modify this (for example with "#define LOG_NDEBUG 0"
  * at the top of your source file) to change that behavior.
  */
+#define LOG_NDEBUG 1   /* lizhiguo 2011-07-19, for release sofe*/
+
 #ifndef LOG_NDEBUG
 #ifdef NDEBUG
 #define LOG_NDEBUG 1
@@ -98,29 +100,45 @@
  * Simplified macro to send a debug log message using the current LOG_TAG.
  */
 #ifndef LOGD
+#if LOG_NDEBUG          /* lizhiguo 2011-07-19, for release sofe*/
+#define LOGD(...)   ((void)0)
+#else
 #define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
 #endif
+#endif

 #ifndef LOGD_IF
+#if LOG_NDEBUG
+#define LOGD_IF(cond, ...)   ((void)0)
+#else
 #define LOGD_IF(cond, ...) \
     ( (CONDITION(cond)) \
     ? ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
     : (void)0 )
 #endif
+#endif

 /*
  * Simplified macro to send an info log message using the current LOG_TAG.
  */
 #ifndef LOGI
+#if LOG_NDEBUG          /* lizhiguo 2011-07-19, for release sofe*/
+#define LOGI(...)   ((void)0)
+#else
 #define LOGI(...) ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
 #endif
+#endif

 #ifndef LOGI_IF
+#if LOG_NDEBUG
+#define LOGI_IF(cond, ...)   ((void)0)
+#else
 #define LOGI_IF(cond, ...) \
     ( (CONDITION(cond)) \
     ? ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
     : (void)0 )
 #endif
+#endif

 /*
  * Simplified macro to send a warning log message using the current LOG_TAG.
@@ -169,16 +187,24 @@
  * debug priority.
  */
 #ifndef IF_LOGD
+#if LOG_NDEBUG              /* lizhiguo 2011-07-19, for release sofe*/
+#define IF_LOGD() if (false)
+#else
 #define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
 #endif
+#endif

 /*
  * Conditional based on whether the current LOG_TAG is enabled at
  * info priority.
  */
 #ifndef IF_LOGI
+#if LOG_NDEBUG          /* lizhiguo 2011-07-19, for release sofe*/
+#define IF_LOGI() if (false)
+#else
 #define IF_LOGI() IF_LOG(LOG_INFO, LOG_TAG)
 #endif
+#endif

 /*
  * Conditional based on whether the current LOG_TAG is enabled at
@@ -227,29 +253,45 @@
  * Simplified macro to send a debug system log message using the current LOG_TAG.
  */
 #ifndef SLOGD
+#if LOG_NDEBUG              /* lizhiguo 2011-07-19, for release sofe*/
+#define SLOGD(...)   ((void)0)
+#else
 #define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
 #endif
+#endif

 #ifndef SLOGD_IF
+#if LOG_NDEBUG
+#define SLOGD_IF(cond, ...)   ((void)0)
+#else
 #define SLOGD_IF(cond, ...) \
     ( (CONDITION(cond)) \
     ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
     : (void)0 )
 #endif
+#endif

 /*
  * Simplified macro to send an info system log message using the current LOG_TAG.
  */
 #ifndef SLOGI
+#if LOG_NDEBUG              /* lizhiguo 2011-07-19, for release sofe*/
+#define SLOGI(...)   ((void)0)
+#else
 #define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
 #endif
+#endif

 #ifndef SLOGI_IF
+#if LOG_NDEBUG
+#define SLOGI_IF(cond, ...)   ((void)0)
+#else
 #define SLOGI_IF(cond, ...) \
     ( (CONDITION(cond)) \
     ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
     : (void)0 )
 #endif
+#endif

 /*
  * Simplified macro to send a warning system log message using the current LOG_TAG.
 
3. c代碼
 對於c代碼,為了更好更容易地控制log輸出,在每個模塊中單獨定義print語句時,最好在全局控制宏的控制之下來定義。
 #define C_PRINTF_CONTROL
 
 模塊中定義:
 #define CUSTOM_DEF_TPD
 #ifdef  C_PRINTF_CONTROL
 #ifdef  CUSTOM_DEF_TPD
 #define TPD_DEBUG(a,arg...)  printk(TPD_DEVICE ": " a,##arg)
 #else       // CUSTOM_DEF_TPD
 #define TPD_DEBUG(arg...)
 #endif       // CUSTOM_DEF_TPD
 #else         // C_PRINTF_CONTROL
 #define TPD_DEBUG(arg...)
 #endif        // C_PRINTF_CONTROL


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM