[置顶] Android学习之Logger driver

Android logger System 由misc的logger driver和相关framework接口组成, 与syslog相比, 它区分了4种不同事件类型, 不同的事件类型有各自的kernel space的循环缓冲来提供, 这样的log更加清晰,对于user space端来说更加友好. 目前logger driver正在寻求被kernel main stream所接受, 不久的将来将会merge到main stream.


驱动层的实现

定义了4个不同的事件类型: main, event, radio, system. 它们都作为misc驱动存在, 初始之后,在/dev/log/下能看到4个对应的设备文件

4个循环缓冲, 大小在编译内核的时候就指定了,如下

DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024)
DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024)
DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024)
支持同步,异步读写并通过fix_up_readers来减少旧log被覆盖的可能性.

与其它android的自定义的software driver一样, 也提供了一些实用的ioctl来给用户层使用.

LOGGER_GET_LOG_BUF_SIZE 
LOGGER_GET_LOG_LEN 
LOGGER_GET_NEXT_ENTRY_LEN 
LOGGER_FLUSH_LOG

其中使用了wait queue来进行读写之间的控制.

每条log都由driver来记录相应的pid, tgid及timestamp, 同时, 用户层会提供相应的level, tag及具体的log内容.

实现的代码相对简单, 这里就详细解释了:)


framework层的接口


    从上图很清楚的可以看出, android的logger系统主要由4个部分组成:

logger driver, 就是第一部分所介绍的log设备

logger framework, 为其它几个部分交互及扩展开发提供的中间层

logcat, 用户态的log读取工具

ddms extension, 与ADT集成的可视化log reader

    如上所述,总共有4种类型的log, 其中event的log是以binary的形式来记录的, 所以在读取它的时候需要做额外处理.

这点从liblog下的logd_write.c中的write log函数就可以看出来了.
__android_log_write
__android_log_bwrite

    应用程序通常使用的是android.util.Log class, 而event log使用的是android.util.Event class, 它比较特殊,对应与其中binary的tags的数据在/system/etc/event-log-tags中.

   system event对应的使用的是android.util.Slog class, 这里大家没有看到radio对应的log类, 是因为framework自动通过分析所有现有log中的tag,radio相关的信息放入对应的radio设备中.

   如liblog/log_write.c中:

    /* XXX: This needs to go! */   
    if (!strcmp(tag, "HTC_RIL") || 
        !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
        !strcmp(tag, "AT") || 
        !strcmp(tag, "GSM") ||
        !strcmp(tag, "STK") ||
        !strcmp(tag, "CDMA") ||        
        !strcmp(tag, "PHONE") ||       
        !strcmp(tag, "SMS"))
            bufID = LOG_ID_RADIO;
   
    另外, android也为调试android native程序提供了一个叫做loggerwrap的使用程序, 能够把通常的native程序写入stdout/stderr的信息经过包装放入对应的logger系统中.

    还可以通过在init.rc指定

service logcat /system/bin/logcat -f /dev/kmsg 
      oneshot

    来使得所有logger所产生的log写入dmsg的空间.而不是独立于通常的kernel log空间.

    关于ddms与liblog的接口的相关实现,参见system/core/logcat/及sdk/ddms/libs/下的实现.ddms即host端是通过调用adb logcat来与device交互,从而获得device端的各种log,再映射到eclipse的ADT中.

其它,

    nonseekable_open, 用来实现不需要支持seek动作的文件的打开动作

    wait queue, 使用了kernel提供的sleep/wake的wait queue机制, 关于wait queue参见<Linux.Kernel.Development>的第四章, Sleeping and Waking up


参考资料:

    Android Logger

    Android Logging System

    <Android Internals: System> 2.3.4

    RFC: android logger feedback request

你可能感兴趣的:(android,System,Class,logging,extension,events)