最近由于个人所负责的模块的不确定性,需要预埋大量的日志以便更精准地分析和定位问题、同时升级项目中原有的日志系统的需求又刚好提上了日程,于是通过和同事的几天调研,最终将公司App的日志系统替换为了微信开源的Mars-xlog组件,关于xlog的优势和使用方式可直接参见其官方Github,这里仅记录拿到收集的日志文件后,如何提升对日志的分析的效率的小技巧。

参考Android Studio的Logcat,结合xlog文件的特性,以最省心和高效的方式来看,可优化的方面包括:自动化解压和打开、语法高亮两方面。

自动化解压和打开(open-build)

xlog在异步模式下会自动开启内容压缩,若直接打开,看到的将全是16进制的数字,所以微信提供了脚本decode_mars_log_file.py来解压,我们所需要做的首先是打开终端,cd到对应的路径,执行python decode_mars_log_file.py xxx.xlog命令以生成最终的xxx.xlog.log文件,然后再打开文件……,作为开发,怎能忍受这么麻烦的操作存在,这里就需要抡起sublime了。

小技巧:.log的文件默认是以“控制台”程序打开,可以通过“右键 - 显示简介 - 打开方式 - 选择‘sublime’ - 全部更改”的方法修改默认配置。

总所周知,sublime可以编辑和编译大部分主流的编程语言文件(js、java、php……),这得益于其强大的构建系统(build system)的自定义,因此这里利用该方案来“build”我们的xlog文件。打开sublime,选择 工具栏 - tool - Build System - New Build System来为xlog文件配置构建方案。在弹出的新文件编辑窗口中填写以下内容即可:

1
2
3
4
5
{
"cmd": ["$packages/User/decode_mars_log_file.py", "$file"],
"selector": "source.xlog"
}


然后保存为例如SampleXlog.sublime-build

关于如何编写这些配置,具体可以参考sublime官方文档-Build System章节【译】

由于sublime本身对python的支持,所以我们可以直接指定相应的参数。

  • 其中cmd的值的第一个元素表示前面提到的用于解压缩的脚本的路径,$packages变量表示sublime本地的Packages路径,因此这里第二个步骤就是将decode_mars_log_file.py文件copy到上述路径下;
  • 第二个元素变量表示当前文件,如果当前窗口是打开的xlog文件,$file就表示它。
    另外还有个selector,我们稍后再解释。

完成上述步骤后如果我们直接选中SampleXlog并点击Build,我们会发现在本地文件系统打开的xlog文件旁边生成了解压缩后的文件xxx.xlog.log,但是……这并没有什么*用,讲了大半天就给看这个?

其实很容易就可以给出解决方案:只要将其解压后的内容的存放位置从原来生成的新文件修改为源文件本身,就可以实现“open-build”,对于解压前的内容,我们本身就不关心。因此,打开decode_mars_log_file.py文件,修改其main方法,将传入ParseFile的第二个参数修改为第一个参数一样的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def main(args):
global lastseq
if 1==len(args):
if os.path.isdir(args[0]):
filelist = glob.glob(args[0] + "/*.xlog")
for filepath in filelist:
lastseq = 0
ParseFile(filepath, filepath)
else: ParseFile(args[0], args[0]) #这里
elif 2==len(args):
ParseFile(args[0], args[1]) #这里手动指定了存放文件,就不修改了 (虽然并不会走到这里)
else:
filelist = glob.glob("*.xlog")
for filepath in filelist:
lastseq = 0
ParseFile(filepath, filepath) #这里(虽然并不会走到这里)

到这里,我们再重试手动Build,解压的内容便成功地覆盖了先前那不知所云的内容。但是密密麻麻的一大片白色字符,眼睛开始痛了起来。在logcat中的红黄蓝绿等所标识的VIDWEF等级显得多么的美丽。

语法高亮

不用刻意注意就知道sublime在打开的例如js、Java等文件时,会自动对相关关键字、方法变量等进行颜色区分,或者直接说语法高亮,其中的原因便是sublime内置了对这些语言的高亮配置方案,因此我们还是可以以为xlog配置build方案的模式来同样为xlog配置“语法高亮”方案。

在sublime中,每种语法的高亮配置是以xml格式的内容组成,而为了更方便的制作高亮配置,已经有前人提供了相应方案,例如sublime的PackageDev插件,以更直观的方式进行编辑。安装好之后,点击“工具栏 - tool - Packages - Package Development - Syntax Definition”来为xlog文件指定高亮方案。如下所示:

1
2
3
4
5
6
7
8
9
# [PackageDev] target_format: plist, ext: tmLanguage
---
name: Codoon Xlog
scopeName: source.xlog
fileTypes: ["xlog", "xlog.log"]
uuid: af21ab18-b1b3-4929-8999-2654833418f4

patterns:
...

  • name:表示该方案的名称,随意;
  • scopeName:这个字段很重要了,可以将其理解为一套“语法方案”,注意将其与下面的fileTypes区分开来,还记得前面在为xlog配置build方案时忽略了一个selector属性吗,这下应该明白了,也就是说,如果发现该文件内容是xlog“语法方案”,那么就sublime就会自动将其build方案指定为SampleXlog
  • fileTypes:大概跟文件类型通配符类似,这里指定了只要文件名是以xlog、xlog.log形式结尾的,都将适用于本方案;
  • uuid:自动生成,勿删除;

接下来最重要的就是这个patterns了,如需详细了解,请自行参考官方文档,可以以一句大白话概括:用正则匹配语句并指定高亮模式,每一种高亮模式在不同的主题中都有对应的颜色,具体颜色可以访问自定义sublime主题颜色-Sublime Color Editor网站。那么有了这些基础了解,xlog的高亮方案也就可以很简单的匹配出来了:

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
patterns:
- comment: others
name: comment
match: (\^|d|g|M|l).*

- comment: verbose
name: variable
match: (\[V])(\[.*?])(\[.*?])(\[.*?])(\[.*?])(\[.*)
captures:
'1': {name: comment}
'2': {name: comment}
'3': {name: comment}
'4': {name: string}
'5': {name: constant.numeric}

- comment: debug
name: support.function
match: (\[D])(\[.*?])(\[.*?])(\[.*?])(\[.*?])(\[.*)
captures:
'1': {name: comment}
'2': {name: comment}
'3': {name: comment}
'4': {name: string}
'5': {name: constant.numeric}

- comment: info
name: entity.name.function
match: (\[I])(\[.*?])(\[.*?])(\[.*?])(\[.*?])(\[.*)
captures:
'1': {name: comment}
'2': {name: comment}
'3': {name: comment}
'4': {name: string}
'5': {name: constant.numeric}

- comment: warn
name: variable.parameter
match: (\[W])(\[.*?])(\[.*?])(\[.*?])(\[.*?])(\[.*)
captures:
'1': {name: comment}
'2': {name: comment}
'3': {name: comment}
'4': {name: string}
'5': {name: constant.numeric}

- comment: error
name: keyword.other
match: (\[E])(\[.*?])(\[.*?])(\[.*?])(\[.*?])(\[.*)
captures:
'1': {name: comment}
'2': {name: comment}
'3': {name: comment}
'4': {name: string}
'5': {name: constant.numeric}

其中

  • comment相当于注释;
  • name表示该套模式的名字;
  • match该套模式的正则表达式,入门正则,可以看看这一篇
  • captures是可选的,是对match粒度的进一步细分;

保存后,还需要执行build将这种编写方式转化为sublime的格式,最后大功告成,看看效果:image

其它

虽然sublime自带强大的搜索/过滤,但以用途和方便而言,这里还是推荐一下Filter Lines插件,可以更好地帮助日志的粗分,最重要的是可以以为单位进行过滤。

最后

最后来总结一下,本文方案其实就是利用sublime的特性,通过将xlog文件当作一种“语言”的方式来为其配置自定义的“语法高亮”规则和“编译”规则,实现了xlog文件的快速解压和查看,极大的提升了日志分析的效率;使用方式也非常方便,直接双击xlog在sublime中打开,然后快捷键F7或command+B执行加压缩,便得到了形如logcat的日志内容。

另外,需要说明的有两点:

  1. 本文所使用的xlog未修改源码,其余压缩方案、加密解密、自定义格式化等修改请自行参考;
  2. 本文所涉及的路径描述、生产环境均基于mac,其它系统请自行参考。