Page 479 - 《软件学报》2024年第4期
P. 479

吴圣垚 等: HiLog: OpenHarmony  的高性能日志系统                                             2057


                 题排查的指导, 也可以在程序运行时进行证据留痕, 还可以对丢失的数据进行恢复                          [19] , 是当前计算机系统不可或
                 缺的基础能力之一. 随着计算机软硬件的高速发展, 操作系统中的信息产生速度快速增长                            [20,21] , 为了实现操作系统
                                                                                                       [1]
                 信息的有效捕获, 构建一个用于日志收集、排序、分类、保存、查看的系统十分必要. 因此, 日志系统就应运而生 .
                    日志系统不但需要尽可能详细地记录计算机的每一条日志, 还需要为开发者提供便捷的查询服务. 随着计算
                 机系统内程序的数量增多, 日志系统记录的日志逐步增多, 日志的写入速率愈发快速                           [20] , 远远超出人工分析的范
                 围. 因此, 对日志系统的功能提出了更多的要求, 如, 能够对日志进行分类、分级筛查, 关键字检索等.
                  1.2   主流日志系统
                    目前业界已存在多种日志系统, 例如            Android  日志系统、Fuchsia 日志系统、FTrace、NanoLog、Log4j2     等,
                 这些日志系统为操作系统和软件提供了不可或缺的日志能力, 提升了开发和维护的效率.
                  1.2.1    Android  日志系统
                    Android 5.0  之前版本的日志系统采用简单可靠的架构, 如图            1  所示, 其中, ① 代表日志写入过程, ② 代表日志
                 读取  (打印) 过程, ③ 代表日志持久化过程. 日志的处理与暂存需要依靠                 Linux Kernel 的  logger 模块, 其中, 不论是
                 应用程序日志、系统日志还是内核日志, 都统一存储于位于内核的                       ringbuffer 中. 写日志接口采用   Linux  原生的
                 ioctl (input/output control) 机制实现用户态向内核态传参  [22] , 读日志接口  logcat 实质是对  logger 命令的封装实现.
                 采用这种架构的优势在于内存           Copy  次数少; 但缺点也很明显, ioctl 机制需要解析命令行才能跳转到对应处理函
                 数, 会增加日志接口延时和        CPU  负载  [23] . 此外, 这种架构对  Linux  内核的耦合极强, 不能脱离    Linux  内核运行, 也
                 必须跟随   Linux  版本进行迭代.

                                           UserSpace Process A
                                                            ①          logcat
                                                                 ②
                                                   Process B
                                                             logger
                                           KernelSpace
                                                           kernel buffer  ③
                                                        Main System  …
                                           Hardware
                                                                       Flash

                                             图 1 Android 5.0  之前版本的日志系统

                    Android  日志系统于  Android 5.0  版本后采用了新架构并一直沿用至今. 如图          2  所示, 其中, ①和②代表用户态
                 日志写入过程, ③和④代表日志读取           (打印) 过程, ⑤代表日志持久化过程, ⑥代表内核态日志的写入过程. 新日志
                 系统通过在用户态维护守护进程            logd  实现对应用日志、系统日志以及内核日志的自动化搜集与暂存. 在日志写
                 入方面, 每一用户态写日志进程与           logd  的进程间通信   (inter process communication, IPC) 采用  Linux  原生套接字
                 (Socket) 实现; 内核态日志通过扫描/proc/kmsg 文件抓取. 在日志输出方面, logcat 采用        Socket 收发的方式实现传输.

                                         UserSpace Process A  logd
                                                       ①    list_buffer  logcat
                                                Process B  ②  Main System  …  ③  ④
                                                               ⑥
                                           KernelSpace
                                                          kernel buffer
                                                                          ⑤
                                                          socket buffer
                                          Hardware
                                                                        Flash
                                 图 2 Android 5.0  及以后版本的日志系统架构       (Android version ≥ 5.0.0)

                    新版  Android  日志系统相比旧版本最大的优势在于能够一定程度上与                  Linux  内核解耦, 同时在用户态维护缓
                 冲区所需的权限较低, 更为安全. 但是          Android  日志系统没有对日志资源的使用进行合理分配或约束, 因此写日志
   474   475   476   477   478   479   480   481   482   483   484