日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

LINUX系统以及ANDROID 平台log信息输出级别设置 [MTK]

發(fā)布時間:2025/4/16 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LINUX系统以及ANDROID 平台log信息输出级别设置 [MTK] 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、LK層:

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

在include\debug.h重要代碼為:

//下面做個判斷:意思是如果makefile(相應(yīng)的平臺mk文件) 定義了DEBUG的值,就是用它,否則默認(rèn)為2等級
//在bootloader\lk\project\rlk6737m_65_n.mk中:DEBUG := 2

#if defined(DEBUG)
#define?DEBUGLEVEL DEBUG
#else
#define?DEBUGLEVEL?2
#endif


/* debug levels 調(diào)試級別*/???
#define?CRITICAL?0??????//數(shù)字越小級別越高,打印的信息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);

//下面的這些打印方法具體含義是:如果級別<=之前定義的調(diào)試級別的話就打印否則不打印

#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)

相關(guān)DEBUG的定義有不同的方式方法,如下例子:

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

DEBUG?:=2??

這時也要注意:不要看到這里是2就表示都會打印,我現(xiàn)在遇到一個項目雖然在\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

最后發(fā)現(xiàn)在類似的bootable\bootloader\lk\target\rlk6757_66_n(project)\rules.mk中:

LK_PROFILING?:=?no??????//LK_PROFILING := yes? 一般項目都會使這個宏,所以之前并沒有太關(guān)注,后續(xù)項目可能會為了性能,把log后期以這種方式關(guān)掉,注意一下

法②、在lk\include\platform\debug.h中定義了這個函數(shù):

void debug_set_trace_level(int trace_type, int level);??//設(shè)置調(diào)試級別

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

#define DEBUG??//這里定義了這個宏

#ifdef DEBUG????//判斷是不是定義了,定義了就執(zhí)行下面的
#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 系統(tǒng)無法使用*/
#define KERN_ALERT?? ?KERN_SOH "1"????/* action must be taken immediately必須立即采取行動 */
#define KERN_CRIT?? ?KERN_SOH "2"????/* critical conditions臨界狀態(tài)---重要信息 */
#define KERN_ERR?? ?KERN_SOH "3"????/* error conditions錯誤狀況 */
#define KERN_WARNING?? ?KERN_SOH "4"????/* warning conditions 報警狀態(tài)*/
#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 調(diào)試級別信息*/

#define KERN_DEFAULT?? ?KERN_SOH "d"?? ?/* the default kernel loglevel 默認(rèn)的內(nèi)核loglevel----一般都為4*/

在kernel-3.18\include\linux\printk.h中定義了各默認(rèn)日志的級別

/* 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"默認(rèn)的消息日志級別*/
#define CONSOLE_LOGLEVEL_DEFAULT 7?/* anything MORE serious than KERN_DEBUG 默認(rèn)的控制臺日志級別*/

#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級別的打印內(nèi)核默認(rèn)為4打印級別。

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

int console_printk[4] = {
?? ?CONSOLE_LOGLEVEL_DEFAULT,?? ?/* console_loglevel控制log級別 */
?? ?MESSAGE_LOGLEVEL_DEFAULT,?? ?/* default_message_loglevel默認(rèn)的消息日志級別?*/
?? ?CONSOLE_LOGLEVEL_MIN,?? ??? ?/* minimum_console_loglevel最低的控制臺日志級別*/
?? ?CONSOLE_LOGLEVEL_DEFAULT,????/* default_console_loglevel默認(rèn)的控制臺日志級別?*/
};

我們的做法:

①、我們可以在查看當(dāng)前控制臺的打印級別:

cat /proc/sys/kernel/printk

7???? 4???? 1???? 7

四個值的含義:控制臺日志級別、默認(rèn)的消息日志級別、最低的控制臺日志級別和默認(rèn)的控制臺日志級別

其中第一個“7”表示內(nèi)核打印函數(shù)printk的打印級別,只有級別比他高的信息才能在控制臺上打印出來,既 0-6級別的信息

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

如果用echo 8? >??/proc/sys/kernel/printk這樣所有級別<8,(0-7)的消息都可以顯示在控制臺上。
不夠打印級別的信息會被寫到日志中可通過dmesg?命令來查看

設(shè)置控制終端打印級別為0,就沒有了任何輸出

如果需要臨時關(guān)閉kernel的log,可以再串口輸入命令:echo "0 0 0 0" > /proc/sys/kernel/printk
需要恢復(fù)的話可以輸入:echo ”7 4 1 7“ > /proc/sys/kernel/printk

③、printk函數(shù)的使用

??????printk(打印級別? “要打印的信息”)


MTK問題:How to enable kernel dynamic debug log

???? 如何啟用內(nèi)核動態(tài)調(diào)試日志

[DESCRIPTION]?在kernel module debug 對照代碼的時候,發(fā)現(xiàn)使用pr_debug 打印的log 無法找到,怎樣在mobilelog 和uart log中開啟pr_debug ?pr_debug()針對這種打印信息[SOLUTION]1?打開dynamic debug feature<project>_defconfig 中設(shè)置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服務(wù)器模塊中的所有消息
? ? ? ? ? ? echo -n "module nfsd +p" > /sys/kernel/debug/dynamic_debug/control?3mobile log 中 pr_debug log? ? ?pr_debug 默認(rèn)以debug 等級輸出到kernel log 中, mobilelog 抓到的kernellog 會包含?4?uartlog 中 pr_debug log? ? ?默認(rèn)pr_debug log 不送uart ,可以通過以下方式打開:? ? ? ? ?1.adb起來后,echo 8 > /proc/sys/kernel/printk
? ? ? ? ?2.改code ,修改console 默認(rèn)輸出log等級
? ? ? ? ? ? ? ?kernel-3.18/include/linux/printk.h : #define CONSOLE_LOGLEVEL_DEFAULT 7 -->#define CONSOLE_LOGLEVEL_DEFAULT 8

三、關(guān)于android日志打印級別

1、??目的:

為了規(guī)范軟件工程師在Android代碼編寫過程中輸出Log的行為,使得發(fā)布的產(chǎn)品中打印的Log是必須的,打印的Log的級別是能真實反映此Log對應(yīng)的級別,標(biāo)簽、Log內(nèi)容具有很好的可讀性。

2、??適用范圍

android平臺Javac++c代碼編寫。

3、??Log的調(diào)用及等級介紹

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

?[D]:調(diào)試(Debug)信息,輸出顏色是藍(lán)色

?[I]:通告(Info)信息,輸出顏色為綠色

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

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

[V]:詳細(xì)(Verbose)信息,輸出顏色為黑色

[assert],新版本加入的。

這里錯誤信息0的級別最高,其次是警告信息1,然后是通知信息2調(diào)試信息3,級別最低的是詳細(xì)信息4

我們?nèi)绻胱屗械男畔⒍即蛴〕鰜硪话愣级x成debug級別。


(2)java層調(diào)用:在java層調(diào)用import android.util.Log,在需要打印Log的地方執(zhí)行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”這個標(biāo)簽的,則需執(zhí)行:adb logcat? -s "MY_LOG_TAG"???即可

(3)cc++層調(diào)用:在c,c++層包含此頭文件:#include <cutils/log.h>,在需要調(diào)用Log的地方執(zhí)行:ALOGV,ALOGD,ALOGI,ALOGW,ALOGE

??????? 敝人認(rèn)為:頭文件可以寫:?#include <utils/Log.h>? ---》 #include <cutils/log.h>----》#include <log/log.h>,中的任何一個,其實質(zhì)在log/log.h中

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

???????? 如:

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

??????????? SLOGE("xxxxxxxxxxxxxxxxxx"); //輸出到system緩沖區(qū)

???????????? 還需要修改 Android.mk

????????????? LOCAL_SHARED_LIBRARIES :=?liblog

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

3 libcore

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

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

Verbose:?開發(fā)調(diào)試過程中一些詳細(xì)信息,不應(yīng)該編譯進產(chǎn)品中,只在開發(fā)階段使用。

Debug:?用于調(diào)試的信息,編譯進產(chǎn)品,但可以在運行時關(guān)閉。

Info:例如一些運行時的狀態(tài)信息,這些狀態(tài)信息在出現(xiàn)問題的時候能提供幫助。

Warn:警告系統(tǒng)出現(xiàn)了異常,即將出現(xiàn)錯誤。

Error:系統(tǒng)已經(jīng)出現(xiàn)了錯誤。

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

4、??具體規(guī)則

1)、Verbose等級的Log,請不要在user版本中出現(xiàn)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,默認(rèn)不開啟,通過終端命令開啟

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

運行時關(guān)閉log:?在終端輸入:setprop log.tag.MyActivity INFO

?

示例c、c++部分:

#include<cutils/log.h>

#defineLOG_CTL?debug.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

運行時關(guān)閉log:?在終端輸入:setpropdebug.MyActivity.enablelog 0

?

最近遇到一個問題:

在.cpp應(yīng)用代碼中有類似這樣的信息:

?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信息中就是打印不出來,我懷疑級別不夠。最終發(fā)現(xiàn)確實有定義級別的地方:

打開:system\core\include\log\log.h發(fā)現(xiàn):

/*
?* 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,表示不關(guān)閉
#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???//這里在源代碼已經(jīng)定義好了,但級別為1,表示只能打印LOGE最高級別的錯誤信息,其它的都不能打印,我們調(diào)試是可以在這里改

/*
?* 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日志記錄宏,即標(biāo)簽,方便過濾log消息。

#ifndef LOG_TAG
#define LOG_TAG NULL??? //如果沒有定義則我們默認(rèn)標(biāo)簽為NULL
#endif

例如:#define LOG_TAG "JIANMIN.NIU"??? ?//在源代碼定義這個,則在篩選log時執(zhí)行:adb logcat -s "jianmin.niu" 即可

總結(jié):

如果要輸出打印信息:

①、定義頭文件

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

②、定義打印級別

#define MTK_LOG_ENABLE4???

③、定義標(biāo)簽

#define LOG_TAG "JIANMIN.NIU"?
④、調(diào)用打印信息

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

⑤、執(zhí)行

adb logcat -s "jianmin.niu"?? //獲取相關(guān)信息即可

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

或者是不是Debug等級的log,默認(rèn)不開啟,通過終端命令開啟才行

⑧或者用一下方法

添加#include "cutils/logd.h"

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

直接調(diào)用__android_log_print(ANDROID_LOG_ERROR,TAG,"print content");函數(shù)打印log信息。

__android_log_print 函數(shù)在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]、法一:失敗

??????????關(guān)機充電的時候,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

結(jié)果:按照你描述的方式修改init.rc和init.mt6735.rc后 show_animation_common.c文件中添加的ALOGD,SLOGE,SLOGD 打印串口log還是均無法輸出出來

【2】法二:

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

結(jié)果:關(guān)機充電連不上adb的怎么使用logcat?
關(guān)機充電只能打串口log,串口log使用不了logcat

【3】、法三:

???????===>> 下面第一步中有開console, 所以uart 可以獲取console, 第二步中有拉logd和logcat 就能用logcat 抓log
關(guān)機充電的時候,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

串口上應(yīng)當(dāng)是可以輸入command的
您看一下是否TX、RX,地線都有接

結(jié)果:沒有出來

【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 等
定義應(yīng)當(dāng)是在
/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)

結(jié)果:使用 KPOC_LOGI 就可以打印了



(3)、禁止使用new Exception("print trace").printStackTrace()或者Log. getStackTraceString(Exception)方式打印普通調(diào)試信息,因為這種方式打印Log非常消耗系統(tǒng)資源。此種方式打印Log一般只出現(xiàn)try..catch某個異常使用。

(4)、Logtag命名,使用Activity名稱或者類、模塊的名稱,不要出現(xiàn)自己的姓名拼音或其他簡稱。在c++/c代碼中調(diào)用ALOGD等宏函數(shù),參數(shù)沒有傳入tag,需要在文件頭部#define LOG_TAG"YOUR_TAG_NAME"。------》如:#define LOG_TAG "BootLogoUpdater"

(5)、Log的內(nèi)容,不要出現(xiàn)公司名稱、個人名稱或相關(guān)簡稱,Log內(nèi)容不要出現(xiàn)無意義的內(nèi)容,如連續(xù)的等號或星號或連續(xù)的數(shù)字等,Log內(nèi)容要方便其他分析Log的人員查看。

(6)、Log輸出的頻率需要控制,例如1s打印一次的Log,盡量只在eng版本使用,user版本如需開啟,請默認(rèn)關(guān)閉,通過設(shè)置setprop命令來開啟。

5、各層詳細(xì)說明

1. java層

import android.util.Log;

對應(yīng)的級別 打印方法 ?
VERBOSE Log.v()
DEBUG Log.d()
INFO Log.i()
WARN Log.w()
ERROR Log.e()

方法:

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


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

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


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

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

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

Config類的實現(xiàn)在文件: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 (默認(rèn)eng)
TARGET_BUILD_TYPE: debug release (默認(rèn)release)

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

對java層log輸出的實現(xiàn)修改:
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、?FRAMEWORK層import android.util.Slog;

對應(yīng)的級別 打印方法 ?
VERBOSE Slog.v()
DEBUG Slog.d()
INFO Slog.i()
WARN Slog.w()
ERROR Slog.e()

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

HAL層:

頭文件:
#include <utils/Log.h>

對應(yīng)的級別 打印方法 ?
VERBOSE LOGV()
DEBUG LOGD()
INFO LOGI()
WARN LOGW()
ERROR LOGE()

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


JNI層頭文件:
#include <utils/Log.h>

對應(yīng)的級別 打印方法 ?
VERBOSE LOGV()
DEBUG LOGD()
INFO LOGI()
WARN LOGW()
ERROR LOGE()

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


?JNI層代碼需包含頭文件frameworks/base/include/utils/Log.h,實際上這個頭文件include了HAL層代碼使用的頭文件system/core/include/cutils/log.h
?在相應(yīng)的中間層代碼中包含log TAG的地方,使用如下形式:
??? //#define? NDEBUG
??? #define? LOG_NDEBUG? 1
??? #define? LOG_TAG? "RFID_HAL"
?? ?#include <cutils/log.h>
?? ?
下面是關(guān)于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.
??
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來打印系統(tǒng)日志信息

logCat是用來獲取系統(tǒng)日志信息的工具,它可以捕獲的信息包括Dalvik虛擬機產(chǎn)生的信息,進程信息,ActivityManager信息,PackagerManager信息,Android運行時信息和應(yīng)用程序信息等等。

我們可以在打開Eclipse之后,選擇Window?–>?Show?View?->Other菜單,然后在Android->LogCat中選擇LogCat,這樣LogCat便會在Eclipse的下方區(qū)域出現(xiàn)了。

其中,在LogCat的右上方的5個字母分別表示了5種不同類型的日志信息(并以不同顏色加以區(qū)分,級別越高,顏色越突出):

1.?[V]:詳細(xì)(Verbose)信息,輸出顏色為黑色

2.?[D]:調(diào)試(Debug)信息,輸出顏色是藍(lán)色

3.?[I]:通告(Info)信息,輸出顏色為綠色

4.?[W]:警告(Warn)信息,輸出顏色為橙色

5.?[E]:錯誤(Error)信息,輸出顏色為紅色,這里錯誤信息的級別最高,其次是警告信息,然后是通知信息和調(diào)試信息,級別最低的是詳細(xì)信息。

6.[assert],新版本加入的。

在LogCat中,我們可以通告這5個字母圖標(biāo)選擇要顯示的信息類型,級別高于所選類型的信息也會在LogCat中顯示,但級別低于所選類型的信息則不會被顯示。

androidsdk中提供了log輸出的api,方法在android.util.Log類中。

Log.v(tag,message);???????//verbose模式,打印最詳細(xì)的日志?

Log.d(tag,message);???????//debug的日志?

Log.i(tag,message);???????//info的日志?

Log.w(tag,message);?? ? ? //warn的日志?

Log.e(tag,message);???????//error的日志?

根據(jù)首字母對應(yīng)VERBOSE,DEBUG,INFO,WARN,ERROR。

tag和message分別是兩個String值?

tag用來標(biāo)記log消息的源頭的. message是這條log的內(nèi)容。

1.自定義打印TAG

自定義全局TAG

新建一個Application類LoggerDemoApplication,在onCreate方法中調(diào)用Logger.init(TAG)。

public class LoggerDemoApplication extends Application {private String TAG = "LoggerDemo";@Overridepublic void onCreate() {super.onCreate();Logger.init(TAG);} }

在AndroidManifest中加入application的name屬性。

<applicationandroid:name=".LoggerDemoApplication"... </application>

自定義單個TAG

Logger.t("MyTag").d("Hello World!");

3.關(guān)閉日志打印

在LoggerDemoApplication中,設(shè)置log的級別為NONE即可關(guān)閉日志打印。

Logger.init(TAG).logLevel(LogLevel.NONE);

3.更多設(shè)置

Logger.methodCount(3) // 設(shè)置打印方法棧的個數(shù),默認(rèn)是2.hideThreadInfo() // 隱藏線程信息,默認(rèn)顯示.methodOffset(2) // 設(shè)置調(diào)用堆棧的偏移值,默認(rèn)是0.logAdapter(new AndroidLogAdapter()); // 自定義Log適配器 }

總結(jié)

以上是生活随笔為你收集整理的LINUX系统以及ANDROID 平台log信息输出级别设置 [MTK]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 性色av一区二区 | 日韩一级视频在线观看 | 久久久久久97 | 少妇厨房愉情理伦bd在线观看 | 东北女人啪啪ⅹxx对白 | 少妇一级淫免费观看 | 性猛交富婆╳xxx乱大交麻豆 | 色就是色av| 国产精品香蕉 | 老鸭窝视频在线观看 | 欧洲亚洲自拍 | 银娇在线观看 | 美腿丝袜亚洲色图 | 色视频在线观看 | 亚洲一区二区三区麻豆 | wwwxxx日韩| 污污视频在线观看网站 | 91免费版在线 | 日日日插插插 | 69xxxx国产| 成人性生交大片免费看中文 | 五月婷婷影院 | 日韩欧美一级 | 日本爽爽 | 国产伦理一区二区三区 | 999www| 日韩r级在线观看 | 欧美成人精品 | 欧美精品久久久久性色 | 日日天天| 中国黄色一级大片 | 人与禽性7777777 | 免费不卡视频 | 草草影院最新 | 国产色秀视频 | av噜噜在线 | 91超碰在线观看 | 中文字幕日韩有码 | 九九视频在线播放 | 人人人草| 日本三级韩国三级美三级91 | 精品久久久亚洲 | 欧美美女性视频 | 精品久久久久久亚洲综合网站 | 91麻豆精品国产91久久久久久久久 | 国产精彩视频在线观看 | 亚洲色图在线视频 | 四虎精品 | 蜜桃视频成人在线观看 | 特黄a级片| 亚洲视频大全 | 青青青青青草 | 久久久久无码国产精品不卡 | 日韩黄色在线视频 | 日韩免费高清 | 金瓶狂野欧美性猛交xxxx | 国产女人叫床高潮大片免费 | 久久亚| 水多多在线 | 亚洲精品在线免费播放 | 亚洲啪啪网址 | 波多野在线观看 | 五月婷婷综合网 | av成人在线网站 | 久久精品国产亚洲av成人 | 欧美又粗又大xxxxbbbb疯狂 | 偷拍中国夫妇高潮视频 | 张柏芝54张无删码视频 | 无码精品一区二区三区在线播放 | 国产精品啪啪啪视频 | 亚洲精品9999 | 欧美一级片免费看 | 天天视频国产 | 亚洲精品欧洲 | 欧美日b视频 | 国产在线观看中文字幕 | 中文字幕系列 | 含羞草一区二区三区 | 日韩av中文字幕在线免费观看 | 99热这里只有精品在线 | 亚洲资源站 | 三级免费观看 | 免费在线观看网址入口 | 97人妻精品一区二区三区软件 | 亚洲一二三精品 | 久久重口味 | 一级片免费 | 日本中文字幕第一页 | 日韩在线观看你懂的 | 在线色导航 | 麻豆黄色片 | 青青射 | 精品亚洲在线 | 国产又粗又猛又爽又黄的视频一 | 国产综合第一页 | 视频这里只有精品 | 97人人看| 欧美日韩字幕 | 一区二区三区精品久久久 |