Android Log系统

一,log是按照种类存储在不同的buffer中。
    /** @hide */ public static final int LOG_ID_MAIN = 0;    
用Log.v, Log.d, .... 输出    

/** @hide */ public static final int LOG_ID_RADIO = 1;    

用RLog.v, Log.d, .... 输出  

 /** @hide */ public static final int LOG_ID_EVENTS = 2;  

 用EventLog.writeEvent方法输出    

/** @hide */ public static final int LOG_ID_SYSTEM = 3;    

用SLog.v, Log.d, .... 输出  

 /** @hide */ public static final int LOG_ID_CRASH = 4;      

RuntimeInit.Clog_e方法和debuggerd应用中会使用

二,同一种log buffer中,log是有优先级的。
    /**
     * Priority constant for the println method; use 
Log.v.
     */
    public static final int VERBOSE = 2;
    /**
     * Priority constant for the println method; use 
Log.d.
     */
    public static final int DEBUG = 3;
    /**
     * Priority constant for the println method; use 
Log.i.
     */
    public static final int INFO = 4;
    /**
     * Priority constant for the println method; use 
Log.w.
     */
    public static final int WARN = 5;
    /**
     * Priority constant for the println method; use 
Log.e.
     */
    public static final int ERROR = 6;
    /**
     * Priority constant for the println method.
     */
    public static final int ASSERT = 7;
其中ASSERT是最高的log优先级,用在Log.wtf函数中。
   (In Log.java)static
 int wtf(int logId, String tag, String msg, Throwable tr, boolean localStack,
            boolean system) {
        TerribleFailure what = new TerribleFailure(msg, tr);
        int bytes = println_native(logId, ASSERT, tag, msg + '\n'
                + getStackTraceString(localStack ? what : tr));
        sWtfHandler.onTerribleFailure(tag, what, system);
        return bytes;
    }
    (In Log.java)private
 static TerribleFailureHandler sWtfHandler = new TerribleFailureHandler() {            

public void onTerribleFailure(String tag, TerribleFailure what, boolean system) {                

RuntimeInit.wtf(tag, what, system);            }        };
    (In RuntimeInit.java)public static voidwtf(String
 tag, Throwable t, boolean system) {
        try {
            if (ActivityManagerNative.getDefault().handleApplicationWtf(
                    mApplicationObject, tag, system, new ApplicationErrorReport.CrashInfo(t))) {
                // The Activity Manager has already written us off -- now exit.
                Process.killProcess(Process.myPid());
                System.exit(10);
            }
        } catch (Throwable t2) {
            Slog.e(TAG, "Error reporting WTF", t2);
            Slog.e(TAG, "Original WTF:", t);
        }
    }

三,利用system property动态调节log是否输出。
在调用Log类的输出函数之前,用isLoggable判断一下是否要输出
    (In Log.java)public
 static native boolean isLoggable(String tag, int level);
    (In Log.java)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 'W': return levels.warn;        

case 'E': return levels.error;        

case 'A': return levels.assert;        

case 'S': return -1; // SUPPRESS    }    return levels.info;
}

 

 

 

 

 

    (In Log.java)static
 jboolean isLoggable(const char* tag, jint level) {
    String8 key;    key.append(LOG_NAMESPACE);    

key.append(tag);   
// 生成属性的名字,如"log.tag.ActivityManager"    

char buf[PROPERTY_VALUE_MAX];    if (property_get(key.string(), buf, "") <= 0)

{    // 获取指定的tag对应的log的最低输出level        

buf[0] = '\0';    

}    

int logLevel = toLevel(buf);    

return logLevel >= 0 && level >= logLevel;  // 如果要输出的level大于显示log的最低level,则返回true
}


四,C++层的log。
要使用c++层的log,需要先定义LOG_TAG,如在android_util_Log.cpp文件中。

#define LOG_TAG "Log_println"
#include <utils/Log.h>

(In utils/Log.h)
#include <cutils/log.h>

(In cutils/log.h)
#include <log/log.h>

(In log/log.h)
#ifndef LOG_TAG
#define LOG_TAG NULL
#endif

#ifndef ALOGV

#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)    
// 输出log的宏定义,用于输出MAIN log,优先级为verbose,tag取自包含该log.h文件的文件中#else#define ALOGV(...) __ALOGV(__VA_ARGS__)

#endif

#endif

#ifndef ALOG
#define ALOG(priority, tag, ...) \
    LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
/*
 * Log macro that allows you to specify a number for the priority.
 */
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
    android_printLog(priority, tag, __VA_ARGS__)
#endif

类似的宏定义如下:
#define 
ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))

#ifndef SLOGV
#define __SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0)
#else
#define SLOGV(...) __SLOGV(__VA_ARGS__)
#endif
#endif

#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))

#define SLOGW(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define SLOGE(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))

#ifndef RLOGV
#define __RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0)
#else
#define RLOGV(...) __RLOGV(__VA_ARGS__)
#endif
#endif
#define RLOGD(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define RLOGI(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define RLOGW(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define RLOGE(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))

五,其他的log使用情况。
public class LogWriter extends Writer {    

private void flushBuilder() {        

if (mBuilder.length() > 0) {            

Log.println_native(mBuffer, mPriority, mTag, mBuilder.toString());            

mBuilder.delete(0, mBuilder.length());        

}    

}

}
public class LogPrinter implements Printer {    

public void println(String x) {        

Log.println_native(mBuffer, mPriority, mTag, x);    

}

}

在binder中的使用:
class 
LogTextOutput : public BufferedTextOutput
{
public:
    LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
    virtual ~LogTextOutput() { };
protected:
    virtual status_t writeLines(const struct iovec& vec, size_t N)
    {
        //android_writevLog(&vec, N);       <-- this is now a no-op
        if (N != 1) ALOGI("WARNING: writeLines N=%zu\n", N);
        ALOGI("%.*s", (int)vec.iov_len, (const char*) vec.iov_base);
        return NO_ERROR;
    }
};

static 
LogTextOutput gLogTextOutput;
// Android MAIN log, 优先级为Infostatic FdTextOutput gStdoutTextOutput(STDOUT_FILENO);  // 输出到stdoutstatic FdTextOutput gStderrTextOutput(STDERR_FILENO);  // 输出到err
三个快捷方式TextOutput& 
alog(gLogTextOutput);TextOutput& 
aout(gStdoutTextOutput);TextOutput& 
aerr(gStderrTextOutput);
--------------------- 
作者:WangMark 
来源:CSDN 
原文:https://blog.csdn.net/petib_wangwei/article/details/54891272 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值