一个轻量高效跨平台日志系统的设计与实现

2017-11-15 16:44杨善宁
电脑知识与技术 2017年28期
关键词:轻量跨平台高效

杨善宁

摘要:日志功能被广泛应用于各种软件开发领域,尤其是在嵌入式系统,然而提高效率、减少开销,一直是日志系统的所追求的目标和所面临的挑战。文中介绍了一个轻量高效、易于跨平台的日志系统的设计思路与实现要点,并通过基准对比测试,展示了其在效率和性能上的表现。

关键词:日志系统;嵌入式;轻量;高效;跨平台

中图分类号:TP311.5 文献标识码:A 文章编号:1009-3044(2017)28-0077-02

Abstract: Logging functionality is widely used in various software development areas, especially, the embedded system. Nevertheless, increasing efficiency and reducing overhead are always the goals that a logging system pursues and the challenges to what it faces as well. This paper represents the design thoughts and implementation techniques of a lightweight, high-efficient and cross-platform logging system, and illustrates the logging efficiency and performance through benchmark test.

Key words: logging system; embedded; lightweight; high-efficient; cross-platform

1 概述

规范与齐全的日志是衡量一个软件系统质量的重要指标,也是大型软件系统,尤其是嵌入式系统进行离线分析诊断问题的重要途径。目前,市场上存在着不少优秀的开源日志系统,例如,使用比较广泛的有Apache log4cxx,Google logging (Glog)等,但这类开源软件的框架通常过于庞大复杂,不便于团队统一规范使用,也不易于跨硬件平台进行移植;或因兼顾编程开发语言、系统平台等因素而引入一些额外的开销,从而导致在性能与效率上有所损失。

在整个软件系统中,日志系统本质上是起辅助性作用的,所以,应尽可能减少其系统开销,而提高其效率和吞吐量。尤其在嵌入式开发领域,日志系统的简洁高效性是一个极为重要的软件质量指标。除了这里提到的程序代码的简洁性与高性能的追求外,在嵌入式开发中,为了确保在不同系统平台上获得一致的日志操作体验,同时也便于一些基于日志的监测与测量分析系统的集成,还需要适当考虑跨平台的可移植性与可扩展性。

通过以上分析,并结合相关开源日志系统的实现机制的研究,去掉不必要的功能特性和避免一些不优化的实现方式,从简单易用性、效率和性能方面出发,设计并实现一套简洁易维护、高效率高性能的跨平台日志系统。

2 系统功能简介

设计与开发的日志系统称为Alog,主要以简单易用性、高效性、跨平台可移植性为核心目标,着重为嵌入式软件项目与开发团队提供有效统一的日志操作体验。Alog日志系统包括的主要功能特性有:

1) 根据标签、严重级别来分类写日志;

2) 日志输出到控制台、文件系统、Android logcat;

3) 使用配置文件來控制写日志的行为;

4) 提供丰富的宏定义以便于写入特定格式的日志用于监测与测量分析;

5) 支持x86、ARM、Android平台。

Alog使用C语言printf函数风格的日志函数设计,之所以选择这样的设计,而不是使用C++输入输出流风格或C#控制台输出样式,是因为考虑到目前在嵌入式软件项目中,软件大多是使用C/C++编写的,通过使用Alog提供的相关宏定义,方便快捷地替换原有日志函数调用,从而使Alog易用性和使用范围得到提高。

用户可通过配置文件来设定日志按标签、严重性来决定是否输出,以及输出到控制台或文件等。同时,Alog提供宏以控制输出为特定格式的日志,便于基于日志的脚本或软件进行监测与测量等用途。此外,在嵌入式软件开发中,ARM架构及linux、android系统是极为普遍的,因此,Alog优先提供这方面的跨平台支持。

3 系统设计

Alog的首要设计目标是精简轻量、高效高性能,去掉不实用的特性,保留最有价值的功能,从而使得逻辑简单清晰,不易出错,并且代码执行效率高,使得更适用于嵌入式系统的开发。

3.1 功能模块设计

Alog的功能模块主要包括API接口层、日志操作主控逻辑、配置文件解析和输出模块,其中输出模块按照日志输出目的地不同细分为终端屏幕、文件系统和Android logcat。如下图1简要描述了Alog的功能模块组成。

API接口层主要负责屏蔽内部细节,给上层应用程序提供访问接口,有利于统一规范地使用日志系统,主要接口包括初始化、关闭日志系统、写日志、查看运行状况等,并以C语言宏定义的方式提供常规与特殊用途的日志功能。

Alog配置文件的解析与应用,使到用户可方便灵活地控制日志的行为:

1) 设置是否打印日志到控制台屏幕、文件、Android logcat;

2) 设置日志保存路径、文件名等;

3) 设置默认日志输出级别,也可设置特定标签、特定严重级别的日志输出等。

日志主控模块负责日志的操作行为,实现控制逻辑,格式化日志文本。根据日志中指定的标签,使用哈希的方法检索相应配置,快速确定日志的操作行为。endprint

日志輸出模块将格式化好的日志,输出到特定的目的地,如磁盘文件、屏幕控制台等。使用C++面向对象设计,以继承的方式实现基类声明的接口,这样可以更好的复用主控模块的控制逻辑,只需实现特定的输出逻辑即可。

3.2 接口设计

Alog使用C/C++编程语言进行开发,以得到良好的运行效率和性能,同时,以动态库与静态库两种形式对外提供接口,方便用户灵活使用。为了进一步屏蔽琐碎的细节,Alog提供C语言宏定义以供外部访问。其访问接口主要有两大类:一类是用于输出常规的日志,如输出特定标签及特定严重性级别的日志;一类是用于输出特定格式的日志,以便使用脚本或软件对日志进行扫描分析,进行实时监测与性能参数测量等。

4 系统实现

4.1 判断是否输出日志

Alog基于标签与严重级别来输出日志,实现过程中,使用C++标准库的std::map来关联标签与相应的日志操作行为设置,这样也是为了能够在运行时动态添加标签配置项。C++标准库的std::map内部实现使用的是哈希算法,其查找、插入操作的复杂度均为O(n),具备理想的运行时效。首先,由配置文件解析模块在程序开始运行时,解析并应用Alog配置,即初始化特定标签的输出日志的级别。然后,在运行时,根据标签名在该std::map中查找,如果不存在相应的配置项,则插入默认级别的配置项,否则,使用查找到的配置项。最后,比较标签所配置的输出级别与日志请求的级别,决定是否输出日志,具体流程如下图2所示。

4.2 格式化日志文本

Alog的日志由消息头与消息体两部分组成。消息头的格式是固定的,其包含的字段依次是:日期时间,严重级别,标签名,文件名,代码行号。消息体为用户指定要输出的日志消息内容。此外,Alog为支持基于日志进行监测与测量,提供稍微特别的日志格式,其消息头与普通日志相同,仅在消息体前面,使用固定格式的花括弧号,将用户指定的日志数据包装起来。借助于一些脚本或软件,用户可以方便地将这些数据进行绘图并加以展示,然后进行直观地分析与评测,从而了解系统的运行状况和变化趋势。

为提高效率,Alog在格式化日志消息时,代码实现上,使用栈存储空间,而不是从系统堆中动态分配内存。很多日志系统使用从堆上动态分配内存的策略,如Glog就是这样实现的。虽然,从堆上分配存储可以让用户输出任意长度的日志,但它的效率比不上从栈空间直接分配,而且,系统的日志通常不会太长。相比之下,Alog采用的策略一是从程序栈上分配存储空间;二是限制日志长度为256字节,这通常已经足够使用,如果不够,用户可以写两条日志,而这是极少发生的情况。

4.3 输出日志

Alog在输出日志时,根据配置文件来决定日志输出的目的地,支持输出到屏幕控制台、文件、Android logcat。实现时,使用C++继承与多态特性,在父类中实现公共可复用的代码逻辑,而子类仅需实现各自特有的部分,并提供必要的接口实现即可。对于屏幕控制台,使用标准错误stderr,这是因为stderr是不进行缓存处理的,可以将日志直接输出到屏幕以确保正确的顺序;对于输出到日志文件,具体实现时,使用POSIX兼容的标准文件读写接口将日志写入磁盘;对于Android平台,调用其提供的日志辅助函数,将日志输出到Android logcat。如下图3简要说明日志输出的类设计。

5 性能对比

日志系统本身不是业务的重点,因此,应该以更少的代价来实现更多的价值,即提供便利而不会带来过多的系统开销。无论在设计上还是在实现中,Alog始终以简洁与高效,并具备必要的跨平台特性为目标,保持简单清晰的功能逻辑,运用高效的技术实现细节,从而成为更适合嵌入式开发的日志系统。

为测试Alog的性能,将Google的开源日志系统Glog与Alog进行对比测试。测试环境使用操作系统为linux 3.18,CPU为Qualcomm Snapdragon 820,内存为2GB的DDR3,外部存储为32GB的Flash。测试用例为使用Glog与Alog分别写入1000000条特定长度的日志到文件,然后统计写入每种长度的日志所花费的时间。如下图4,展示了Glog与Alog性能对比情况:

6 结束语

通过在功能上进行精简设计,以及在性能上进行优化实现,开发出一个轻量而高效,易于跨平台的日志系统,能够被广泛地应用到各领域的软件开发,尤其是嵌入式软件系统的开发。

参考文献:

[1] 李英军.设计模式: 可复用面向对象软件的基础[M].北京: 机械工业出版社,2000:84-88.

[2] 侯捷. C++标准库[M].2版.北京: 电子工业出版社,2015.

[3] 黄艺海,胡君.日志审计系统设计与实现[J].计算机工程,2006,33(22):67-68.

[4] 刘思尧,李斌.基于ELK 的电力信息监控日志审计系统实现[J].电脑知识与技术,2016, 12(30):61-64.

[5] 孙李斌,赵明明. 基于Linux的嵌入式日志系统设计与实现[J].电子科学技术, 2017, 4 (3):97-99.

[6] google/glog. Github[EB/OL]. https://github.com/google/glog.endprint

猜你喜欢
轻量跨平台高效
并继竿之我见(四)
——轻量竿只有新手才用?
轻量新能源汽车应用开关磁阻电机系统匹配的研究
跨平台APEX接口组件的设计与实现
我对轻量型并继竿的看法
提高提问的有效性, 构筑高效的语文课堂
打造务实、创新、高效的语文课堂
基于QT的跨平台输电铁塔监控终端软件设计与实现
基于OPC跨平台通信的电机监测与诊断系统
基于B/S的跨平台用户界面可配置算法研究
降低车用发动机燃油耗的高强度轻量气门弹簧