Fuchsia 中的元件可能會公開符合 Inspect API 的自身結構化資訊。本文將說明元件檢查的概念、介面、介面的 C++ 語言實作,以及與公開資訊的元件互動的使用者工具。
快速連結
不知道該從何處著手嗎?
- 快速入門:元件檢查入門指南。
ffx inspect:檢查元件的ffx指令。- Codelab:以 C++ 和 Rust 撰寫的完整程式碼研究室。
- C++ 和 Rust 的 API 參考資料。
- 健康狀態檢查:說明健康狀態檢查子系統。
概念
元件可能會公開 Node 樹狀結構,每個節點都有一組屬性。

節點
節點是元件中匯出的實體,可能沒有子項,也可能有多個子項。每個節點都有名稱,且節點的每個子項在子項中都必須有不重複的名稱。

屬性
節點可以有任意數量的屬性。屬性具有字串鍵和值,值可以是下列任一類型:
數值類型
UintProperty- 64 位元不帶正負號整數。IntProperty- 64 位元帶正負號整數。DoubleProperty- 64 位元浮點值。BoolProperty- 布林值。
字串類型
StringProperty- UTF-8 字串。ByteVectorProperty- 位元組向量。
陣列類型
UintArray、IntArray、DoubleArray:對應數字型別的陣列。
直方圖類型
LinearUintHistogram、LinearIntHistogram、LinearDoubleHistogram
直方圖,其中固定大小的 bucket 儲存在陣列中。
ExponentialUintHistogram、ExponentialIntHistogram、ExponentialDoubleHistogram
直方圖,其中以指數大小的值區儲存在陣列中。
檢查檔案格式
「檢查檔案格式」是二進位格式,支援在執行階段有效插入、修改及刪除節點和屬性。讀者可持續取得內容的快照,不必與作者溝通。
檔案系統介面
頂層節點會以 VmoFiles 的形式,顯示在元件的傳出目錄中,並以 .inspect 副檔名結尾。元件通常會將主要或根樹狀結構公開為 out/diagnostics/root.inspect。
語言程式庫
C++
C++ Inspect 程式庫完整支援 Inspect 檔案格式的寫入和讀取作業。
寫入檢查資料的元件應避免讀取該資料。 讀取時需要遍歷整個緩衝區,這項作業非常耗費資源。
Inspector 類別會提供包裝函式,用於建立可新增至單一根節點的新緩衝區。節點和屬性具有型別包裝函式,超出範圍時會自動從緩衝區刪除基礎資料。
inspect_component 程式庫提供簡單的 ComponentInspector 單例介面,可協助您從元件公開單一階層,這是常見的做法。
健康功能支援以健康檢查工具可辨識的格式,公開結構化健康資訊。
測試比對器程式庫提供 GMock 比對器,用於驗證測試中從 Inspect 階層讀取的資料。
閱讀輔助
讀取程式庫支援將檢查檔案剖析為 Hierarchy。Hierarchy 包含 NodeValue 和 PropertyValues,分別是 Node 和 Property 的剖析版本。
Hierarchy 的 NodeValue 會由 node() 傳回,而子項 Hierarchy 則會由 children() 以向量形式傳回。GetByPath 函式支援依路徑讀取特定子項階層。
特定 NodeValue 的屬性可透過 properties() 存取子取得。如要判斷屬性是否包含特定型別,請將對應的 PropertyValue 型別做為範本參數,傳遞至 Contains<T>() 方法:
// Returns true if the first property of the hierarchy's node is an INT value.
if (hierarchy.node().properties()[0].Contains<IntPropertyValue>()) {
// ...
}
使用 Get<T>() 方法取得屬性:
// Get the IntPropertyValue of the first property on the node.
// Note: This causes a runtime exception if the property does not contain
// the given type, crashing the program.
hierarchy.node().properties()[0].Get<IntPropertyValue>();
您也可以根據不同的可能格式類型切換:
const auto& property = hierarchy.node().properties()[0];
switch (property.format()) {
case FormatType::INT:
const auto& value = property.Get<IntPropertyValue>();
/* ... */
break;
/* ... */
}
陣列類型可特別設定格式,以包含直方圖。GetBuckets() 方法支援從 {Int,Uint,Double}ArrayValue 型別傳回直方圖值區陣列。如果基礎陣列不是特別格式化的直方圖,這個陣列就會是空白。
Rust
Rust Inspect 程式庫完整支援 Inspect 檔案格式的寫入和讀取作業。
寫入檢查資料的元件應避免讀取該資料。 讀取時需要遍歷整個緩衝區,這項作業非常耗費資源。
Inspector 類別會提供包裝函式,用於建立可新增至單一根節點的新緩衝區。節點和屬性具有型別包裝函式,超出範圍時會自動從緩衝區刪除基礎資料。
component 模組支援簡單的 inspector 函式,可處理從元件公開單一層級的常見用途。
健康模組支援以健康檢查工具可辨識的格式,公開結構化健康資訊。
測試模組支援 assert_data_tree! 巨集,可比對 Inspect 資料以進行測試。
測試
驗證器架構說明 Inspect 語言程式庫的整合測試架構。
使用者空間工具
ffx inspect
如要檢查元件的檢查階層,可以使用 ffx inspect show 指令:
列印所有檢查階層:
ffx inspect show列印特定元件的檢查階層 (例如
core/font_provider):ffx inspect show core/font_provider
ffx inspect show 也會對輸入內容進行模糊比對。例如:
ffx inspect show archivist.cmThis prints all of the Inspect forbootstrap/archivist as long as this is the only 元件 that exposes Inspect in the system whose URL ends witharchivist.cm 。
如果輸入內容不夠具體,無法識別個別元件,模糊比對就會失敗。在這種情況下,工具會列印與查詢相符的代號清單。
一般來說,這項指令接受下列項目:
元件路徑名稱,例如
core/network/netstack。如果只傳遞路徑名稱,則集合標記不需要轉義,儘管也可以選擇轉義。模糊搜尋參數,對應於網址片段、資訊清單片段或路徑名稱片段。也就是說,資訊清單
archivist.cm適用於ffx inspect show archivist.cmbootstrap/archivist。元件選取器,例如
core/network/*。完整診斷選擇器,例如
core/network/netstack:root/path/to/*:property。在完整選取器的情況下,必須執行逸出,才能建立有效的選取器。
假設您有 bootstrap/driver-hosts:driver-host-337 元件,如要盡可能避免逸出特定屬性,符合人體工學的做法可能如下:
ffx inspect driver-host-337 --data root/stats:my_statFFX 目標快照
ffx target snapshot 會產生 ZIP 封存檔,內含系統的診斷資訊,包括檢查:
ffx target snapshot最佳做法
避免從其他元件以巢狀方式嵌入指標
設計元件診斷時,請將每個元件的檢查階層嚴格限定在該元件產生的資料。避免從中介元件的檢查樹狀結構,轉送或巢狀檢查用戶端或下層元件的檢查指標。
將檢查指標轉送或巢狀化至外部元件底下,會對工具、偵錯和隱私權法規遵循造成多項問題:
開發人員體驗和工具歸因:檢查資料是否由元件路徑名稱歸因。診斷工具,例如
ffx inspect show和自動快照分類查詢使用元件路徑名稱檢查階層 (例如core/network/netstack)。在單一中介服務中巢狀嵌入多個元件的指標時,查詢生產者元件的路徑名稱不會傳回任何資料,查詢中介服務則會傳回無法管理的匯總階層。隱私權審查和許可清單強制執行:Fuchsia 診斷管道和快照匯出工具會使用基於路徑名稱選取器強制執行隱私權控制項。將多個製作人的指標放在外來路徑名稱下,會遮蓋資料來源、妨礙精細的資料修訂,並使隱私權審查驗證變得複雜。
生命週期和故障隔離:代表其他元件保存指標的中介元件,可以比實際指標產生器更長壽或獨立終止。如果中介程式當機,這會導致診斷資訊過時或資料遺失。
建議模式
每個元件都應在自己的路徑名稱下直接發布自己的檢查樹狀結構。