xcactivitylog

Xcode 日志存储在扩展名为.xcactivitylog。 文件内容是经过一种 SLF 的编码格式进行压缩过的。可以通过gzip -cd 展开。在Logs/Build下有一个LogStoreManifest.plist文件,终端plutil -p 打开,里面会有很多字段,其中timeStartedRecording 655351382.847489 需要使用timeIntervalSinceReferenceDate方法还原时间戳

SLF 格式

SLF文档的头部以SLF0开始。在header之后,文档有一组编码过的值。SLF编码格式支持以下类型:

  • Integer
  • Double
  • String
  • Array
  • Class names
  • Class instances
  • Null

编码的值由 3 部分组成:

  • 左侧值(可选)
  • 字符类型分隔符
  • 右侧值(可选)

Integer

  • 字符类型分隔符: #
  • 例子: 200#
  • 左侧值:一个无符号的 64 位整数。

Double

  • 字符类型分隔符: ^
  • 例子: afd021ebae48c141^
  • 左侧值:以十六进制编码的小端浮点数。

可以使用以下bitPattern属性将其转换为 Swift Double Double

guard let value = UInt64(input, radix: 16) else {
  return nil
}
let double =  Double(bitPattern: value.byteSwapped)

xcactivitylog的文件中,这种类型的值用于编码时间戳。因此,double 表示使用 的timeIntervaltimeIntervalSinceReferenceDate

Null

  • 字符类型分隔符: -
  • 没有左边,也没有右边的值

String

  • 字符类型分隔符: "
  • 例子: 5"Hello
  • 左侧值:一个Integer,表示字符串的长度
  • 右侧值: String

字符的数量在NSString中有效,但在String中无效,因为它计算字符串的UTF-16表示中的16 bit单元,而不是像在Swift的String中那样计算字符串中的Unicode扩展字符集群的数量。

所以使用 UTF-8 对SLF格式进行字符串加载会记数不匹配,可以通过加载为 ASCII 字符串避免该问题:

let content = String(data: unzippedXcactivitylog, encoding: .ascii)

其他示例: 6"Hello--9# 在这种情况下,有三个编码值:

  1. 字符串“Hello-”
  2. Null
  3. 整数 9。

Array

  • 字符类型分隔符: (
  • 例子: 22(
  • 左侧值:一个表示数组的元素数量的整数

Array的节点是Class instances

Class name

  • 字符类型分隔符: %
  • 例子: 21%IDEActivityLogSection
  • 左侧值:类名字符个数的整数
  • 右侧值: Class name

它遵循与String相同的规则。

一个给定Class name只出现一次:在它的第一个Class instance. 在日志中存储Class名称的顺序很重要,因为Class instance使用该索引

Class instance

  • 字符类型分隔符: @
  • 例子: 2@
  • 左侧值:具有类实例类型的类名索引的整数。

在上述的2@情况下,意味着Class instance的类型是在SLF文档中第3个位置找到的Class name。

Tokenizing .xcactivitylog

使用这些规则,可以解码日志并将其标记化。例如:

SLF010#21%IDEActivityLogSection1@0#39"Xcode.IDEActivityLogDomainType.BuildLog20"Build XCLogParserApp20"Build XCLogParserApp0074f8eaae48c141^8f19bcf4ae48c141^12(1@1#50"Xcode.IDEActivityLogDomainType.XCBuild.Preparation13"Prepare build13"Prepare build

可以获得这些token:

[type: "int", value: 10],
[type: "className", name: "IDEActivityLogSection"],
[type: "classInstance", className: "IDEActivityLogSection"],
[type: "int", value: 0],
[type: "string", value: "Xcode.IDEActivityLogDomainType.BuildLog"],
[type: "string", value: "Build XCLogParserApp"],
[type: "string", value: "Build XCLogParserApp"],
[type: "double", value: 580158292.767495],
[type: "double", value: 580158295.086277],
[type: "array", count: 12],
[type: "classInstance", className: "IDEActivityLogSection"],
[type: "string", value: "Xcode.IDEActivityLogDomainType.XCBuild.Preparation"],
[type: "string", value: "Prepare build"],
[type: "string", value: "Prepare build"],

第一个整数是所用SLF格式的版本。在 Xcode 10.x 和 11 Beta 中,version 为 10。version 后面的值是日志的实际内容。

你可能感兴趣的:(xcactivitylog)