起源
前六章中我們了解 Grafana 在視覺化處理的背後過程。還記得 Grafana Lab 是一個致力於開源的組織,因此他們非常鼓勵使用者以 plugin 的方式開發各種實用的工具,而通常這些工具最後都是以 dashboard 呈現,其中可能包含多頁面及多個 Panel 圖表。但許多高複雜的 plugin 功能開發讓社群上出現了一些挑戰,例如:
-
多資料源查詢的複雜性:
- 資料源在不同頁面上可能有顯示與隱藏不一的狀況。
- 查詢時可能會使用 Grafana 的預設轉換或自定義轉換,有時更需要結合兩者。
- 例如:一個監控系統可能需要同時從 Prometheus 獲取效能指標,從 Elasticsearch 獲取 Logs 數據,這增加了數據整合和展示的複雜度。
-
Panel 自定義的挑戰:
- 必須覆寫 Grafana Panel 以實現正確的自定義。
- 需要保持 Panel 位置、維持比例、優化查詢並建立可重用的響應式設計。
-
URL 管理與測試的困難:
- 在不同頁面之間傳遞和處理查詢參數。
- 與自定義路由、資料源參數和時間範圍選擇器的結合管理更加複雜。
- 實例:在一個大型 dashboard 中,使用者可能需要在不同的視圖之間切換,同時保持選定的時間範圍和過濾條件,這需要複雜的 URL 參數管理。
-
應用一致性問題:
- 儘管使用了 Grafana UI package,仍需耗費大量時間依賴自定義樣式來確保響應性。
Grafana UI
是一個基於 React 的前端元件庫,專為 Grafana 開發而設計,提供了一系列高維護及擴展性的 UI 元件,幫助開發者建立一致且響應迅速的使用者界面。包括表單控制項、圖表、面板、彈出視窗等,並與 Grafana 的設計風格無縫融合。
https://developers.grafana.com/ui/latest/index.html
Grafana Scenes 的誕生
基於以上的挑戰,Grafana Labs 的工程師們也發現很多既有且非常優秀的 Plugin 專案和 Grafana Dashboard 的架構及功能非常相似,且也有一些功能已經存在於 Grafana 的核心 Dashboard 中,只是還沒有一個簡單方便的方法讓使用者可以整合使用這些功能。因此包括 Bogdan Matei 和 Dominik Prokop 的工程師催生出了 Grafana Scenes 的 Plugin,並開始著手許多專案的舊架構,它的誕生帶來了顯著的效率提升:
- 僅用兩個工作日就將一個現有的 Plugin 專案遷移至 Scenes。
- 程式碼量減少了 50%。
- 上述所有挑戰都得到了有效解決。
Grafana Scenes 是什麼?
Grafana Scenes 是一個基於 React 的 TypeScript 前端庫,目標是讓開發者能夠更容易、更直觀地使用 API 來增強或擴展 Plugin 的功能。使用 Scenes 可以將模板變數、查詢與轉換、動態面板渲染、時間範圍、可視化和佈局,甚至是詳細資訊頁面(Drilldown page)和標籤頁面(Tab page)嵌入 Dashboard 中。
優勢
-
減少重複勞動:
常見的功能如變數支持或時間範圍管理由庫提供,讓開發者專注於應用的核心價值,而不必重新發明輪子。
-
為 Grafana 使用者提供熟悉的體驗:
使用 Scenes 的應用能夠與 Grafana 無縫整合,提供與核心 Grafana 產品一致的外觀和使用感受。所有的 UI 與 Layout 皆以 Grafana 主題開發,開發者不需再重新刻劃打造 CSS 樣式,可以使用套件提供的元件完成。
-
高自定義及擴展性:
承如第一章節中介紹,許多 Grafana 的外掛工具可能透過 Grafana Cloud 或 Enterprise 來限制使用者的用量或功能,所以可以透過 Scenes 的方式在自建的 Grafana 平台中以 Plugin 的方式建立相同的功能,因為 Scenes API 不僅提供核心功能,還可以進行擴展,也可以透過 Grafana 內部的 API 工具取得 datasource,再藉由 Scenes 進行查詢和轉換資料,最後形成可視化的圖表。
-
建立高複雜性的 Dashboard:
可以建立包含多功能的 Layout、可切換 tab 的頁面、多個 Time ranges、將查詢內容同步 URL 以更容易分享或檢視,乃至於可導向更多內容的詳細資訊頁面。
例如在一張 Dashboard 中建立『多個 Time Range』的功能已經是社群中長期以來的需求,但在一般的 Dashboard 中只能以 Dashboard 為主,使用單一個 Time Range。若使用 Scenes 建立則甚至可以為每個 Panel 建立各自的 time range 設定。
架構
下圖為一個 Scene 的資料流及元件功能架構,包含了 Scene 本身、Time range 和 Variables 可操控的元件、多功能的 Layout、呈現圖表內容的 panel、以及承包 datasource 的 Query runner:
- Scene : 這是整個架構的核心。它包含並管理時間範圍(Time range)和變量(Variables)。
- Layout:指設置和管理儀表板中各個面板和元素的佈局方式,提供靈活的佈局選項以實現響應式和可自定義的視覺化呈現。
- Table panel 和 Time series panel:具體可視化組件,分別由不同的資料來源所呈現的圖表。
- Query runner:負責從資料源取得資料。圖中顯示了兩個 Query runner,分別連接到 Postgres 和 Prometheus 資料源。
- Time range 和 Variables: 直接連接到 Scene 的組件,代表頂層共用的設定值。圖中兩條紅線從各自的 query runner 指向 Time range 和 Variables,表示 query runner 會自動遍歷 scenes graph,找到最相近的時間範圍 (time range) 上下文來執行查詢。如果找不到,則會直接使用頂層的共用設定值。
實現
一個 scene 是由一組物件組成,這些物件被稱為 scene objects,這些物件代表 scene 中的不同方面:資料、時間範圍、變數、佈局和可視化。scene objects 共同構成了一個物件樹 (object tree)。而且也因為每個物件會繼承自一個基礎的 Scene Object 類別,因此將這些物件分組和嵌套都是可行的,這讓開發者能夠更有條理地管理各個物件之間的關係。開發人員也可以依循著 scene objects 的規則及狀態,自己動手做出客製化的 Scene Object,打造出更符合使用者需求的體驗,甚至可以做出比原本的功能更進階的內容。
宣告式 API
下圖範例為一個建立一個 Scene 的程式碼,其中 Scenes API 用一種宣告式的方式(下圖框起的部分)來打造 Grafana 應用程式。這種方法的優點包括:
-
程式碼易讀性與可維護性:宣告式語法使程式碼結構更清晰,開發者能夠更輕鬆地理解和修改。
-
減少附加效應 (side effects):降低了不必要的狀態變化或副作用,確保程式在可預期的範圍內運作。
-
更容易進行單元測試:由於程式碼結構更為明確,分離關注點,測試變得更加簡單,可以針對不同的 scene objects 進行獨立測試,提升測試覆蓋率與準確性。
參考資料
https://grafana.com/events/grafanacon/2023/dynamic-dashboards-with-grafana-scenes/
https://grafana.com/blog/2023/08/03/new-in-grafana-10-grafana-scenes-for-building-dynamic-dashboarding-experiences/
筆者語錄
簡而言之,Grafana Scenes 就像是一個樂高積木組,讓開發者可以隨心所欲地組裝出各式各樣的監控儀表板。通過簡化常見的元件建置、提供一致的使用者體驗、支援高度自定義和擴展,以及能夠構建複雜的 Dashboard,Scenes 提高了開發效率。隨著 Grafana 生態系統的不斷發展,Scenes 的誕生為開發者提供更多工具和功能,以創建更加強大和使用者友好的數據視覺化解決方案。