| RFC-0171:改善診斷作業路徑 | |
|---|---|
| 狀態 | 已接受 | 
| 區域 | 
 | 
| 說明 | 推出 CML 和 CMC 公用程式,改善診斷轉送 | 
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2022-05-19 | 
| 審查日期 (年-月-日) | 2022-06-23 | 
摘要
這項提案建議在 cmc 和 CML 中提供公用程式,以簡化樹狀結構中所有位置的診斷通訊協定 (fuchsia.logger.LogSink 和 fuchsia.diagnostics.InspectSink) 路由,並減少缺少記錄或檢查資料的 DX 痛點。雖然本文件著重於檢查和記錄,但也可以用於改善大多數元件可能需要的其他通訊協定,例如 fuchsia.tracing.provider.Registry。
提振精神
使用記錄檔的 DX 痛點是,元件需要在所有地方路由 fuchsia.logger.LogSink:在正式版元件、測試和 RealmBuilder 路徑中等。記錄檔是大多數 Fuchsia 體驗的核心部分,我們希望幾乎每個元件和測試都會使用記錄檔。
RFC-0168 建議使用通訊協定 fuchsia.inspect.InspectSink,讓元件發布 Inspect,以便進行一些改善並減少技術債務。就像 fuchsia.logger.LogSink 一樣,我們希望所有 (或至少大多數) 元件都使用 Inspect 檢測功能。目前,每個元件都可以 expose /diagnostics to framework,讓每個元件都能公開檢查功能,並提供給 Archivist 使用。我們必須朝向通訊協定邁進,確保所有元件都能繼續公開檢查資料,這對開發人員來說非常重要,可用於偵錯元件在執行階段執行的作業。
這不符合人體工學,且容易出錯,因為我們需要更新所有 CML,才能手動將這個通訊協定路由至目前正在寫入檢查資訊的所有元件。LogSink 也存在相同的問題,尤其是在測試中,很容易忘記將 LogSink 路由至測試中的元件,導致記錄遺失,並浪費開發人員的時間。
元件管理服務會利用元件的 LogSink 列印與該元件相關的路由錯誤。這可改善 DX,因為開發人員可以快速找出路由錯誤。不過,如果 LogSink 未正確轉送,這些錯誤就會出現在歸因於元件管理服務的全域 syslog,開發人員更容易錯過這些錯誤,因為他們會查看自己的元件記錄。
本文件嘗試在 cmc 和 CML 中引入公用程式,以便簡化將這兩種通訊協定轉送至每個元件的程序,進而改善上述情況。
元件架構預計會審查導向 API,並構思如何讓模型更一致且更符合使用者需求。這需要好幾個季度,因此建議採用使用現有基本元素並擴充這些元素的漸進式方法。
相關人員
講師:leannogasawara@google.com
審查者:
- crjohns@google.com
- geb@google.com
- hjfreyer@google.com
- shayba@google.com
- zarvox@google.com
諮詢:
- bryanhenry@google.com
- cgonyeo@google.com
- jmatt@google.com
- thatguy@google.com
社會化:這項設計以 Google 文件文件的形式進行社會化,這是一份決策文件,其中列出的替代方案經過深入討論,並在利益相關者之間進行會議和對話。
設計
為了讓開發人員更容易在現有元件功能路由系統下,不錯過任何記錄和檢查功能,並遵循最低權限和階層式隔離原則,並繼續能夠公開檢查功能,我們將開發以下項目:
- cmc檢查是否有必要的商品。
- 可為 CML 中的所有子項和集合提供能力。
- 新的診斷用 CML 分片。
- RealmBuilder會自動為所有元件提供診斷功能。
cmc 必要的優惠和用途
cmc 會取得指令列選項 --must-offer-protocol,其中包含一組通訊協定名稱清單,並驗證下列陳述式是否為真:
對於資訊清單中宣告的每個子項和集合,每個必要通訊協定清單中定義的通訊協定,都會存在從某個來源連往該子項和集合的
OfferDecl。
此外,cmc 會取得對等的指令列選項 --must-use-protocol,用於檢查 UseDecl 的對等項目。
每當呼叫 cmc 時,系統都會更新 GN 和 Bazel 工具,以便在這些選項中傳遞 fuchsia.logger.LogSink 和 fuchsia.diagnostics.InspectSink。
如要完全停用這項檢查功能,無論資訊清單如何呼叫 cmc,開發人員都可以在 CML 檔案中加入以下內容 (這是 CML 中推出的新語法):
{
    disable: {
        must_use_protocol: [ "fuchsia.logger.LogSink", "fuchsia.diagnostics.InspectSink" ],
        must_offer_protocol: [ "fuchsia.logger.LogSink", "fuchsia.diagnostics.InspectSink" ],
    }
}
如果開發人員不想將 LogSink 或 InspectSink 導向部分子項,可以自由選擇以下做法:
- 使用能力路徑:將通訊協定 from: "void"路由至他們想要關閉單一商品的子項/集合。
- 手動將通訊協定從所需來源轉送。
這些功能的來源 bootstrap 和 root 領域需要特殊處理:
- bootstrap:這個選項會開啟,確保- LogSink會轉送至 Bootstrap 中的所有元件。此外,也會將優惠- Inspect/- LogSink從- void新增至 Archivist。
- root:這個選項會開啟,確保我們將- LogSink從 Archivist 轉送至所有同層兄弟姊妹。由於- bootstrap是提供這項能力的服務,我們會從- void新增- Inspect/- LogSink至- bootstrap。
我們希望透過這項功能,讓 Fuchsia 上的每位開發人員都不會錯過記錄或檢查資料。
zarvox@ 為這個部分建立了原型 (和關聯鏈結)。
允許在 CML 中為所有子項和集合提供能力
為改善轉送至所有子項的 DX,我們會在 CML 中導入語法糖,讓您將能力轉送至「所有子項和集合」。
您可以使用以下語法糖果:
offer: [
    {
        protocol: "fuchsia.logger.LogSink",
        from: "parent",
        to: "all",
    }
]
當含有該語法的 CML 檔案編譯時,系統會產生 N 個 OfferDecl,其中 N 是元件擁有的集合和子項總數。
目標為 all 的 OfferDecl 會在 cmc 中設下門檻,僅可用於在前一個章節所述的新選用引數中定義的通訊協定。
CML 分割區
系統會建立下列切片:
// syslog/use.shard.cml
{
    use: [
        { protocol: "fuchsia.logger.LogSink" },
    ],
}
// syslog/offer.shard.cml
offer: [
    {
        protocol: "fuchsia.logger.LogSink",
        from: "parent",
        to: "all"
    }
]
// inspect/use.shard.cml
{
    use: [
        { protocol: "fuchsia.diagnostics.InspectSink" },
    ],
}
// inspect/offer.shard.cml
offer: [
    {
        protocol: "fuchsia.diagnostics.InspectSink",
        from: "parent",
        to: "all"
    }
]
系統會更新下列現有分割區:
- syslog/client.shard.cml:包含- syslog/use.shard.cml和- syslog/offer.shard.cml。
- inspect/client.shard.cml:包含- inspect/use.shard.cml和- inspect/offer.shard.cml。
只執行路由而不會執行任何程式的邏輯元件,可以使用 offer.shard.cml。需要使用這些通訊協定,但需要設定要將哪些內容導向子項的元件,可以使用 use.shard.cml。其餘的則可使用標準且方便的 client.shard.cml。
如果元件沒有子項或集合,但仍使用 client.shard.cml (因為使用的是通訊協定),則分割區中的 offer to all 陳述式會是無操作,因為它是語法糖,只會如前所述展開為 OfferDecl。
為了方便起見,我們會提供包含兩個 client.shard.cml 檔案的 diagnostics/client.shard.cml。
RealmBuilder 更新以支援 offer to all
為方便將診斷通訊協定轉送至所有測試中的元件,RealmBuilder 會收到幾項更新,可將通訊協定轉送至所有子項和集合:
- 自動為所有子項和集合提供 LogSink 和 InspectSink。在 Rust 中,這可能會是以下形式: - builder .add_route( Route::new() .capability(Capability::protocol_by_name("fuchsia.diagnostics.InspectSink")) .from(Ref::parent()) .to(Ref::all()), ) .await?;
- 除了某些特殊情況外,我們希望所有測試都會這麼做,因此 RealmBuilder 會自動將這些通訊協定轉送至所有元件。這似乎與 - cmc和 CML 採用的方法不一致,但- RealmBuilderAPI 在某些方面已經偏離,以提供更方便的工作流程,更適合用於測試。我們預期 99% 的時間都會將這些通訊協定導向至測試元件,因此我們會教導- RealmBuilder自動執行這項操作,並提供關閉這項功能的方法:- let builder = RealmBuilder::new().await?; … let instance = builder .route_logs_to_all(false) // defaults to true .route_inspect_to_all(false) .build() .await;
實作
- 更新 cmc,以便支援 CML 中的新標記和offer to all。
- 新增包含 offer LogSink to all的syslog/offer.shard.cml。
- 更新樹狀結構中的 cmc用法,以便使用新旗標,並更新可能缺少路徑的現有 CML。系統會更新 GN 和 Bazel SDK,但在 OOT CML 遷移至完整的產品組合之前,這些 SDK 的必要通訊協定預設為[]。
- 更新樹狀結構中的 cmc用法,以便使用新旗標,並更新可能缺少路徑的現有 CML (利用優惠分片)。
- 更新 GN 和 Bazel SDK,要求使用診斷通訊協定。
- 納入 syslog/client.shard.cml中的syslog/offer.shard.cml。
- 推出後,請重構使用商品分片但不再需要該分片的 OOT 資訊清單,因為該分片已透過用戶端分片納入。
成效
cmc 會執行一些額外工作,但在編譯期間不會造成任何重大影響。
安全性考量
這項變更符合元件架構安全性屬性,特別是最低權限原則和階層隔離原則。
隱私權注意事項
不會影響隱私權。
測試
新的 cmc 功能將進行單元測試。
說明文件
cmc 會更新為納入新選項,而 CML 也會更新為說明新的 offer to all 功能。
缺點、替代方案和未知事項
在 Environment 中使用 debug_capabilities
這是我們主要考慮的替代方案。在這個替代方案中,我們會擴充 fuchsia.sys2.Environment,讓它擁有 diagnostics_capabilities,就像 debug_capabilities 一樣,或將 debug_capabilities 轉換為 diagnostics_capabilities,或只將 debug_capabilities 用於診斷通訊協定,讓樹狀結構 from: diagnostics 或 from: debug 中的任何元件都能使用。
這項功能會在元件管理服務安全性政策中設下限制,確保只有根目錄 Archivist 和測試中嵌入的 Archivist 才能使用。
優點:
- 每個元件都可以在樹狀結構的任何位置使用 InspectSink和LogSink。
- 與目前的全球狀態保持一致,每個元件都能公開檢查功能。
- 開發人員不必花時間找出元件未記錄的原因,進而發現測試中缺少了廣告,因此可改善使用者體驗。
- 可靜態檢查能力的點對點用法。
- 除非明確使用此能力,否則所有元件在命名空間中都會以「nothing」開頭。
- 涵蓋透過 fuchsia.component.Realm/CreateChild建立的動態元件。
缺點:
- 不再提供明確的父項子項,這表示這項功能不符合階層隔離的安全性原則。
- 在拓撲中取代或模擬 LogSink/InspectSink需要調整環境,而這需要變更安全政策。
- 這不是自食其力的最佳例子嗎?第三方開發人員無法將環境用於其通訊協定的任意用途,我們為何要這麼做?
製作 LogSink 和 InspectSink 架構功能
允許使用這些通訊協定 from: framework。Archivist 可以將這些功能公開給架構,也可以在 Archivist 和元件管理服務之間建立合約,以便提供這些功能。
優點:
- 優點與前述替代方案相同,但詳細說明診斷通訊協定 (InspectSink和LogSink) 會成為架構通訊協定,即使未由元件管理服務提供服務也一樣。
- 由於每個元件都會取得專屬的一組架構功能,因此不需要指派能力,因為指派作業會直接在架構中執行。
缺點:
- 與前述替代方案相同的缺點。
- 從框架使用的通訊協定第一個例項,此框架並非由元件管理服務本身提供。
- 不清楚如何在測試中提供獨立的記錄,而無須建立供 Test Manager 使用的額外機制。
- 為所有裝置端元件建立單一記錄目的地。
讓 cmc 自動為所有孩子提供 LogSink
cmc 會為每個子項和集合自動執行這項操作,而非使用標記要求使用者將 OfferDecl 新增至 CML。
優點:
- 明確的父項/子項產品,可協助模擬、取代拓樸中的通訊協定等。
- CML 沒有任何變更。
缺點:
- 在 CMC 中對某項能力採取特殊處理。
- 在 .cml中宣告的元件和透過Realm/CreateChild建構的元件行為不一致。
在 cmc 中提供選項,並在 CML 中提供語法糖,可讓這項功能更具彈性,並提供可供他人利用的機制,而不僅限於診斷。
不採取任何行動,並照常轉送
請開發人員手動為所有子項提供 LogSink 和 InspectSink。
優點:
- 明確的父項/子項產品,可協助模擬、取代拓樸中的通訊協定等。
- API 邊界仍是父項和子項之間的本地問題,而非涉及其他方的邊界。
缺點:
- 目前的問題:很容易遺漏 LogSink 路由,導致在偵錯測試時浪費時間。
- 其他問題:很容易錯過將 InspectSink路由至某個元件 (因為目前每個人都可以公開),導致在欄位中遺漏診斷資訊。這與 LogSink 遇到的問題相同,因此我們現在在兩個通訊協定中都遇到這個問題,而非只有一個。
考量這些通訊協定的廣泛使用情形,我們認為在 cmc 和 CML 中新增其他選項,有助於降低遺漏路徑的可能性。
其他想法
我們也討論了其他想法,例如使用能力套件來路由包含兩種通訊協定的 diagnostics 套件,或是以網域或能力來源的形式改善環境。由於我們計畫審查路由 API,因此捨棄了這些方案,改用採用現有機制和 API 的短期解決方案。
既有技術與參考資料
無