1. 程式人生 > >LINUX系統以及ANDROID 平臺log資訊輸出級別設定 [MTK]

LINUX系統以及ANDROID 平臺log資訊輸出級別設定 [MTK]

http://blog.csdn.net/ffmxnjm/article/details/72723325

一、LK層:

首先,在LK中,有一個對log列印級別的控制文件,其路徑一般為:vendor\mediatek\proprietary\bootable\bootloader\lk\include\debug.h(以mtk平臺為例)

在include\debug.h重要程式碼為:

//下面做個判斷:意思是如果makefile(相應的平臺mk檔案) 定義了DEBUG的值,就是用它,否則預設為2等級
//在bootloader\lk\project\rlk6737m_65_n.mk中:DEBUG := 2

#if defined(DEBUG)
#define

 DEBUGLEVEL DEBUG
#else
#define DEBUGLEVEL 2
#endif

/* debug levels 除錯級別*/   
#define CRITICAL 0      //數字越小級別越高,列印的資訊log越少
#define ALWAYS 0
#define INFO 1
#define SPEW 2

/* output */  輸出方式介紹
void _dputc(char c); // XXX for now, platform implements  平臺工具
int _dputs(const char *str);
int _dprintf(const char *fmt, ...) __PRINTFLIKE(1, 2);
int _dvprintf(const char *fmt, va_list ap);

//下面的這些列印方法具體含義是:如果級別<=之前定義的除錯級別的話就列印否則不列印

#define dputc(level, str) do { if ((level) <= DEBUGLEVEL) { _dputc(str); } } while (0)  
#define dputs(level, str) do { if ((level) <= DEBUGLEVEL) { _dputs(str); } } while (0)
#define dprintf(level, x...) do { if ((level) <= DEBUGLEVEL) { _dprintf(x); } } while (0)
#define dvprintf

(level, x...) do { if ((level) <= DEBUGLEVEL) { _dvprintf(x); } } while (0)

相關DEBUG的定義有不同的方式方法,如下例子:

法①、在bootable\bootloader\lk\project\rlk6757_66_n.mk:

DEBUG :=2  

這時也要注意:不要看到這裡是2就表示都會列印,我現在遇到一個專案雖然在\lk\project\rlk6757_66_n.mk檔案中配置了DEBUG :=2,但log並沒有打印出來,原因最後找到了:

#ifdef LK_PROFILING
    dprintf(INFO, "[PROFILE] ------- WDT Init  takes %d ms -------- \n", (int)get_timer(time_wdt_early_init));   //打印不出來
#endif

最後發現在類似的bootable\bootloader\lk\target\rlk6757_66_n(project)\rules.mk中:

LK_PROFILING := no      //LK_PROFILING := yes  一般專案都會使這個巨集,所以之前並沒有太關注,後續專案可能會為了效能,把log後期以這種方式關掉,注意一下

法②、在lk\include\platform\debug.h中定義了這個函式:

void debug_set_trace_level(int trace_type, int level);  //設定除錯級別

法③、還有在具體的程式碼中:如:

#define DEBUG  //這裡定義了這個巨集

#ifdef DEBUG    //判斷是不是定義了,定義了就執行下面的
#define LCM_DEBUG(fmt, args...)  _dprintf(fmt, ##args)

#else 
#define LCM_DEBUG(fmt, args...) do {} while(0)

#endif

二、kernel層:

在kernel-3.18\include\linux\kern_levels.h中定義了列印級別:

(以前定義在kernel-3.18\include\linux\kernel.h)

#define KERN_SOH    "\001"        /* ASCII Start Of Header */
#define KERN_SOH_ASCII    '\001'

#define KERN_EMERG    KERN_SOH "0"    /* system is unusable 系統無法使用*/
#define KERN_ALERT    KERN_SOH "1"    /* action must be taken immediately必須立即採取行動 */
#define KERN_CRIT    KERN_SOH "2"    /* critical conditions臨界狀態---重要資訊 */
#define KERN_ERR    KERN_SOH "3"    /* error conditions錯誤狀況 */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions 報警狀態*/
#define KERN_NOTICE    KERN_SOH "5"    /* normal but significant condition正常但重要條件 */
#define KERN_INFO    KERN_SOH "6"    /* informational重要資訊 */
#define KERN_DEBUG    KERN_SOH "7"    /* debug-level messages 除錯級別資訊*/

#define KERN_DEFAULT    KERN_SOH "d"    /* the default kernel loglevel 預設的核心loglevel----一般都為4*/

在kernel-3.18\include\linux\printk.h中定義了各預設日誌的級別

/* printk's without a loglevel use this.. 沒有日誌級別的printk使用*/
#define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT

/* We show everything that is MORE important than this..我們展示了所有比這更重要的東西 */
#define CONSOLE_LOGLEVEL_SILENT  0 /* Mum's the word */
#define CONSOLE_LOGLEVEL_MIN     1 /* Minimum loglevel we let people use最低的控制檯日誌級別*/
#define CONSOLE_LOGLEVEL_QUIET     4 /* Shhh ..., when booted with "quiet"預設的訊息日誌級別*/
#define CONSOLE_LOGLEVEL_DEFAULT 7 /* anything MORE serious than KERN_DEBUG 預設的控制檯日誌級別*/

#define CONSOLE_LOGLEVEL_DEBUG    10 /* issue debug messages */
#define CONSOLE_LOGLEVEL_MOTORMOUTH 15    /* You can't shut this one up */

extern int console_printk[];

#define console_loglevel (console_printk[0])
#define default_message_loglevel (console_printk[1])
#define minimum_console_loglevel (console_printk[2])

在這裡注意一下:有些人在寫printk()時,並不加log級別,這是如果我們定義的log級別小於4,則它是打印不出來的,因為不寫log級別的列印核心預設為4列印級別。

在kernel-3.18\kernel\printk\printk.c中:

int console_printk[4] = {
    CONSOLE_LOGLEVEL_DEFAULT,    /* console_loglevel控制log級別 */
    MESSAGE_LOGLEVEL_DEFAULT,    /* default_message_loglevel預設的訊息日誌級別 */
    CONSOLE_LOGLEVEL_MIN,        /* minimum_console_loglevel最低的控制檯日誌級別*/
    CONSOLE_LOGLEVEL_DEFAULT,    /* default_console_loglevel預設的控制檯日誌級別 */
};

我們的做法:

①、我們可以在檢視當前控制檯的列印級別:

cat /proc/sys/kernel/printk

7     4     1     7

四個值的含義:控制檯日誌級別、預設的訊息日誌級別、最低的控制檯日誌級別和預設的控制檯日誌級別

其中第一個“7”表示核心列印函式printk的列印級別,只有級別比他高的資訊才能在控制檯上打印出來,既 0-6級別的資訊

②、修改列印:
echo "新的列印級別  4    1    7" >/proc/sys/kernel/printk

如果用echo 8  >  /proc/sys/kernel/printk這樣所有級別<8,(0-7)的訊息都可以顯示在控制檯上。
不夠列印級別的資訊會被寫到日誌中可通過dmesg 命令來檢視

設定控制終端列印級別為0,就沒有了任何輸出

如果需要臨時關閉kernel的log,可以再串列埠輸入命令:echo "0 0 0 0" > /proc/sys/kernel/printk
需要恢復的話可以輸入:echo ”7 4 1 7“ > /proc/sys/kernel/printk

③、printk函式的使用

 printk(列印級別  “要列印的資訊”)

MTK問題:How to enable kernel dynamic debug log

     如何啟用核心動態除錯日誌

[DESCRIPTION] 在kernel module debug 對照程式碼的時候,發現使用pr_debug 列印的log 無法找到,怎樣在mobilelog 和uart log中開啟pr_debug ? pr_debug()針對這種列印資訊[SOLUTION] 1 開啟dynamic debug feature    <project>_defconfig 中設定CONFIG_DYNAMIC_DEBUG=y (default 開啟) 2 開啟pr_debug log 輸出     enable:echo "<match-spec> +p" > <debugfs>/dynamic_debug/control    disable:echo "<match-spec> -p" > <debugfs>/dynamic_debug/control    <match-spec>: file <path>                          line line-range  module <module_name>  func <func-name>      eg:enable the message at line 1603 of file svcsock.c   //使能訊息
             echo -n "file svcsock.c line 1603 +p" > /sys/kernel/debug/dynamic_debug/control    eg:enable all the messages in the NFS server module  //啟用NFS伺服器模組中的所有訊息
            echo -n "module nfsd +p" > /sys/kernel/debug/dynamic_debug/control 3mobile log 中 pr_debug log     pr_debug 預設以debug 等級輸出到kernel log 中, mobilelog 抓到的kernellog 會包含 4 uartlog 中 pr_debug log     預設pr_debug log 不送uart ,可以通過以下方式開啟:         1.adb起來後,echo 8 > /proc/sys/kernel/printk
         2.改code ,修改console 預設輸出log等級
               kernel-3.18/include/linux/printk.h : #define CONSOLE_LOGLEVEL_DEFAULT 7 -->#define CONSOLE_LOGLEVEL_DEFAULT 8
三、關於android日誌列印級別

1、 目的:

為了規範軟體工程師在程式碼編寫過程中輸出Log的行為,使得釋出的產品中列印的Log是必須的,列印的Log的級別是能真實反映此Log對應的級別,標籤、Log內容具有很好的可讀性。

2、 適用範圍

android平臺Javac++c程式碼編寫。

3、 Log的呼叫及等級介紹

(1)Log的等級有Verbose,Debug,Info,Warn,Error

 [D]:除錯(Debug)資訊,輸出顏色是藍色

 [I]:通告(Info)資訊,輸出顏色為綠色

[W]:警告(Warn)資訊,輸出顏色為橙色

[E]:錯誤(Error)資訊,輸出顏色為紅色

[V]:詳細(Verbose)資訊,輸出顏色為黑色

[assert],新版本加入的。

這裡錯誤資訊0的級別最高,其次是警告資訊1,然後是通知資訊2除錯資訊3,級別最低的是詳細資訊4

我們如果想讓所有的資訊都打印出來一般都定義成debug級別。

(2)java層呼叫:在java層呼叫import android.util.Log,在需要列印Log的地方執行Log.v,Log.d,Log.i,Log.w,Log.e.

          如:             

                       private static final String LOG_TAG = "MY_LOG_TAG";   //這個TAG可以隨意定義,後面列印篩選的時候可以用到

                      Log.i(LOG_TAG, "This is the log printed by Log.i in android user space.");

                       Log.e(LOG_TAG, "xxxxxxxxxxx" + mFileName, e);

   比如:在所有的log中我想選出有包含“MY_LOG_TAG”這個標籤的,則需執行:adb logcat  -s "MY_LOG_TAG"   即可

(3)cc++層呼叫:在c,c++層包含此標頭檔案:#include <cutils/log.h>,在需要呼叫Log的地方執行:ALOGV,ALOGD,ALOGI,ALOGW,ALOGE

        敝人認為:標頭檔案可以寫: #include <utils/Log.h>  ---》 #include <cutils/log.h>----》#include <log/log.h>,中的任何一個,其實質在log/log.h中

       具體目錄為:system\core\include\log\log.h

         如:

             ALOGE("This is the log printed by LOGV in android user space.");//輸出到main緩衝區

            SLOGE("xxxxxxxxxxxxxxxxxx"); //輸出到system緩衝區

             還需要修改 Android.mk

              LOCAL_SHARED_LIBRARIES := liblog

              LOCAL_C_INCLUDES += system/core/include //可不用

3 libcore

System.out.println("##### xxxxxxxxxxxx #######   ");

(4)、各個Log等級的使用

Verbose:開發除錯過程中一些詳細資訊,不應該編譯進產品中,只在開發階段使用。

Debug:用於除錯的資訊,編譯進產品,但可以在執行時關閉。

Info:例如一些執行時的狀態資訊,這些狀態資訊在出現問題的時候能提供幫助。

Warn:警告系統出現了異常,即將出現錯誤。

Error:系統已經出現了錯誤。

InfoWarnError這三個等級的Log的警示作用依次提高,需要一直保留。這些資訊在系統異常時能提供有價值的分析線索。

4、 具體規則

1)、Verbose等級的Log,請不要在user版本中出現Verbose級別的Log輸出參見下面例子。

示例Java部分:

import android.os.Build;

import android.util.Log

final public Boolean isEng =Build.TYPE.equals("eng");

if (isEng)

Log.v(LOG_TAG,LOG_MESSAGE);

示例c、c++部分:

#include<cutils/log.h>

char value[PROPERTY_VALUE_MAX];

int isEng=0;

property_get("ro.build.type",value, "user");

isEng=strcmp(value, "eng");

if (isEng)

ALOGV();

2)、Debug等級的log,預設不開啟,通過終端命令開啟

Debug級別的log輸出參見下面例子。

示例Java部分:

import android.util.Log

final String TAG=”MyActivity”;

final public Boolean LOG_DEBUG = Log.isLoggable(TAG, Log.DEBUG);

if (LOG_DEBUG)

Log.d(LOG_TAG,LOG_MESSAGE);

執行時開啟log:在終端輸入:setprop log.tag.MyActivity DEBUG

執行時關閉log:在終端輸入:setprop log.tag.MyActivity INFO

示例c、c++部分:

#include<cutils/log.h>

#defineLOG_CTLdebug.MyActivity.enablelog

charvalue[PROPERTY_VALUE_MAX];

int isDebug=0;

property_get(LOG_CTL,value, "0");

isDebug=strcmp(value,"1");

if (isDebug)

ALOGD();

執行時開啟log:在終端輸入:setpropdebug.MyActivity.enablelog 1

執行時關閉log:在終端輸入:setpropdebug.MyActivity.enablelog 0

最近遇到一個問題:

在.cpp應用程式碼中有類似這樣的資訊:

 SLOGD("[boot_logo_updater %s %d]boot_logo_updater,\n",__FUNCTION__,__LINE__)

SLOGD("[libshowlogo: %s %d]show kernel logo, index = 38 \n",__FUNCTION__,__LINE__);

但輸出的log資訊中就是打印不出來,我懷疑級別不夠。最終發現確實有定義級別的地方:

開啟:system\core\include\log\log.h發現:

/*
 * Normally we strip ALOGV (VERBOSE messages) from release builds.
 * You can modify this (for example with "#define LOG_NDEBUG 0"
 * at the top of your source file) to change that behavior.
 */

//對log級別的

#ifndef LOG_NDEBUG    //如果我們沒有定義,我們就給它賦值為0,表示不關閉
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif

#ifdef MTK_LOG_ENABLE  //如果我們沒有定義它,我們就定義為0,這裡就是定義列印級別,很重要。
#define MTK_LOG_ENABLE 0
#endif

例如:#define MTK_LOG_ENABLE 1   //這裡在原始碼已經定義好了,但級別為1,表示只能列印LOGE最高級別的錯誤資訊,其它的都不能列印,我們除錯是可以在這裡改

/*
 * This is the local tag used for the following simplified
 * logging macros.  You can change this preprocessor definition
 * before using the other macros to change the tag.
 */

//這裡定義log日誌記錄巨集,即標籤,方便過濾log訊息。

#ifndef LOG_TAG
#define LOG_TAG NULL    //如果沒有定義則我們預設標籤為NULL
#endif

例如:#define LOG_TAG "JIANMIN.NIU"    //在原始碼定義這個,則在篩選log時執行:adb logcat -s "jianmin.niu" 即可

總結:

如果要輸出列印資訊:

①、定義標頭檔案

#include <cutils/log.h>#include <log/log.h>等等

②、定義列印級別

#define MTK_LOG_ENABLE4   

③、定義標籤

#define LOG_TAG "JIANMIN.NIU" 
④、呼叫列印資訊

SLOGD("[libshowlogo] read %s : %s\n",name,value);

⑤、執行

adb logcat -s "jianmin.niu"  //獲取相關資訊即可

⑥、如果以上操作還是不行,則有可能列印環境有問題;或者用一下方法:

或者是不是Debug等級的log,預設不開啟,通過終端命令開啟才行

⑧或者用一下方法

新增#include "cutils/logd.h"

定義TAG,如:#define TAG "errorlog"

直接呼叫__android_log_print(ANDROID_LOG_ERROR,TAG,"print content");函式列印log資訊。

__android_log_print函式在system\core\include\log\log.h中定義

 * The stuff in the rest of this file should not be used directly.
 */

#define android_printLog(prio, tag, fmt...) \
    __android_log_print(prio, tag, fmt)

#define android_vprintLog(prio, cond, tag, fmt...) \
    __android_log_vprint(prio, tag, fmt)

⑨、MTK的建議

      [1]、法一:失敗

          關機充電的時候,mobilelog是無法抓取
同樣uart log這邊也是無法抓取的,logcat這邊由於沒有載入,所以也抓取不到log
所以請您幫忙在
1.
init.rc中新增如下

on property:ro.debuggable=1
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
start console
之後新增
    #add by mtk13230 debug for charger log
on property:ro.debuggable=0
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
start console
    #end add
2.
在init.mt6735.rc中新增
在on charger 這段的最後start servicemanager 之後新增
    #add by mtk13230 for debug charger log
    start logd
    start logcatd
    #end add

然後您build code後,在uart上面再輸入logcat,看是否可以抓取到charging_animation這邊的log

結果:按照你描述的方式修改init.rc和init.mt6735.rc後 show_animation_common.c檔案中新增的ALOGD,SLOGE,SLOGD 列印串列埠log還是均無法輸出出來

【2】法二:

請您使用如下的命令抓取log
logcat -b main -b system -v threadtime
看是否能抓取到您想要的log

結果:關機充電連不上adb的怎麼使用logcat?
關機充電只能打串列埠log,串列埠log使用不了logcat

【3】、法三:

       ===>> 下面第一步中有開console, 所以uart 可以獲取console, 第二步中有拉logd和logcat 就能用logcat 抓log
關機充電的時候,mobilelog是無法抓取
同樣uart log這邊也是無法抓取的,logcat這邊由於沒有載入,所以也抓取不到log
所以請您幫忙在
1.
init.rc中新增如下

on property:ro.debuggable=1
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
start console
之後新增
    #add by mtk13230 debug for charger log
on property:ro.debuggable=0
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
start console
    #end add
2.
在init.mt6735.rc中新增
在on charger 這段的最後start servicemanager 之後新增
    #add by mtk13230 for debug charger log
    start logd
    start logcatd
    #end add

然後您build code後,在uart上面再輸入logcat,看是否可以抓取到charging_animation這邊的log

串列埠上應當是可以輸入command的
您看一下是否TX、RX,地線都有接

結果:沒有出來

【4】法四:可以了

從您這邊看到,
/vendor/mediatek/proprietary/external/charger 下面的log是可以show出來的
[ 4.971466] <0>.(0)[205:kpoc_charger]charger: [ChargingAnimation: bootlogo_init 97]
[ 4.972426] <0>.(0)[205:kpoc_charger]charger: [ChargingAnimation: sync_anim_version 55]
您可以在/vendor/mediatek/proprietary/external/libshowlogo/ 中也借鑑一下這裡的列印方式
charger這邊的列印方式為KPOC_LOGI 等
定義應當是在
/vendor/mediatek/proprietary/external/charger/main.h
#define KPOC_LOGI(x...) do { KLOG_ERROR("charger", x); } while (0)
// HACK: Sprout drops previous console logs below log level 4
#define KPOC_LOGE(x...) do { KLOG_WARNING("charger", x); } while (0)
#define KPOC_LOGD(x...) do { KLOG_DEBUG("charger", x); } while (0)

結果:使用 KPOC_LOGI 就可以列印了

(3)、禁止使用new Exception("print trace").printStackTrace()或者Log. getStackTraceString(Exception)方式列印普通除錯資訊,因為這種方式列印Log非常消耗系統資源。此種方式列印Log一般只出現try..catch某個異常使用。

(4)、Logtag命名,使用Activity名稱或者類、模組的名稱,不要出現自己的姓名拼音或其他簡稱。在c++/c程式碼中呼叫ALOGD等巨集函式,引數沒有傳入tag,需要在檔案頭部#define LOG_TAG"YOUR_TAG_NAME"。------》如:#define LOG_TAG "BootLogoUpdater"

(5)、Log的內容,不要出現公司名稱、個人名稱或相關簡稱,Log內容不要出現無意義的內容,如連續的等號或星號或連續的數字等,Log內容要方便其他分析Log的人員檢視。

(6)、Log輸出的頻率需要控制,例如1s列印一次的Log,儘量只在eng版本使用,user版本如需開啟,請預設關閉,通過設定setprop命令來開啟。

5、各層詳細說明

1. java層

import android.util.Log;

對應的級別列印方法 
VERBOSELog.v()
DEBUGLog.d()
INFOLog.i()
WARNLog.w()
ERRORLog.e()

方法:

Log.d(TAG, "something to say.");

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輸出的實現修改:
[email protected]:~/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、 FRAMEWORK層import android.util.Slog;

對應的級別列印方法 
VERBOSESlog.v()
DEBUGSlog.d()
INFOSlog.i()
WARNSlog.w()
ERRORSlog.e()

方法:
Slog.d(TAG, "something to say.");
3. 中間層(HAL+JNI)

HAL層:

標頭檔案:
#include <utils/Log.h>

對應的級別列印方法 
VERBOSELOGV()
DEBUGLOGD()
INFOLOGI()
WARNLOGW()
ERRORLOGE()

方法:
LOGD("%d, %s", int, char* )

JNI層標頭檔案:
#include <utils/Log.h>

對應的級別列印方法 
VERBOSELOGV()
DEBUGLOGD()
INFOLOGI()
WARNLOGW()
ERRORLOGE()

方法:
LOGD("%d, %s", int, char* )

 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輸出:
[email protected]:~/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.
  
4. 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


四、使用logcat來列印系統日誌資訊

logCat是用來獲取系統日誌資訊的工具,它可以捕獲的資訊包括Dalvik虛擬機器產生的資訊,程序資訊,ActivityManager資訊,PackagerManager資訊,Android執行時資訊和應用程式資訊等等。

相關推薦

LINUX系統以及ANDROID 平臺log資訊輸出級別設定 [MTK]

一、LK層: 首先,在LK中,有一個對log列印級別的控制文件,其路徑一般為:vendor\mediatek\proprietary\bootable\bootloader\lk\include\debug.h(以mtk平臺為例) 在include\debug.h重要程式碼

LINUX系統以及ANDROID 平臺log資訊輸出級別設定 [MTK]

http://blog.csdn.net/ffmxnjm/article/details/72723325一、LK層:首先,在LK中,有一個對log列印級別的控制文件,其路徑一般為:vendor\mediatek\proprietary\bootable\bootloader

Android平臺Log輸出規範

1、 目的: 為了規範軟體工程師在android程式碼編寫過程中輸出Log的行為,使得釋出的產品中列印的Log是必須的,列印的Log的級別是能真實反映此Log對應的級別,標籤、Log內容具有很好的可讀性。 2、 適用範圍 android平臺java、c++、c程式碼編寫。

3.了解linux系統以及搭建學習環境

基礎 軟件工程 store 開放 sos 時間 它的 情況 XML 目錄: 1.linux的前世今生. 2.企業如何選擇linux系統? 3.如何在虛擬機上安裝linux系統?搭建學習環境. 1.linux的前世今生. 1).起源:先是貝爾實驗室的Unix系統,因為各家對於

linux系統shell中重定向 標準輸出 錯誤輸出 >/dev/null 2>&1

經常shell指令碼中,會看到: 仔細體會下面例子。 >/dev/null  2>&1 這句話的意思簡單理解為:標準輸出和錯誤輸出都不會輸出出來。 [email protected]:/tmp>date>1.txt >/de

VMware虛擬機器安裝蘋果系統linux系統以及VMtools的安裝介紹(超詳細)

Ubuntu 簡介: 程式碼寫煩了,就沒事想學一點linux命令,但是又愁於沒有系統,所以就用一下午時間簡單的瞭解了下linux的安裝。Ubuntu這是一個基於linux核心的系統,因為linux是一個核心,本身並沒有視覺化介面,所以咱們這裡安裝linux論壇裡最火的Ubun

Linux 系統管理命令 - mpstat - CPU資訊統計

命令詳解 重要星級:         ★★★★☆ 功能說明:         mpstat 是 Multiprocessor Statistics 的縮寫,是一種實時系統監控工具。mpstat 命令會輸出 CPU 的一些統

Linux系統CPU核數等資訊檢視

物理機的基本資訊: 1、檢視CPU資訊 # 檢視cpu負載 ' uptime ' # cpu使用率 (沒有sar 則yum -y install sysstat) ' sar 1 1 '

Linux系統資源檢視 之 資源資訊

Linux系統資源檢視 之 資源資訊 1. 系統 版本資訊 核心版本 使用 uname 命令: -a : 檢視所有系統資訊 -r : 檢視核心版本資訊 -s : 檢視核心名稱

Android系統底層驅動除錯之資訊列印級別

(本文說明的平臺:msm8953,系統:Android N,其他平臺和系統可作為參考使用)    在Linux中除錯核心模組時使用printk函式來列印除錯資訊時,可以設定列印資訊的級別。那麼就肯定會有這樣一個設定,用於控制終端顯示的資訊級別的。這個是通過/proc/sys/

Android應用log資訊儲存到手機本地

在除錯android app時,為了方便檢視logcat資訊,所以選擇把log資訊儲存在本地。在沒有wifi的情況下,無法選擇無線連線除錯,儲存log資訊到本地也是不錯的選擇。 程式碼如下: importandroid.content.Context; import an

Linux系統安裝android studio

標籤(空格分隔):Linux android-studio 下載openjdk-7-jdk 通過終端直接安裝的方式,不需要進行jdk配置,如下: sudo apt-get install openjdk-7-jdk 使用以下程式查詢安裝的目錄

Linux系統下檢視伺服器CPU資訊

首先推薦一篇文章超執行緒、多核知識實戰,5分鐘讓你成為CPU專家,非常好的一篇文章,解釋超執行緒的含義,對CPU的結構也可以有一個巨集觀的理解。 1 檢視物理CPU的個數 cat /pr

Linux系統下吉林快-三平臺開發環境搭建以及關於變量的基本操作

end 進行 相關操作 and 之前 超級用戶 oss 這樣的 常見 有問題聯系Q1446595067吉林快-三平臺開發, 是一種面向對象的解釋型計算機程序設計語言,由荷蘭人Guido van Rossum於1989年發明,第一個公開發行版發行於1991年。 Python是

Linux 4.4核心移植以及Android系統編譯

Android預移植到tiny4412 kernel for tiny4412  前面的文章已經把uboot給弄好了,下面就可以用自己移植的uboot來啟動核心了。對於核心的移植,一開始選擇的是linux4.4的核心,為什麼選4.4,因為開始的時候是想

Linux系統檢視伺服器型號、CPU、RAM、ROM以及網絡卡資訊

首先是CPU方面的: 檢視CPU型號 # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 8 Intel(R) Xeon(R

linux系統用戶以及用戶組管理

love 當前 信息 生日 order 改進 永遠 個數 麻煩 【認識/etc/passwd和/etc/shadow】 這兩個文件可以說是linux系統中最重要的文件之一。如果沒有這兩個文件或者這兩個文件出問題,則你是無法正常登錄linux系統的。 /etc/passwd

Android平臺Camera實時濾鏡實現方法探討(十)--代碼地址以及簡單介紹(20160118更新)

div iss 將在 spa 方法 target 用途 net dsm 簡單做了個相機和圖片編輯模塊,時間原因非常多功能還沒有做。尚有BUG,見諒,將在以後抽時間改動 代碼地址 PS:請點個Star^-^ -----------------------

如何為Android平臺編譯 opencv3 和 opencv_contrib (Linux)

gre inter jni fuzzy dnn letter ott esc lis p { margin-bottom: 0.1in; direction: ltr; color: rgb(0, 0, 10); line-height: 120%; text-align:

linux系統搭建本地yum源以及搭建第3方軟件倉庫

linux 基礎 學習篇 搭建yum源與軟件倉庫一、搭建本地yum源 yum是上層軟件管理工具,可以解決軟件的依賴關系,但是yum能使用的前提是必須要有yum源,以及配置源的指向文件。1.配置鏡像安裝源一般情況,我會把重要的文件保存在根目錄下,這裏將鏡像導入根下的1.配置鏡