1 Instrument 10 架構(gòu)
主要分為兩個部分 Standard UI (界面) 和 Analysis Core (分析核心)

1.1
其中 Standard UI 也是分為兩部分 : table (藍(lán)色部分)和 graph (紅色部分).

其中
table 又大致分為5種格式1 List (列表)
2 Aggregation (聚合顯示)
3 Call Tree (就是timeprofile 中的堆棧)
4 Narrative (敘事)
5 Time Slice (時間片)
graph的話基本分為4種顯示
1 Plot

2 Automatic Treatment
3 Plot Template

4 Histogram (矩形圖)
2 graph和table的數(shù)據(jù)來源.
這就到了介紹 Analysis core的時候了。首先就是收集,存儲[不需要我們實現(xiàn)], 分析(合并), 可視化。
一個數(shù)據(jù)的展示流程
Tracing -> Schemas/Modeling -> Visualization
2.1 數(shù)據(jù)源
數(shù)據(jù)源 通過 定義的os_singPost 或者 molder規(guī)則產(chǎn)生數(shù)據(jù), 我們利用收集到的數(shù)據(jù) 去定義 Schema ,可以說 Instrument 的所有可視化都是依賴于Schema ,因為定義的 modeler 也是要輸出到 Schema中
Schema 分為
<1 <os-signpost-interval-schema> 對應(yīng)我們自定義的 os_singPost 或者modeler
<2 <point-schema> 點類型 schema

2.2 如何在schema使用數(shù)據(jù)源
<1 os_singPost的數(shù)據(jù)源 需要在 schame中 <start-pattern> <end-pattern>中的定義 和 代碼中定義的 參數(shù)名 一致。
代碼中的定義
case .downloading:
os_signpost(.begin, log: SignPostLog.imageLoadLog, name: SignPostLog.imgDownload, signpostID:OSSignpostID(log: SignPostLog.imageLoadLog, object: self),"Image name:%@", name)
case .success:
os_signpost(.end, log: SignPostLog.imageLoadLog, name: SignPostLog.imgDownload, signpostID:OSSignpostID(log: SignPostLog.imageLoadLog, object: self),"download result:%@, time:%d", "success", time)
case .cancel:
os_signpost(.end, log: SignPostLog.imageLoadLog, name: SignPostLog.imgDownload, signpostID:OSSignpostID(log: SignPostLog.imageLoadLog, object: self),"download result:%@, time:%d", "cancel", time)
Schema中的定義
<os-signpost-interval-schema>
<!-- 數(shù)據(jù)捕捉 -->
<start-pattern>
<message>"Image name:"?image-name</message>
</start-pattern>
<end-pattern>
<message>"download result:" ?result ", time:" ?time</message>
</end-pattern>
</os-signpost-interval-schema>
<2 關(guān)于使用 modeler 進(jìn)行數(shù)據(jù)源采集
需要到 CLIPS 語法定義 modeler 規(guī)則 進(jìn)行數(shù)據(jù)收集, 然后在自定義的 Instrument 配置文件中增加 <modeler> 模塊
先看一個示例
<!-- 建模器 -->
<modeler>
<id>com.coderhg.dt.download.Anitipatterns</id>
<title>Anti-patterns modeler</title>
<purpose>Generates warnings into detected</purpose>
<production-system>
<rule-path>duplicate-call-detection.clp</rule-path>
</production-system>
<output>
<schema-ref>downloader-narrative</schema-ref>
<required-input>
<schema-ref>os-signpost</schema-ref>
</required-input>
</output>
</modeler>
此modeler 是數(shù)據(jù)規(guī)則 在duplicate-call-detection.clp 文件中定義, 輸出的schema 是 downloader-narrative ,還有一個必須要強制導(dǎo)入的 os-signpost(系統(tǒng)的 Schema) 的依賴。
然后 在 downloader-narrative 的 schema 中將 modeler采集到的數(shù)據(jù) 再定義成需要使用的 column 供給 instrument 使用。
Sorry:本文暫不涉及 modeler文件的編寫。
2.3 然后將數(shù)據(jù)定義成 column 提供給 instrument 中定義的 table 和 graph
如下就是將image-name數(shù)據(jù) 轉(zhuǎn)換成 column, 還可以自己定義如何展示column的規(guī)則
<os-signpost-interval-schema>
<!-- 定義數(shù)據(jù)結(jié)構(gòu) -->
<column>
<mnemonic>image-name</mnemonic>
<title>image-name-title</title>
<type>string</type>
<expression>?image-name</expression>
</column>
<column>
<mnemonic>impact</mnemonic>
<title>Impact</title>
<type>event-concept</type>
<!-- 如果size?大于2 就是 高 否則 是 低 -->
<expression>(if (> ?size 2) then "High" else "Low")</expression>
</column>
</os-signpost-interval-schema>
3 Instrument
3.1 Instrument的結(jié)構(gòu)
Instrument 的格式采用 xml 。
主要分為三部分
1 基本參數(shù)定義 Instrument 的 一些基本參數(shù)(名稱、描述、id、icon) ,更多的還可以從外部引入其他 parameter 參數(shù)
<instrument>
<id>com.mm.uitest.DownloaderInstrument.downloader</id>
<title>Instruement-title</title>
<category>Behavior</category>
<purpose>Download-purpose</purpose>
<icon>Generic</icon>
<import-parameter>
<from-scope>trace</from-scope>
<name>?target-pid</name>
</import-parameter>
</instrument>
2 創(chuàng)建 table,table 一定要引入 schema
<instrument>
<create-table>
<id>image-download-table</id>
<schema-ref>image-download-schema</schema-ref>
</create-table>
</instrument>
3 創(chuàng)建可視化(graph or table )就是第一部分說的 標(biāo)準(zhǔn)UI 部分, 數(shù)據(jù)依賴于 第二部定義的 table, 所有數(shù)據(jù)源都必須是 table 中依賴的 schema 中定義的 column, 具體展示格式可以根據(jù)需要進(jìn)行調(diào)整。
以list 為例
<instrument>
<list>
<title>image-download-list</title>
<table-ref>image-download-table</table-ref>
<column>image-name</column>
<column>image-result</column>
<column>image-time-mnemonic</column>
</list>
</instrument>
蘋果詳細(xì)的 Instrument 配置 格式文檔
一下是一個完整的Instrument 結(jié)構(gòu)
<package>
<!-- package定義 -->
<!-- 定義或者 引入系統(tǒng)的schema -->
<import-schema>os-signpost</import-schema>
<os-signpost-interval-schema>
......
<column></column>
</os-signpost-interval-schema>
<!-- 定義modeler -->
<modeler>
......
</modeler>
<!-- 定義Instrument -->
<instrument>
<!-- 基本參數(shù)定義 -->
<id>com.mm.DownloaderInstrument.downloader</id>
<title>Image Download</title>
<category>Behavior</category>
<purpose>ShowImageDownPurpose</purpose>
<icon>Generic</icon>
<!-- 創(chuàng)建table 必須要依賴某個 schema -->
<create-table>
<id>image-download-table</id>
<schema-ref>image-download-schema</schema-ref>
</create-table>
<!-- 可視化 -->
<graph>
<title>Background Images</title>
<lane>
</lane>
</graph>
<list>
<title>image-download-list</title>
<table-ref>image-download-table</table-ref>
<column>image-name</column>
</list>
</instrument>
總結(jié): 所有的可視化數(shù)據(jù) 都是來自于table 而table 又依賴于 自定義或者 蘋果已經(jīng)實現(xiàn)的schema 。所以所有的數(shù)據(jù)都需要換成 schema中的 column
4 自定義展示一個 time-profile
此處我因為沒有讀懂 time-profile 中modeler源碼,所以數(shù)據(jù)源無法自定義,只能獲取 time-profile的數(shù)據(jù)并自定義的展示出來。
time-profile 的 modeler的源碼推測是在 此路徑中
?Xcode.app? ? ?Contents? ? ?Applications? ? ?Instruments.app? ? ?Contents? ? ?Packages? ? ?Sampling.instrdst? ? ?Contents? ? ?Extensions ? ??com.apple.dt.instruments.time-profiler.dtac??
1、首先在自定義的 Instrument 中 引入 time-profile 所在的 package (sampling), SystemTrace是 另一個package.

系統(tǒng)的
schema和 package可以通過 Instrument的 preferences 查看 我們自定義的 package 也會在這里展示出來
2、通過查看time-profile 的配置xml 文件 ,可知time-profile中所有暴露出的所有 column ,所有的column都可以為我們所用
xml 文件所在路徑 Xcode.app? ? ?Contents? ? ?Applications? ? ?Instruments.app? ? ?Contents? ? ?Packages? ? ?Sampling.instrdst? ? ?Contents? ? ?Extensions? ? ?com.apple.dt.instruments.sampling.dtac?
3、如此自定義展示需要的column
3.1 package中引入 time-profile
3.2 在Instrument 中 創(chuàng)建表格
3.3 可視化 time-profile 中的 column
備注: 在蘋果的文檔中透漏了一部分 time-profile 的 xml部分源碼,但是time-profile 的具體 modeler的源碼 可能是在 Sampling.instrdst? 的 Extension 中.
3.4 代碼。
<package>
<id>com.mm.uitest.DownloaderInstrument</id>
<title>DownloaderInstrument</title>
<owner>
<name>mumu</name>
</owner>
<import-schema>time-profile</import-schema>
<instrument>
<id>com.mm.uitest.DownloaderInstrument.downloader</id>
<title>Instruement-title</title>
<category>Behavior</category>
<purpose>Download-purpose</purpose>
<icon>Generic</icon>
<import-parameter>
<from-scope>trace</from-scope>
<name>?target-pid</name>
</import-parameter>
<create-parameter>
<name>?recordWaitingThreads</name>
<boolean-value>
<true-choice>Record Waiting Threads</true-choice>
</boolean-value>
</create-parameter>
<create-parameter>
<name>?highFreqSampling</name>
<boolean-value>
<true-choice>High Frequency</true-choice>
</boolean-value>
</create-parameter>
<create-parameter>
<name>?recordKernelStacks</name>
<boolean-value>
<true-choice>Record Kernel Call Stacks</true-choice>
</boolean-value>
</create-parameter>
<create-table>
<id>image-stack-table</id>
<schema-ref>time-profile</schema-ref>
<attribute>
<name>needs-kernel-callstack</name>
<parameter-ref>?recordKernelStacks</parameter-ref>
</attribute>
<attribute>
<name>high-frequency-sampling</name>
<parameter-ref>?highFreqSampling</parameter-ref>
</attribute>
<attribute>
<name>record-waiting-threads</name>
<parameter-ref>?recordWaitingThreads</parameter-ref>
</attribute>
<attribute>
<name>target-pid</name>
<parameter-ref>?target-pid</parameter-ref>
</attribute>
</create-table>
<list>
<title>image-stack-list</title>
<table-ref>image-stack-table</table-ref>
<column>time</column>
<column>stack</column>
<column>thread</column>
<column>process</column>
<column>weight</column>
<column>thread-state</column>
</list>
<calltree>
<title>DemoCallTree</title>
<table-ref>image-stack-table</table-ref>
<backtrace-column>stack</backtrace-column>
<thread-column>thread</thread-column>
<category-column>thread-state</category-column>
<weight-column>weight</weight-column>
</calltree>
</instrument>
可視化效果


后續(xù)深入:
1 time-profile如何獲取數(shù)據(jù)源,modeler 綁定方法 ,定義規(guī)則
2 (time-profile是從kernel 獲取堆棧信息) 比timer-profile更靈活的使用 kernel 中的 堆棧.
3 更細(xì)致的理解 package 的參數(shù)使用
難點: CLIPS 語法理解
和實際在 modeler 中的使用
參考
WWDC 2018:創(chuàng)建自定義的 Instrument
Xcode 中自定義 Instruments
WWDC 405_measuring_performance_using_logging
WWDC 410_creating_custom_instruments
WWDC 414_developing_a_great_profiling_experience
WWDC 418_using_time_profiler_in_instruments
WWDC 421_modeling_in_custom_instruments