你的日志打印对了么?

一、前言

日志不仅记录了程序的执行过程,同时也是分析问题的一种重要手段。

对于神策分析 iOS SDK 而言,通过日志系统不但可以了解到 SDK 的行为,而且便于我们排查问题。因此,日志系统是 SDK 中必不可少的一项功能。

下面针对神策分析 iOS SDK 日志系统进行解析,希望能够给大家提供一些参考。

二、日志打印方式

对于 iOS 开发而言,在控制台打印日志的常用方式有 NSLog 和 printf,我们先来看一下两者的区别。

2.1NSLog

NSLog 是 Foundation 框架提供的日志输出函数,可以在控制台进行格式化输出。

日志的内容会自动包含一些系统信息,例如:项目名称、时间等。另外,NSLog 还可以打印 OC 中的对象,并且输出的内容会自动换行。示例代码如下:

image.png

2.2. printf

printf 只能打印 char* 类型,并且内容不会自动换行,需要我们手动操作[1]。示例代码如下:


image.png

2.3. 小结

通过前面的介绍我们不难看出,在 iOS 平台上通过 NSLog 输出日志更有优势。既然如此,神策为什么不选用 NSLog 来进行日志输出呢?主要原因如下:
1、NSLog 只有简单的控制台打印输出,没有其他的输出方式;
2、NSLog 打印格式相对单一,不够灵活,又无法自定义和扩展;
3、NSLog 打印效率不高,而且有长度限制;
4、如果客户重写了 NSLog,那么日志可能无法打印到控制台,影响问题定位。

为了解决上述问题,神策开发了自己的日志系统(SALog)来进行日志输出。

3. SALog 的实现

SALog 是一个日志系统,具有较好的扩展性和易用性,下面我们来看下 SALog 具体是如何实现的。

3.1. 原理简介

目前 SALog 中最重要的功能就是在控制台输出日志(通过子类 SAConsoleLogger 实现),SAConsoleLogger 的主要原理是:实例化一个 iovec 结构体来容纳数据,然后通过 writev 函数来发送这些数据。
结构体 iovec 包含了 iov_base 和 iov_len 两个属性[2],它们的含义如下:
1、 iov_base 属性指向一个缓冲区,存放将要发送的数据;
2、 iov_len 属性记录了输出日志的长度。
核心代码如下所示:


image.png

3.2. 整体设计

SALog 是一个日志系统,既可以用于控制台日志的打印也可以输出到本地文件。这样的日志系统有一套核心的设计标准:创建一个基类实现基本的逻辑,具体的模块通过继承基类并重写基类的方法实现功能。
这样的设计具有较好的扩展性与维护性,整体的 UML 如图 3-1 所示:

image.png

图 3-1 日志系统的 UML 图

通过上图可以看到神策定义了 SALogger 协议,在基类 SAAbstractLogger 中实现了基本的逻辑。SAFileLogger(文件日志)、SAConsoleLogger(控制台日志)等日志模块都是通过继承 SAAbstractLogger 这个基类,在 - logMessage: 方法中实现各自的功能逻辑。核心代码如下所示:


image.png

3.3. 日志格式

神策定义了 SALogMessageFormatter 协议,基于此协议可实现多种不同的 formatter,便于后期的维护和扩展。例如:SALoggerConsoleFormatter、SALoggerPrePostFixFormatter 等,可以标注不同颜色、前后缀、特定标识等。核心代码如下所示:

//SALoggerConsoleFormatter.m

  • (NSString *)formattedLogMessage:(nonnull SALogMessage *)logMessage {
    NSString *prefixEmoji = @"";
    NSString *levelString = @"";
    switch (logMessage.level) {
    case SALogLevelError:
    prefixEmoji = @"❌";
    levelString = @"Error";
    break;
    ······
    default:
    break;
    }

    ······
    return [NSString stringWithFormat:@"%@ %@ %@ %@ %@ %@ line:%@ %@\n", dateString, prefixEmoji, levelString, self.prefix, logMessage.fileName, logMessage.function, line, logMessage.message];

3.4. 长度限制

不同开发者的代码习惯是不同的,业务逻辑也是不同的,这就导致 SDK 采集的数据大小都是不确定的。如果开发人员想要查看采集的数据是否正确,就需要保证输出的日志信息是完整的。为了保证采集的数据都能完整打印,SALog 将低于 1024 * 4 Bytes 的日志数据存储在栈区,超过 1024 * 4 Bytes 的日志数据存储在堆区,以保证打印的完整性。核心代码如下所示:


image.png

3.5. 日志分级

为了方便开发人员查看和筛选日志,SDK 通过设置枚举类型对日志等级进行划分,从高到低依次为 Error、Warn、Info、Debug、Verbose,如下所示:


image.png

另外,为了便于使用,SALog 通过宏定义的方式实现了不同等级的日志接口:


image.png

4. SALog 的使用

SALog 的接口设计十分友好,使用起来也比较方便。只需要在初始化 SDK 时,打开日志输出功能即可:


image.png

然后在 Xcode 控制台中可筛选关键字进行查看:
1、 埋点事件触发成功时,SDK 会输出【track event】字段开头的事件数据;
2、 埋点事件触发失败时,SDK 会输出相应的错误原因;
3、 事件数据上报成功时,SDK 会输出【valid message】字段开头的事件数据;
4、 事件数据上报失败时,SDK 会输出【invalid message】字段开头的事件数据并输出错误原因。

通常情况下,我们只希望在 DEBUG 模式下输出日志。此时,可以通过宏定义来解决此问题:


image.png

如上配置后,SDK 只会在 DEBUG 模式下输出日志,这样避免了线上应用因忘记关掉日志输出功能而产生的性能影响。

5. 展望未来

通过 SALog 可以在控制台上输出各种各样的日志信息,给我们排查线上问题带来了极大的便利。不过,SALog 并非完美的,还有一些改进的空间。

在实际使用的过程中,我们收集了一些关于 SALog 的痛点:
1、 当前没有对输出日志的级别进行控制,导致在开启日志的情况下,会将所有级别的日志进行输出;
2、 无法对于日志内容进行筛选;
3、目前只支持输出日志到控制台。

针对这些痛点,我们也给出了相应的解决方案:
1、 在 SDK 的配置项中增加字段,用于控制输出日志的级别;
2、 针对日志内容增加模糊匹配的功能,实现对于日志内容的筛选;
3、 增加日志输出的渠道,例如:文件系统、云端等。
目前,这些功能已经在逐步研发中,不久之后大家就可以体验这些功能。

6. 总结

本文主要介绍了神策分析 iOS SDK 日志系统的实现和使用,并对日志系统的未来进行了规划。希望通过这篇文章,大家能够对日志系统的实现和使用有更深入的了解。

7. 参考文献

[1] https://www.cplusplus.com/reference/cstdio/printf/

[2] https://linux.die.net/man/2/writev

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容