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

posted @ 2012-07-26 11:48  一根骨头棒子*熬的汤  阅读(4102)  评论(0编辑  收藏  举报