iOS崩溃日志符号化及NLP聚类实现
在解决iOS应用线上崩溃时,我们通常要分析崩溃日志来定位原因。线上崩溃日志一般是未符号或部分符号化的日志,是一堆十六进制的内存地址集合,可读性比较差,这对解决问题几乎没有帮助。所以,我们首先需要先对崩溃日志进行符号化——根据App出错的函数内存地址,在.dSYM文件中找到具体的文件名、函数名和行号信息。有了上述信息,我们就可以定位分析具体的崩溃原因了。
如果存在大量的崩溃日志,光符号化崩溃日志是远远不够的,我们不可能一条一条去分析大量崩溃日志,这时候就需要对符号化的崩溃日志进行聚类了。通过聚类,将相同或相近的一类崩溃归类在一起,进行统计分析,这在实际问题解决中具有重要的意义。本文将介绍基于NLP的崩溃日志聚类的实现。
本文提纲如下:
1. 崩溃符号化
1.1 崩溃日志结构
线上崩溃日志结构大致如下图所示。我们需要关心的信息主要是标注为红色的部分,具体说明详见表格的描述。
日志段 | 字段 | 意义 |
头部信息 | Identifier | 应用的bundle ID |
Version | 应用版本号 | |
Code Type | 设备CPU类型,例如ARM-64 | |
Date/Time | 崩溃时间 | |
OS Version | 崩溃设备及系统版本 | |
异常信息 | Exception Type | 崩溃类型 |
Exception Codes | 崩溃代码 | |
Crashed Thread | 崩溃线程号,根据线程号定位到具体的崩溃栈信息 | |
崩溃栈 | Thread xx: | 线程信息 |
Thread xx Crashed | 实际崩溃线程栈信息,也是符号化的关键信息 | |
崩溃线程状态 | Thread xx crashed with ARM-64 Thread State | 崩溃线程状态信息 |
Binary Images | yourAppProjectName | 你的工程名称 |
<xxxxxxxxxxxxxxxx> | 崩溃日志对应的dsYM文件的uuid,日志和dsYM的uuid要一一对应才可以符号化 |
通过分析崩溃日志的格式,我们很容易获取到应用的bundle ID、版本号、CPU类型、崩溃时间、崩溃设备及系统版本、崩溃类型、崩溃线程号,崩溃线程栈信息、崩溃日志对应dsYM文件的uuid。了解这些基础信息,我们就可以进行符号化了。
1.2 符号化方法
Xcode自带工具可以帮助我们来完成符号化的工作:symbolicatecrash、atos。
1.2.1 symbolicatecrash
symbolicatecrash
是一个将堆栈地址符号化的脚本,执行symbolicatecrash命令,可以得到一个符号化之后的输出文件,查看这个文件可以看到崩溃的位置。
1)准备工作
准备3个文件,放在同一个文件夹下:
I. dSYM文件;
II. 崩溃日志文件(注意文件格式为.crash,如果是其他格式,如txt,先将文件后缀改为.crash);
III.symbolicatecrash(symbolicatecrash的位置可以通过下面的指令来查找)
find /Applications/Xcode.app -name symbolicatecrash -type f
会输出所有的路径,我们只需要随便拷贝一个脚本和dSYM、崩溃日志放在一起即可。
find: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/private/var/mobile: Permission denied
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/iOSSupport/Library/PrivateFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
2)执行命令
在终端分别输入下面的两条命令,会生成YourApp.log文件,在该文件中可以产看具体的崩溃位置。
export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
./symbolicatecrash YourApp.crash YourApp.app.dSYM > YourApp.log
1.2.2 atos
atos
命令的特点是可以对单行堆栈进行符号化操作,通过输入本地地址(load address)和崩溃内存地址(address to symbolicate)就可以符号化。
1)命令使用
atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate>
Binary Architecture:arm64、armv6、armv7armv7s, 根据应用的情况来写;
Path to dSYM file: dSYM文件的路径;
binary image name: 你工程的名字;
load address:基地址,如果我们的崩溃日志中没有这个信息,load address = address to symbolicate - offset;
address to symbolicate:当前方法的内存地址。
2)使用例子
参考图1.1的崩溃日志片段,我们通过顶部的崩溃信息找到崩溃线程的ID为23,然后查看线程号为23的崩溃栈信息,从圈红色部分找到本地地址和崩溃的内存地址。例如本地地址为:0x102104000,崩溃的内存地址:0x000000010338cee8。
执行指令即可符号化出崩溃日志。
atos -o yourProject.app.dSYM/Contents/Resources/DWARF/yourProjectName -arch arm64 -l 0x102104000 0x00000001032c60a4
1.2.3 符号化方法总结
symbolicatecrash:开发者不需要分析本地地址和崩溃内存地址,直接将整个崩溃文件符号化,指令会自动找到崩溃线程栈,并对崩溃关键信息进行符号化,操作简单
。
atos:需要开发者分析本地地址和崩溃内存地址才能进行符号化,优点是可以对
单行堆栈进行符号化。
在实际应用中,我们需要根据项目线上崩溃情况,灵活选择符号化的方法。例如在博主的项目中,下载的崩溃日志是已经格式化的csv崩溃日志,采用atos来符号化,便于批量操作,统计分析。
2.崩溃日志聚类
通过第1节内容,我们已经可以将线上大量的崩溃日志进行符号化了。实际项目中,光符号化崩溃日志远远不够的。面对大量的崩溃日志,我们不可能一条一条地去分析。因此,对符号化的崩溃日志进行分门别类,将相同或相近的一类崩溃归类在一起,统计分析每一类崩溃,在应用问题解决中十分有意义。本节将介绍基于NLP的崩溃日志聚类实现。
2.1 聚类流程
整个聚类过程分为崩溃日志输入、分词、特征提取、输出特征向量、计算相似度、聚类归并、输出统计结果七部分。
2.2 聚类实现
1)崩溃日志输入:就是批量输入符号化的崩溃日志,初始化每条崩溃版本号、标题、崩溃log、崩溃次数等。
2)分词:采用jieba分词库,对崩溃log进行分词。
3)特征提取:将分词后的字符串作为每条崩溃 log的特征。
def getWordList(s):cut = jieba.cut(s)list_word = (','.join(cut)).split(',')return list_word
4)生成特征向量:循环计算每两条日志的所有词、取并集、计算词频。
def getWordVector(list_word1, list_word2):# 列出所有的词,取并集key_word = list(set(list_word1 + list_word2))# 给定形状和类型的用0填充的矩阵存储向量word_vector1 = np.zeros(len(key_word))word_vector2 = np.zeros(len(key_word))# 计算词频# 依次确定向量的每个位置的值for i in range(len(key_word)):# 遍历key_word中每个词在句子中的出现次数for j in range(len(list_word1)):if key_word[i] == list_word1[j]:word_vector1[i] += 1for k in range(len(list_word2)):if key_word[i] == list_word2[k]:word_vector2[i] += 1return word_vector1, word_vector2
5)计算相似度:余弦距离是自然语言处理中用来计算两个句子的相似度的方法之一,在本文中,博主通过计算特征向量的余弦距离来判断两条日志的相似度。余弦距离越大,相似度越大。
def calcuCosDistance(vec1, vec2):dist = float(np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)))return dist
6)聚类归并:设定余弦距离阈值,当相似度大于等于余弦阈值时,则认为这两条日志是相似的,把它们归并在一起。余弦阈值选取多少,没有统一的标准,需要在项目中进行测试选择一个合适的值。
7)输出统计结果:遍历聚类归并全部崩溃日志之后,输出统计后的崩溃日志,例如保存到数据库或以csv格式输出。 下面是博主项目中输出的统计结果截图。
3.参考文章
1.Apple Developer Documentation
2.jieba:https://github.com/fxsjy/jieba
iOS崩溃日志符号化及NLP聚类实现相关推荐
- iOS崩溃日志符号化 UUID获取
1. 符号表是什么? 符号表就是指在Xcode项目编译后,在编译生成的二进制文件.app的同级目录下生成的同名的.dSYM文件. .dSYM文件其实是一个目录,在子目录中包含了一个16进制的保存函数地 ...
- iOS 崩溃日志在线符号化实践
1. 什么是符号化? 在日常开发中,应用难免会发生崩溃.通常,我们直接从用户导出来的崩溃日志都是未符号化或者部分符号化的,都是一堆十六进制内存地址的集合,可读性较差.未符号化或者部分符号化的崩溃日志对 ...
- iOS崩溃日志分析-b
1名词解释 1.1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID,目的是为了唯一识别这个文件. 1.2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查 ...
- ios崩溃日志收集_iOS崩溃与日志分析
在iOS开发中经常需要靠记录日志来调试应用程序.解决崩溃问题等,整理常用的日志输出和崩溃日志分析. 最新更新:2018-11-30 基于CocoaLumberjack 的 Swift使用封装库 一.崩 ...
- iOS崩溃日志的分析
崩溃日志的产生 iOS中运行App过程中如果发生程序崩溃,会生成一个崩溃日志文件.这个文件会保存的特定系统目录下,扩展名是crash.当手机连接到iTunes时,会将该文件同步到电脑上. 在Mac系统 ...
- 如何看iOS崩溃日志
重点:Triggered by Thread这句话后边的线程号,快速定位问题出现在那个线程,是否是你的锅:Triggered by Thread所指的线程表示导致异常.崩溃的线程 下边内容转自简书 简 ...
- ios崩溃日志收集_漫谈iOS Crash收集框架
为了能够第一时间发现程序问题,应用程序需要实现自己的崩溃日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 等.追求方便省心,对于保密性要求不高的程 ...
- 遭遇Crash文件战:教你如何搞定iOS崩溃日志
请叫我背景 最近在提交应用到App Store的时候,竟然被拒了两次.那时候心里的想法是,尼玛完蛋了,要被老板开除了,我是不是要失业了.于是乎那两周几乎毛脑子都是为什么Apple你这么狠心,我们明明相 ...
- iOS应用崩溃日志分析 iOS应用崩溃日志揭秘
转自:http://www.raywenderlich.com/zh-hans/30818/ios%E5%BA%94%E7%94%A8%E5%B4%A9%E6%BA%83%E6%97%A5%E5%BF ...
最新文章
- 我们需要什么样的数据架构?
- Jenkins持续集成环境之插件管理和角色管理
- ADO.NET知识要点
- 阿里云ARMS重磅推出小程序监控,助力小程序稳定运行
- 数据仓库中的模型设计(转)
- web 折线图大数据量拉取展示方案_分布式、服务化的企业级 ERP 系统架构设计方案...
- [C] 跨平台使用Intrinsic函数范例2——使用SSE2、AVX指令集 处理 双精度浮点数组求和...
- 计算机办公软件考证教学总结,考证经历——办公软件的套路
- linux运行uclinux程序,uClinux的编译与运行详解
- cs6制作拼图游戏 dreamweaver_Dreamweaver制作拼图步骤
- 8.22 ps课堂练习
- 拼多多直播带货,中小主播及商家的新机会
- 投影仪用光学引擎行业现状调研及趋势分析报告
- JavaScript实现存款利息计算器
- 计算机视觉图像处理入门
- 求二叉树根节点到叶节点的所有路径
- Linux 监控工具 tsar(转)
- ArcGIS中的TIN与DEM数据的生成
- int和String类型的转换
- js:图片url转base64编码