Selenium Grid 的可觀察性
目錄
Selenium Grid
Grid 透過在各種瀏覽器和作業系統組合上執行測試,協助擴展和分發測試。
可觀察性
可觀察性有三個支柱:追蹤、指標和日誌。由於 Selenium Grid 4 設計為完全分散式,可觀察性將使其更容易理解和偵錯內部運作。
分散式追蹤
單一請求或交易跨越多個服務和組件。追蹤會追蹤請求生命週期,因為每個服務都會執行請求。這在錯誤情境中對於偵錯很有用。在追蹤上下文中使用的部分關鍵術語為
追蹤 (Trace) 追蹤允許使用者追蹤請求通過多個服務,從其來源到最終目的地。此請求的旅程有助於偵錯、監控端對端流程,並識別失敗。追蹤描繪了端對端請求流程。每個追蹤都有一個唯一的 ID 作為其識別符。
跨度 (Span) 每個追蹤都由稱為跨度的計時操作組成。跨度具有開始和結束時間,它代表服務完成的操作。跨度的粒度取決於它的檢測方式。每個跨度都有一個唯一識別符。追蹤內的所有跨度都具有相同的追蹤 ID。
跨度屬性 (Span Attributes) 跨度屬性是鍵值對,提供關於每個跨度的額外資訊。
事件 (Events) 事件是跨度內的時間戳記日誌。它們為現有跨度提供額外上下文。事件也包含鍵值對作為事件屬性。
事件日誌記錄
日誌記錄對於偵錯應用程式至關重要。日誌記錄通常以人類可讀的格式完成。但是為了讓機器搜尋和分析日誌,它必須具有明確定義的格式。結構化日誌記錄是一種以固定格式一致記錄日誌的常見做法。它通常包含如下欄位
- 時間戳記
- 日誌記錄層級
- 日誌記錄器類別
- 日誌訊息 (這進一步分解為與記錄日誌的操作相關的欄位)
日誌和事件密切相關。事件封裝了所有可用資訊以完成單一工作單元。日誌本質上是事件的子集。在核心上,兩者都有助於偵錯。有關詳細理解,請參考以下資源
- https://www.honeycomb.io/blog/how-are-structured-logs-different-from-events/
- https://charity.wtf/2019/02/05/logs-vs-structured-events/
Grid 可觀察性
Selenium 伺服器使用 OpenTelemetry 進行追蹤檢測。每個對伺服器的請求都會從開始到結束進行追蹤。每個追蹤都由一系列跨度組成,因為請求在伺服器內執行。Selenium 伺服器中的大多數跨度都包含兩個事件
- 正常事件 - 記錄關於工作單元的所有資訊,並標記工作成功完成。
- 錯誤事件 - 記錄直到錯誤發生前的所有資訊,然後記錄錯誤資訊。標記例外事件。
執行 Selenium 伺服器
視覺化追蹤
所有跨度、事件及其各自的屬性都是追蹤的一部分。在上述所有模式下執行伺服器時,追蹤都有效。
預設情況下,Selenium 伺服器中已啟用追蹤。Selenium 伺服器通過兩個匯出器匯出追蹤
- Console - 在 FINE 層級記錄所有追蹤及其包含的跨度。預設情況下,Selenium 伺服器以 INFO 層級及以上層級列印日誌。**log-level** 標誌可用於在執行 Selenium Grid jar/s 時傳遞選擇的日誌記錄層級。
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
- Jaeger UI - OpenTelemetry 提供 API 和 SDK 在程式碼中檢測追蹤。而 Jaeger 是一個追蹤後端,有助於收集追蹤遙測資料,並為資料提供查詢、篩選和視覺化功能。
透過執行命令可以獲得使用 Jaeger UI 視覺化追蹤的詳細說明
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
一個非常好的範例和腳本來執行伺服器並將追蹤發送到 Jaeger
利用事件日誌
即使不希望匯出追蹤以進行視覺化,也必須啟用追蹤以進行事件日誌記錄。
**預設情況下,追蹤已啟用。無需傳遞額外參數即可在控制台上看到日誌。** 跨度內的所有事件都記錄在 FINE 層級。錯誤事件記錄在 WARN 層級。
所有事件日誌都具有以下欄位
欄位 | 欄位值 | 描述 |
---|---|---|
事件時間 | eventId | 事件記錄在 epoch 奈秒中的時間戳記。 |
追蹤 ID | tracedId | 每個追蹤都由追蹤 ID 唯一識別。 |
跨度 ID | spanId | 追蹤內的每個跨度都由跨度 ID 唯一識別。 |
跨度種類 | spanKind | 跨度種類是跨度的屬性,指示跨度的類型。它有助於理解跨度完成的工作單元的性質。 |
事件名稱 | eventName | 這對應於日誌訊息。 |
事件屬性 | eventAttributes | 這構成了事件日誌的核心,基於執行的操作,它具有 JSON 格式的鍵值對。這也包括處理常式類別屬性,以顯示日誌記錄器類別。 |
範例日誌
FINE [LoggingOptions$1.lambda$export$1] - {
"traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
"spanId": "b7d3b9865d3ddd45",
"spanKind": "INTERNAL",
"eventTime": 1597819675128886121,
"eventName": "Session request execution complete",
"attributes": {
"http.status_code": 200,
"http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
"http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
"http.method": "DELETE",
"session.id": "dd35257f104bb43fdfb06242953f4c85"
}
}
除了上述欄位外,根據 OpenTelemetry 規範,錯誤日誌包含
欄位 | 欄位值 | 描述 |
---|---|---|
例外類型 | exception.type | 例外的類別名稱。 |
例外訊息 | exception.message | 例外的原因。 |
例外堆疊追蹤 | exception.stacktrace | 列印拋出例外時的呼叫堆疊。有助於理解例外的來源。 |
範例錯誤日誌
WARN [LoggingOptions$1.lambda$export$1] - {
"traceId": "7efa5ea57e02f89cdf8de586fe09f564",
"spanId": "914df6bc9a1f6e2b",
"spanKind": "INTERNAL",
"eventTime": 1597820253450580272,
"eventName": "exception",
"attributes": {
"exception.type": "org.openqa.selenium.ScriptTimeoutException",
"exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
"exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
"http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
"http.url": "\u002fsession",
"http.method": "POST"
}
}
注意:上面的日誌為了可讀性而進行了美化列印。Selenium 伺服器中關閉了日誌的美化列印。
上述步驟應設定您查看追蹤和日誌。