本文编辑整理自: http://www.linuxidc.com/Linux/2011-07/38987.htm 一、简介 Android为我们提供了一个轻量级的日志系统,在用户空间分别提供了Java接口和C/C++接口来使用这个日志系统。 关于Android的日志系统,请先阅读《 Android中LOG机制详解》,《 在Android的c/c++域使用LOG》,《 logcat命令详解Android日志系统最终还是以驱动程序的形式实现在内核空间的。Logger驱动程序主要由两个文件构成,分别是       kernel/common/drivers/staging/Android/logger.h               kernel/common/drivers/staging/Android/logger.c  本文将介绍Logger驱动程序的相关数据结构,然后对Logger驱动程序源代码进行情景分析,分别日志系统初始化情景、日志读取情景和日志写入情景。 二、基本数据结构 我们首先来看logger.h头文件的内容: #ifndef _LINUX_LOGGER_H    #define _LINUX_LOGGER_H       #include    #include       struct logger_entry {       __u16        len;     /* length of the payload */       __u16        __pad;   /* no matter what, we get 2 bytes of padding */       __s32        pid;     /* generating process's pid */       __s32        tid;     /* generating process's tid */       __s32        sec;     /* seconds since Epoch */       __s32        nsec;    /* nanoseconds */       char         msg[0]/* the entry's payload */   };      #define LOGGER_LOG_RADIO    "log_radio" /* radio-related messages */    #define LOGGER_LOG_EVENTS   "log_events"    /* system/hardware events */    #define LOGGER_LOG_SYSTEM "log_SYSTEM" /* system/framework  message*/ #define LOGGER_LOG_MAIN     "log_main"  /* everything else */       #define  LOGGER_ENTRY_MAX_LEN        (4*1024)    #define  LOGGER_ENTRY_MAX_PAYLOAD    \        (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))      #define __LOGGERIO  0xAE       #define LOGGER_GET_LOG_BUF_SIZE     _IO(__LOGGERIO, 1) /* size of log */    #define LOGGER_GET_LOG_LEN      _IO(__LOGGERIO, 2) /* used log len */    #define LOGGER_GET_NEXT_ENTRY_LEN   _IO(__LOGGERIO, 3) /* next entry len */    #define LOGGER_FLUSH_LOG        _IO(__LOGGERIO, 4) /* flush log */       #endif /* _LINUX_LOGGER_H */   logger_entry 是一个用于描述一条 Log 记录的结构体。 len 成员变量记录了这 条记录的有效负载的长度,有效负载指定的日志记录本身的长度,但是不包括用于描述这个记录的 struct logger_entry 结构体 。我们调用Android.util.Log接口来使用日志系统时,会指定日志的优先级别Priority、Tag字符串以及Msg字符串;Priority + Tag + Msg三者内容的长度加起来就是记录的有效负载长度了。 __pad 成员变量是用来对齐结构体的。 pid tid 成员变量分别用来标明是 哪条进程 哪个线程 写入的这条记录。 sec nsec 成员变量记录日志写的时间。 msg 成员变量记录的就有效负载的内容了,它的大小由 len 成员变量来确定。        接着定义两个宏:        #define  LOGGER_ENTRY_MAX_LEN              (4*1024)               #define  LOGGER_ENTRY_MAX_PAYLOAD    \                          (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) 从这两个宏可以看出,每条日志记录的有效负载长度加上结构体 logger_entry 的长度不能超过4K个字节。        logger.h文件中还定义了其它宏,读者可以自己分析,在下面的分析中,碰到时,我们也会详细解释。再来看logger.c文件中,其它相关数据结构的定义: /*   * struct logger_log - represents a specific log, such as 'main' or 'radio'   *   * This structure lives from module insertion until module removal, so it does   * not need additional reference counting. The structure is protected by the   * mutex 'mutex'.   */   struct  logger_log {       unsigned char *      buffer/* the ring buffer itself */       struct miscdevice    misc;    /* misc device representing the log */       wait_queue_head_t    wq/* wait queue for readers */       struct list_head      readers/* this log's readers */       struct mutex         mutex /* mutex protecting buffer */       size_t           w_off;   /* current write head offset */       size_t           head;    /* new readers start here */       size_t           size;    /* size of the log */   };      /*   * struct logger_reader - a logging device open for reading   *   * This object lives from open to release, so we don't need additional   * reference counting. The structure is protected by log->mutex.   */   struct  logger_reader {       struct logger_log *  log;     /* associated log */       struct list_head     list;    /* entry in logger_log's list */       size_t           r_off /* current read head offset */   };   /* logger_offset - returns index 'n' into the log via (optimized) modulus */   #define  logger_offset(n)    ((n) & (log->size - 1))  
结构体 logger_log 就是真正用来保存日志的地方了。 buffer 成员变量变是用保存日志信息的内存缓冲区,它的大小由 size 成员变量确定。从 misc 成员变量可以看出, logger驱动程序使用的设备属于misc类型的设备,通过在Android模拟器上执行cat /proc/devices命令,可以看出,misc类型设备的 主设备号是10 wq 成员变量是 一个等待队列,用于保存正在等待读取日志的进程 readers 成员变量用来保存当前正在读取日志的进程,正在读取日志的进程由结构体 logger_reader 来描述。 mutex 成员变量是一个互斥量,用来保护log的并发访问。可以看出, 这里的日志系统的读写问题,其实是一个生产者-消费者的问题,因此,需要互斥量来保护log的并发访问 。  w_off 成员变量 用来记录下一条日志应该从哪里开始写 head 成员变量用来表示打开日志文件中,应该从哪一个位置开始读取日志。     结构体 logger_reader 用来表示一个读取日志的进程, log 成员变量指向要读取的日志缓冲区。 list 成员变量用来连接其它读者进程。 r_off 成员变量 表示当前要读取的日志在缓冲区中的位置         logger_log 结构体中用于保存日志信息的内存缓冲区 buffer 是一个循环使用的环形缓冲区,缓冲区中保存的内容是以结构体 logger_entry 为单位的,每个单位的组成为: logger_entry + priority + tag + msg        由于是内存缓冲区buffer是一个循环使用的环形缓冲区,给定一个偏移值,它在buffer中的位置由下logger_offset来确定:         #define logger_offset(n)          ((n) & (log->size - 1))

更多相关文章

  1. Android平台开发指导(Android(安卓)Porting Guide)
  2. 命令行建avd
  3. android 使用Intent传递数据之全局变量传递
  4. android 使用Intent传递数据之全局变量传递
  5. Android(安卓)Studio安装教程
  6. android环境变量的设置及注意问题
  7. Android环境变量
  8. 如何配置android的adb环境变量
  9. Android(安卓)Handler机制2之ThreadLocal

随机推荐

  1. Android(安卓)查询字段
  2. Android中判断是否有声音在播放
  3. Android(安卓)startActivityForResult的
  4. Android(安卓)XML使用
  5. Android(安卓)国际化,文本国际化,图片国
  6. android 获得焦点(View get focus)
  7. 【Android(安卓)系统开发】 Android(安卓
  8. 除去ScrollView拉到尽头时再拉的阴影效果
  9. Qt 5.7.0 (32 bit) 配置 Android(安卓)环
  10. Android(安卓)后台发邮件