Android Log系统

    xiaoxiao2021-03-26  41

    一,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.javastatic 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.javaprivate 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.javapublic static native boolean isLoggable(String tag, int level);

        In Log.javastatic 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.javastatic 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, 优先级为Info static FdTextOutput gStdoutTextOutput(STDOUT_FILENO);  // 输出到stdout static FdTextOutput gStderrTextOutput(STDERR_FILENO);  // 输出到err 三个快捷方式 TextOutput& alog(gLogTextOutput); TextOutput& aout(gStdoutTextOutput); TextOutput& aerr(gStderrTextOutput);

    转载请注明原文地址: https://ju.6miu.com/read-664077.html

    最新回复(0)