程式碼研究室:使用 Triage

本程式碼研究室會說明 Triage 公用程式:

  • 用途。
  • 如何執行,包括指令列選項。
  • 如何新增及測試設定規則,以便偵測 Fuchsia 快照中的問題。

本文件所參照的來源檔案和範例可在以下位置找到:

什麼是 Triage?

Triage 可讓您掃描 Fuchsia 快照 (snapshot.zip 檔案),找出符合預先定義條件的檔案。

分類系統可輕鬆設定新的條件,讓所有使用者都能充分運用分類功能。

必要條件

開始本程式碼研究室之前,請務必完成下列事項:

透過指令列執行 Triage

  • 如要執行 Triage:
fx triage

這個指令會使用 fx snapshot 指令下載新的 snapshot.zip 檔案。這個指令會執行位於來源樹狀結構中的預設規則:

  • //src/diagnostics/config/triage/*.triage

如要分析特定的 snapshot.zip 檔案,請使用 --data

  • 您最多可以指定一個 --data 引數。
  • --data 的引數也可以是包含解壓縮快照的目錄路徑。
  • 如果您在執行 fx triage 時未指定 --data 選項,系統會執行新的 fx snapshot,並分析其檔案。
fx triage --data my/foo/snapshot.zip

如要使用特定設定檔或特定目錄中的所有 *.triage 檔案,請使用 --config

  • 您可以使用多個 --config 引數。
  • 如果使用 --config 引數,系統不會自動載入預設規則。
fx triage --config my/directory --config my/file.triage

新增分類規則

本程式碼研究室的其餘部分會說明如何在 Triage 中設定新行為。

總覽

篩選程序會透過下列步驟,將大量的診斷資料濃縮為實用資訊:

  1. 使用設定檔 select 部分中的選取器字串,從 inspect.json 檔案中選取值。
  2. 執行運算和比較,產生新的值,如設定檔的 eval 部分所述。
  3. 根據設定檔 act 部分中的項目採取行動。
    1. 如果錯誤條件 (布林運算式) 為 True,就會發出警告。
    2. 向使用者顯示值。
  4. 支援透過 test 區段中的項目單元測試動作和運算。

尋找程式碼研究室的範例檔案

前往來源樹狀結構中的 examples/diagnostics/triage 目錄。下列指令可從該目錄執行:

fx triage --config . --data snapshot

在範例目錄中執行此指令時,如果使用未經修改的程式碼研究室檔案,系統會列印預先提供動作的一行內容:

Warning: 'always_triggered' in 'rules' detected 'Triage is running': 'always_true' was true

inspect.json

本程式碼研究室包含含有檢查資料的 inspect.json 檔案,可讓練習內容正常運作。這個檔案位於 snapshot/inspect.json 底下的範例目錄中。

rules.triage

Triage 程式會使用從一或多個 .triage 檔案載入的設定。本程式碼研究室使用位於範例目錄中的 rules.triage 檔案。

.triage 檔案使用 JSON5,比 JSON 更容易讀寫:

  • 在最後一個清單項目後方加上半形逗號是良好的風格。
  • 大部分的鍵 (包括所有有效的 Triage 名稱) 不需要加上引號。
  • 您可以使用 /* 多行 */ 和 // 單行註解。

為「檢查」值新增選取器

範例目錄中的 inspect.json 檔案指出系統有幾個問題。您將設定分類系統,以便偵測這些問題。

這個步驟會設定 Triage,從 inspect.json 檔案中的資料中擷取值。

rules.triage 檔案包含名為 select 的鍵/值區段。每個鍵 (名稱) 都可以用於其他設定項目的內容。每個值都是選取器字串。實際上,select 區段 (以及下文所述的 eval 區段) 中的每個項目都會定義一個變數。

選取器字串是以冒號分隔的字串,可指出檢查資料中可找到所需值的位置。

select: {
    disk_total: "INSPECT:bootstrap/fshost:root/data_stats/stats:total_bytes",
    // "data_stat" is an intentional typo to fix later in the codelab.
    disk_used: "INSPECT:bootstrap/fshost:root/data_stat/stats:used_bytes",
}

元件發布的檢查資料會以樹狀節點的形式排列,其中分葉節點會顯示值 (屬性)。inspect.json 檔案是這些樹狀結構的陣列,每個樹狀結構都有一個用於識別來源元件的路徑名稱。

INSPECT: 和第二個冒號之間的選取器字串部分,應與 inspect.json 檔案中的其中一個別名字串相符。

第二個冒號和第三個冒號之間的部分,是 / 分隔的節點名稱清單。

最後一個冒號後面的部分是屬性名稱。

上述選取器字串表示元件的 moniker 與字串 bootstrap/fshost 相符,且檢查樹狀結構包含路徑 root/data_stat/stats。它也會在該元件的檢查樹狀結構中,從 root 節點的 stats 子節點中,指出 used_bytes 屬性。

將上述選取器放入 rules.triage 檔案的「select」部分。

產生選取器

手動輸入選取器容易出錯,因此可以使用 fx triage --select 輸出有效的選取器。

fx triage --data snapshot --select total_bytes
INSPECT:bootstrap/fshost:root/data_stats/stats:total_bytes

您可以使用多個 --select 參數。程式會為快照的診斷資料產生所有可能的選取器,然後透過所有 --select 參數進行篩選 (grep)。

新增運算

inspect.json 檔案中選取值後,您需要執行一些邏輯和算術運算,以便查看這些值是否表示值得標記的條件。

複製並新增下列程式碼至 rules.triage 檔案的 eval 區段,以計算磁碟的使用率:

eval: {
    ....
    disk_percentage: "disk_used / disk_total",
}

eval 項目會使用一般內嵌式數學運算式。詳情請參閱「詳細資料」一節。

新增動作

在設定檔的「act」部分中,新增一項動作,在磁碟已滿 98% 時顯示警告。請使用以下幾行內容:

act: {
    ...
    disk_full: {
        type: "Warning",
        trigger: "disk_percentage > 0.98",
        print: "Disk reached 98% full",
    },
}

注意事項:

  • 「觸發條件」是評估為布林值的運算式。這可能是布林值類型選取器或運算的名稱,或任何適當的數學運算式。
  • 如要進一步瞭解比較功能,請參閱「詳細資料」一節。
  • 如要瞭解其他支援的動作,請參閱設定參考資料

新增量表

act: {
    ...
    disk_display: {
        type: "Gauge",
        value: "disk_percentage",
        format: "percentage",
    }
}

量表一律會顯示所提供的值。

format 為選填欄位。值為「percentage」時,輸出格式化工具會預期值介於 0 和 1 之間,並以百分比顯示。

立即試用

下列指令會針對本機設定檔執行 Triage。

fx triage --config . --data snapshot

您會收到類似下方的錯誤訊息:

[ERROR] In config 'rules': No value found matching selector
bootstrap/fshost:root/data_stat/stats:used_bytes

選取器規則中出現錯字,分類無法找到評估規則所需的值。事實上,正確的選取器是「data_stats」,而非「data_stat」。請在選取器規則中修正問題,然後再試一次。

fx triage --config . --data snapshot

那麼現在發生了什麼事?沒有任何問題,對嗎?那麼,您要如何判斷 inspect.json 檔案沒有問題,還是規則有錯誤?

測試規則

您可以 (而且應該) 為動作新增測試。針對每項測試,指定值,並指出這些值是否應觸發規則。

如要測試您新增的規則,請在 rules.triage 檔案的 test 區段中加入以下內容:

test: {
    ....
    is_full: {
        yes: ["disk_full"],
        values: {
            disk_used: 98,
            disk_total: 100,
        }
    }
}

values 區段中的鍵應為 evalselect 項目的名稱。提供的值會覆寫項目選取或計算的值。

您也可以測試不應觸發動作的條件:

test: {
    ....
    not_full: {
        no: ["disk_full"],
        values: {
            disk_used: 97,
            disk_total: 100,
        }
    }
}

如要執行測試,請執行 Triage。每次執行時都會自動進行自我測試。

fx triage --config . --data snapshot

哎呀!這應該會傳送錯誤訊息:

Test is_full failed: trigger 'disk_percentage > 0.98' of action disk_full returned Bool(false), expected true

修正規則

您想在磁碟已滿 98% 或更高時觸發,但這並非您寫入的內容,而且測試也發現了問題。將動作中的 > 修改為 >=

        trigger: "disk_percentage >= 0.98",

再次執行 Triage。錯誤訊息應會消失,並改為警告,指出 inspect.json 檔案確實顯示磁碟已滿。

Warning: 'disk_full' in 'rules' detected 'Disk is 98% full': 'disk98' was true

記錄檔掃描

您可以編寫運算式,測試規則運算式是否與記錄檔的某一行 (syslog.txt、klog.txt、bootlog.txt) 相符。如下所示:

    eval: {
        syslog_has_not_found: "SyslogHas('ERROR.*not found')",
        ...
    }
    act: {
        something_not_found: {
            trigger: "SyslogHas('ERROR.*not found')",
            ...
        }
    }

這些函式分別是 SyslogHas()、KlogHas() 和 BootlogHas()。如果缺少記錄檔案 (例如,某些快照檔案不含 bootlog.txt),系統會將其視為空白檔案。

如要測試這項功能,您可以在測試中加入項目,如下所示:

test: {
    test_error: {
        yes: [error_scan],
        syslog: "ERROR: file Foo not found\nSecond line OK",
    }
}

annotations.json

快照包含檔案 annotations.json,其中包含建構、電路板、正常運作時間等資訊。

您可以使用 Annotation() 函式搭配單一字串參數 (即檔案中 JSON 物件的鍵),從這個檔案擷取值。例如:

eval: {
    using_chromebook: "Annotation('build.board') == 'chromebook-x64'",
}

使用多個設定檔

您可以新增任意數量的分類設定檔,甚至在另一個檔案中使用在一個檔案中定義的變數。這項功能有許多應用:

  • 一個檔案用於磁碟相關變數和動作,另一個檔案用於網路相關變數和動作。
  • 用來定義產品專屬編號的檔案。
  • 為特定工程師或團隊建立個別檔案。

新增檔案「product.triage」,其中包含以下內容:

{
    eval: {
        max_components: "4",
    },
}

注意事項:

  • 空白區段可能會從 .triage 檔案中省略。這個檔案不含 selectacttest 項目。
  • 雖然 JSON 中的數值不含引號,但 4 是數學運算式字串,因此需要加上引號。

在 rules.triage 檔案中新增下列項目:

select: {
    ...
    actual_components: "INSPECT:bootstrap/archivist:root/event_stats:components_started",
}

這麼做可擷取裝置中已啟用的元件數量。

eval: {
    ...
    too_many_components: "actual_components > product::max_components",

這會比較實際元件與產品的理論最大值。

最後,新增動作:

act: {
    ...
    component_overflow: {
        type: "Warning",
        trigger: "too_many_components",
        print: "Too many components!",
    },
}

很抱歉,這個裝置嘗試使用太多元件,因此在執行「fx triage」時,系統會觸發這項警告。

在實際工作環境中,可以將多個「product.triage」檔案保留在不同的目錄中,並透過「--config」指令列引數,指示 Triage 使用其中任何一個檔案。

測試和命名空間

測試只會使用發生測試的檔案內的指標,以及測試提供的值。使用「a::b」等命名空間限定值的運算式 (eval 或測試觸發事件),必須在測試值中使用「a::b」項目提供這些值。

test: {
    component_max_ok: {
        no: [
            "component_overflow",
        ],
        values: {
            actual_components: 17,
            "product::max_components": 17,
        },
    },
},

詳細資料

名稱

選取器、運算式、動作和測試的名稱 (以及設定檔的 base 名稱) 可以是任何英文字母或底線,後面可以接任意數量的英文字母、數字或底線。

以底線開頭的名稱在未來版本的 Triage 中可能具有特殊意義。雖然這類內容並未違規,但建議您避免使用。

每個 .triage 檔案的名稱會建立其命名空間。系統不允許從不同目錄載入兩個名稱相同的 .triage 檔案。

數學運算式

  • 變數可以是 64 位元浮點數、帶正負號的 64 位元整數或布林值。
  • 算術運算式會使用 + - * / // 運算子,並採用一般運算順序和運算優先順序。
  • 除法運算子 / 會產生浮點值。
  • 除法運算子 // 會產生 int 值,即使使用浮點值引數,也會將結果截斷為 0。(請注意,這與 Python 3 不同,在 Python 3 中,// 會向下截斷)。
  • + - * 保留運算元的類型 (混合升級為浮點)。
  • 比較運算子為 > >= < <= == !=
  • 比較運算的結果類型為布林值,可用於觸發動作。
  • 您可以在單一 eval 規則中結合運算和比較。
  • 您可以使用括號。
  • 您可以使用 evalselect 項目的鍵名稱做為變數。
  • 空格為選用項目,且可用於所有位置,但不得用於 filename::variable 命名空間變數中。

預先定義函式

Triage 提供可用於 eval 運算式的預先定義函式:

  • Max(value1, value2, value3...) 會傳回最大值,並將類型升級為浮點值。
  • Min(value1, value2, value3...) 會傳回最小值,並將類型升級為浮點值。
  • And(value1, value2, value3...) 會接受布林引數,並傳回值的邏輯 AND。
  • Or(value1, value2, value3...) 會接受布林值引數,並傳回值的邏輯 OR。
  • Not(value) 會採用一個布林引數,並傳回其邏輯 NOT。
  • 如果對應的記錄檔案含有與比對器相符的行 (比對器是包含規則運算式的字串),SyslogHas(matcher)KlogHas(matcher)BootlogHas(matcher) 會傳回 true。
  • Annotation(key) 會傳回 annotations.json 檔案中的對應值。
  • Option(value1, value2, value3...) 會傳回第一個實用值,以支援選取器遷移作業和預設值:第一個非空白清單、非遺漏值 (如果有);如果提供空白清單,則傳回空白清單;或傳回遺漏值。
  • 如果值是錯誤指示,Missing(value) 會傳回 true。
  • Days()Hours()Minutes()Seconds()Millis()Micros()Nanos() 會計算值,以便與單調時間戳記進行比較。
  • Now() 會傳回診斷資料建立時的近似時間戳記。
  • StringMatches(value, regex) 會將指定的規則運算式套用至指定的值,如果相符,則傳回 true。規則運算式語法是 Rust 規則運算式 crate 支援的語法。

功能式程式設計

Triage 可將函式套用至值的向量。向量格式為 "[expr, expr, expr...]"。部分選取器會傳回多元素向量。

Triage 提供 Map()Fold()Filter()Count() 函式,用於處理向量、Fn() 函式或 lambda 以便套用 Map、Fold 和 Filter,以及 Apply() 函式,用於將 Fn() 套用至引數。

詳情請參閱「設定 fx triage」。

其他資訊

如要瞭解最新功能和選項,請參閱 fx triage - Triage 會持續改善!