首页 > 系统 > Android > 正文

Android Log系统

2019-11-09 17:46:01
字体:
来源:转载
供稿:网友

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

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表