相关文章推荐
性感的小摩托  ·  vue3 + computed ...·  12 月前    · 
飞翔的甜瓜  ·  前端modbus-掘金·  1 年前    · 
朝气蓬勃的足球  ·  马普所韦业/Dierk ...·  1 年前    · 

一、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

如何启用内核动态调试日志

1、 目的:

为了规范软件工程师在 Android 代码编写过程中输出 Log 的行为,使得发布的产品中打印的 Log 是必须的,打印的 Log 的级别是能真实反映此 Log 对应的级别,标签、 Log 内容具有很好的可读性。

2、 适用范围

android 平台 Java c++ 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) c c++ 层调用:在 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 :系统已经出现了错误。

Info Warn Error 这三个等级的 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_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

运行时关闭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_ENABLE 4

③、定义标签

#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)、 Log tag 命名,使用 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;

对应的级别 打印方法
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类实现,该类定义于文件:
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、 FRAMEWORK层 import android.util.Slog;

对应的级别 打印方法
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>

对应的级别 打印方法
VERBOSE LOGV()
DEBUG LOGD()
INFO LOGI()
WARN LOGW()
ERROR LOGE()

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

JNI层 头文件:
#include <utils/Log.h>

对应的级别 打印方法
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
在相应的中间层代码中包含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.

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运行时信息和应用程序信息等等。

我们可以在打开Eclipse之后,选择Window –> Show View ->Other菜单,然后在Android->LogCat中选择LogCat,这样LogCat便会在Eclipse的下方区域出现了。

其中,在LogCat的右上方的5个字母分别表示了5种不同类型的日志信息(并以不同颜色加以区分,级别越高,颜色越突出):

1. [V]:详细(Verbose)信息,输出颜色为黑色

2. [D]:调试(Debug)信息,输出颜色是蓝色

3. [I]:通告(Info)信息,输出颜色为绿色

4. [W]:警告(Warn)信息,输出颜色为橙色

5. [E]:错误(Error)信息,输出颜色为红色,这里错误信息的级别最高,其次是警告信息,然后是通知信息和调试信息,级别最低的是详细信息。

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

在LogCat中,我们可以通告这5个字母图标选择要显示的信息类型,级别高于所选类型的信息也会在LogCat中显示,但级别低于所选类型的信息则不会被显示。

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

Log.v(tag,message); //verbose模式,打印最详细的日志

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

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

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

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

根据首字母对应VERBOSE,DEBUG,INFO,WARN,ERROR。

tag和message分别是两个String值

tag用来标记log消息的源头的. message是这条log的内容。

1.自定义打印TAG

自定义全局TAG

新建一个Application类LoggerDemoApplication,在onCreate方法中调用Logger.init(TAG)。

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

在AndroidManifest中加入application的name属性。

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

自定义单个TAG

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

3.关闭日志打印

在LoggerDemoApplication中,设置log的级别为NONE即可关闭日志打印。

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

3.更多设置

Logger
  .methodCount(3)                 // 设置打印方法栈的个数,默认是2
  .hideThreadInfo()               // 隐藏线程信息,默认显示
  .methodOffset(2)                // 设置调用堆栈的偏移值,默认是0
  .logAdapter(new AndroidLogAdapter()); // 自定义Log适配器
一、LK层:
首先,在LK中,有一个对log打印级别的控制文档,其路径一般为:vendor\mediatek\proprietary\bootable\bootloader\lk\include\debug.h(以mtk平台为例)
在include\debug.h重要代码为:
//下面做个判断:意思是如果makefile(相应的平台mk文件) 定义了DEBUG的值,就是用它,否则默认为2
                                    (本文说明的平台:msm8953,系统Android N,其他平台系统可作为参考使用)    在Linux中调试内核模块时使用printk函数来打印调试信息时,可以设置打印信息级别。那么就肯定会有这样一个设置,用于控制终端显示的信息级别的。这个是通过/proc/sys/kernel/printk文件内容来控制。    在Android N版本中的默认设置是7    0    1    7  ...
                                    我们在调试adb时不能使用logcat,这个时候我们需要把adb的log输出到串口,init就能实现,我们仿造init的代码,在adbd的main函数中调用了如下函数InitKernelLogging(nullptr);这个函数在init进程中也有调用。这个函数的意思把标准输入输出,标准错误全部写到/sys/fs/selinux/null,也就没有了。然后定了一InitLogging为kernel...
                                    Android修改kernel和logcat的输出级别
文章目录Android修改kernel和logcat的输出级别kernel查看当前输出级别输出宏定义指定级别高通初始化服务java备注
kernel
查看当前输出级别
cat /proc/sys/kernel/printk
6       6       1       7
# kernel/msm-4.9/kernel/printk/printk.c
int console_printk[4] = {
        CONSOLE_LOG
                                    Android - Log的等级: Verbose,Debug,Info,Warn,Error - ALOGV,ALOGD,ALOGI,ALOGW,ALOGE
	发布时间:2018-08-28 来源:网络 上传者:用户
	摘要:http://blog.csdn.net/liuxd3000/article/details/137681411、  目的:为了规范软件工程师...
先实现HIDL,打通从HAL到framework层
可以把自己的HIDL模块建立在hardware/interfaces/、frameworks/hardware/interfaces/、 system/hardware/interfaces/、 system/libhidl/transport/或者是vendor/<VENDOR>/proprietary/hardware/interfaces/等目录.
                                    引入:Python中有个logging模块可以完成相关信息的记录,在debug时用它往往事半功倍一、日志级别(从低到高):DEBUG :详细的信息,通常只出现在诊断问题上INFO:确认一切按预期运行WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。ERROR:更严重的问题,软件没能执行一些功能CRITICAL :一个严...
                                    讲RIL这个TAG的日志级别设置为I,可以在下面文件中修改
device/mediatek/common/device.mk:2702: PRODUCT_PROPERTY_OVERRIDES += persist.log.tag.RIL=I
也可以通过adb去设置:setproppersist.log.tag.RIL I
                                    在我们开发过程中,内核的信息一开机就会很多,然后一直打个不停,很烦人,也不好看调试信息,更不好在串口终端输入相关的命令进行调试。那么有什么办法可以解决?1、在kernel中修改log默认等级,kernel-3.18/include/linux/printk.hstatic inline void console_verbose(void)函数中的console_loglevel = CONSOLE...