第7期博客(查违章日志系统的接入NSLogger)

查违章日志系统的接入NSLogger

NSLogger是一款强力的日志记录和分析工具,其强大的功能,可以完全替代Xcode自带的Debugger,本文将介绍一些其主要特点和用法以及接入查违章的思路。github地址.

安装

  • Step 1. 在Mac上下载并安装NSLogger desktop viewer.
  • Step 2. 将NSLogger framework添加到工程中.
  • Step 3. There is no step 3…

效果



配置

NSLogger支持TCP和Bonjour两种方式连接终端设备,Bonjour连接一般不需要配置,如果要是使用TCP连接,要通过LoggerSetViewerHost()配置IP地址和端口(同时需配置NSLoggerViewer,在Preferences的Network中,勾选 “Listen for loggers on TCP port”打开监听):

1
LoggerSetViewerHost(NULL, (__bridge CFStringRef)@"192.168.11.38", (UInt32)50000);

使用

1
#import "NSLogger.h"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifdef DEBUG
#define NSLog(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"NSLog", 0, __VA_ARGS__)
#define LoggerError(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Error", level, __VA_ARGS__)
#define LoggerApp(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"App", level, __VA_ARGS__)
#define LoggerView(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"View", level, __VA_ARGS__)
#define LoggerService(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Service", level, __VA_ARGS__)
#define LoggerModel(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Model", level, __VA_ARGS__)
#define LoggerData(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Data", level, __VA_ARGS__)
#define LoggerNetwork(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Network", level, __VA_ARGS__)
#define LoggerLocation(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Location", level, __VA_ARGS__)
#define LoggerPush(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Push", level, __VA_ARGS__)
#define LoggerFile(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"File", level, __VA_ARGS__)
#define LoggerSharing(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Sharing", level, __VA_ARGS__)
#define LoggerAd(level, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Ad and Stat", level, __VA_ARGS__)
#else
#define NSLog(...) LogMessageCompat(__VA_ARGS__)
#define LoggerError(...) while(0) {}
#define LoggerApp(level, ...) while(0) {}
#define LoggerView(...) while(0) {}
#define LoggerService(...) while(0) {}
#define LoggerModel(...) while(0) {}
#define LoggerData(...) while(0) {}
#define LoggerNetwork(...) while(0) {}
#define LoggerLocation(...) while(0) {}
#define LoggerPush(...) while(0) {}
#define LoggerFile(...) while(0) {}
#define LoggerSharing(...) while(0) {}
#define LoggerAd(...) while(0) {}
#endif

##特点

  • 标签输出
  • 自定义优先级
  • 直接输出图片
  • 多线程标记
  • 时序控制
  • 远程记录

##查违章是如何接入的

1.该日志直接接入已有的BPLogger中,对比NSLogger.h中提供的宏定义,我们可以有符合我们项目的宏定义,对于Release下不输出日志,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifdef DEBUG
#define BPLog(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Normol Log", 0, __VA_ARGS__)
#define BPLoggerNetwork(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"NetWork Log", 0, __VA_ARGS__)
#define BPLoggerAd(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"AD Log", 0, __VA_ARGS__)
#define BPLoggerEvent(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Event Log", 0, __VA_ARGS__)
#define BPLoggerCache(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cache Log", 0, __VA_ARGS__)
#define BPLoggerSkipping(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Skipping Log", 0, __VA_ARGS__)
#define BPLoggerCWZSDK(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cwzsdk Dispatch Log", 0, __VA_ARGS__)
#define BPLoggerCustom(CustomStr,...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, CustomStr, 0, __VA_ARGS__)
#else
#define BPLog(...) while(0) {}
#define BPLoggerNetwork(...) while(0) {}
#define BPLoggerAd(level, ...) while(0) {}
#define BPLoggerEvent(...) while(0) {}
#define BPLoggerCache(...) while(0) {}
#define BPLoggerSkipping(...) while(0) {}
#define BPLoggerCWZSDK(...) while(0) {}
#define BPLoggerCustom(CustomStr,...) while(0) {}
#endif

2.由于日志系统可能会嵌入查违章的主工程和很多基础库中,比如CLAdsSDK,CLSafeKit,BPCommon等,正常的使用就是在最基础库中依赖NSLogger,但是这样会使项目对该工具的使用和剥离增加更多的人为操作,这并不是最好的解决方法,我们期望的是所有的基础库都不依赖NSLogger,如果需要这个功能,在主工程的podfile中pod ‘NSLogger’就行,就像一个”插件”那样,可以随意加入工程,也可以随时拿走,所以对BPLogger.h进行改造,比如这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#if MainProjectMarco(一个在主工程的宏定义)
#import "LoggerClient.h"
#endif
#if MainProjectMarco(一个在主工程的宏定义)
#ifdef DEBUG
#define BPLog(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Normol Log", 0, __VA_ARGS__)
#define BPLoggerNetwork(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"NetWork Log", 0, __VA_ARGS__)
#define BPLoggerAd(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"AD Log", 0, __VA_ARGS__)
#define BPLoggerEvent(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Event Log", 0, __VA_ARGS__)
#define BPLoggerCache(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cache Log", 0, __VA_ARGS__)
#define BPLoggerSkipping(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Skipping Log", 0, __VA_ARGS__)
#define BPLoggerCWZSDK(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cwzsdk Dispatch Log", 0, __VA_ARGS__)
#define BPLoggerCustom(CustomStr,...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, CustomStr, 0, __VA_ARGS__)
#else
#define BPLog(...) while(0) {}
#define BPLoggerNetwork(...) while(0) {}
#define BPLoggerAd(level, ...) while(0) {}
#define BPLoggerEvent(...) while(0) {}
#define BPLoggerCache(...) while(0) {}
#define BPLoggerSkipping(...) while(0) {}
#define BPLoggerCWZSDK(...) while(0) {}
#define BPLoggerCustom(CustomStr,...) while(0) {}
#endif
#else
#ifdef DEBUG
#define BPLog(...) NSLog(__VA_ARGS__)
#define BPLoggerNetwork(...) NSLog(__VA_ARGS__)
#define BPLoggerAd(...) NSLog(__VA_ARGS__)
#define BPLoggerEvent(...) NSLog(__VA_ARGS__)
#define BPLoggerCache(...) NSLog(__VA_ARGS__)
#define BPLoggerSkipping(...) NSLog(__VA_ARGS__)
#define BPLoggerCWZSDK(...) NSLog(__VA_ARGS__)
#define BPLoggerCustom(CustomStr,...) NSLog(__VA_ARGS__)
#else
#define BPLog(...) while(0) {}
#define BPLoggerNetwork(...) while(0) {}
#define BPLoggerAd(level, ...) while(0) {}
#define BPLoggerEvent(...) while(0) {}
#define BPLoggerCache(...) while(0) {}
#define BPLoggerSkipping(...) while(0) {}
#define BPLoggerCWZSDK(...) while(0) {}
#define BPLoggerCustom(CustomStr,...) while(0) {}
#endif
#endif

3.尽管如此,我们还是依赖主工程需要提供的宏定义,离”插件”的定义还差最后一步,我们要想办法把这个宏定义也去掉,比如这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#if __has_include(<NSLogger/LoggerClient.h>)
#import "LoggerClient.h"
#endif
#if __has_include(<NSLogger/LoggerClient.h>)
#ifdef DEBUG
#define BPLog(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Normol Log", 0, __VA_ARGS__)
#define BPLoggerNetwork(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"NetWork Log", 0, __VA_ARGS__)
#define BPLoggerAd(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"AD Log", 0, __VA_ARGS__)
#define BPLoggerEvent(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Event Log", 0, __VA_ARGS__)
#define BPLoggerCache(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cache Log", 0, __VA_ARGS__)
#define BPLoggerSkipping(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Skipping Log", 0, __VA_ARGS__)
#define BPLoggerCWZSDK(...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"Cwzsdk Dispatch Log", 0, __VA_ARGS__)
#define BPLoggerCustom(CustomStr,...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, CustomStr, 0, __VA_ARGS__)
#else
#define BPLog(...) while(0) {}
#define BPLoggerNetwork(...) while(0) {}
#define BPLoggerAd(level, ...) while(0) {}
#define BPLoggerEvent(...) while(0) {}
#define BPLoggerCache(...) while(0) {}
#define BPLoggerSkipping(...) while(0) {}
#define BPLoggerCWZSDK(...) while(0) {}
#define BPLoggerCustom(CustomStr,...) while(0) {}
#endif
#else
#ifdef DEBUG
#define BPLog(...) NSLog(__VA_ARGS__)
#define BPLoggerNetwork(...) NSLog(__VA_ARGS__)
#define BPLoggerAd(...) NSLog(__VA_ARGS__)
#define BPLoggerEvent(...) NSLog(__VA_ARGS__)
#define BPLoggerCache(...) NSLog(__VA_ARGS__)
#define BPLoggerSkipping(...) NSLog(__VA_ARGS__)
#define BPLoggerCWZSDK(...) NSLog(__VA_ARGS__)
#define BPLoggerCustom(CustomStr,...) NSLog(__VA_ARGS__)
#else
#define BPLog(...) while(0) {}
#define BPLoggerNetwork(...) while(0) {}
#define BPLoggerAd(level, ...) while(0) {}
#define BPLoggerEvent(...) while(0) {}
#define BPLoggerCache(...) while(0) {}
#define BPLoggerSkipping(...) while(0) {}
#define BPLoggerCWZSDK(...) while(0) {}
#define BPLoggerCustom(CustomStr,...) while(0) {}
#endif
#endif

这里面有个关键的宏定义:

1
#if __has_include()

此宏传入一个你想引入文件的名称作为参数,如果该文件能够被引入则返回1,否则返回0。

现在我们的所有基础库都不依赖NSLogger,只要主工程podfile中有NSLogger,那么这个工具就能工作,如果没有,就是普通的NSLog

基于上面接入查违章的过程,#if __has_include()这个方式是否可以进行延展使用

比如CLSafeKit/Log是不是可以以”插件”的形式接入查违章,而不是直接依赖在BPCommon中。