繼續昨天的方向來聊
不只Dashboards可以變成document file.
連Datasources, alert都能.
這全部建立變成configuration file搭配自動化之後
就是所謂的Configuration As Code(CAC).
以下是參考連結內對於Configuration as code的一段解釋
Configuration as code
Configuration as code is the practice of storing the configuration of your system as a set of version controlled, human-readable configuration files, rather than in a database. These configuration files can be reused across environments to avoid duplicated resources.
Provisioning目前有支持
提供Provisioning程式碼連結, 有興趣能自己研究.
每一個裡面都有個types.go, 剛好會對應到CAC的yaml檔案.
Grafana有一隻ini設定檔, 裡面有一個區塊專門設定path的
我們可以定義provisioning的檔案都在哪個資料夾能找到
[paths]
provisioning = <path to config files>
該資料夾底下的folder layout也是有被規範的
provisioning/
datasources/
<yaml files>
dashboards/
<yaml files>
notifiers/
<yaml files>
plugins/
<yaml files>
alterting/
<yaml files>
第一行就是把ini檔設定的provision path, 跟datasources這資料夾名稱給合併起來, 才開始對其內容做讀取配置.
上述的每種類型都有一隻這樣的function做近乎一樣的流程.
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardProvisioningService, ps.SQLStore, ps.dashboardService)
if err != nil {
return fmt.Errorf("%v: %w", "Failed to create provisioner", err)
}
ps.mutex.Lock()
defer ps.mutex.Unlock()
ps.cancelPolling()
dashProvisioner.CleanUpOrphanedDashboards(ctx)
err = dashProvisioner.Provision(ctx)
if err != nil {
// If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the
// old provisioner as we did not switch them yet.
return fmt.Errorf("%v: %w", "Failed to provision dashboards", err)
}
ps.dashboardProvisioner = dashProvisioner
return nil
}
昨天有建立一隻demoDashboard.yaml, 放在provisioning/dashboards
, 每個這隻檔案內, 都有一串的dashbords providers
來讓Grafana在啟動時, 載入並配置.
下面是provisioning/dashboards yaml檔案layout.
# config file version
apiVersion: 1
providers:
# <string> an unique provider name. Required
- name: 'a unique provider name'
# <int> Org id. Default to 1
orgId: 1
# <string> name of the dashboard folder.
folder: ''
# <string> folder UID. will be automatically generated if not specified
folderUid: ''
# <string> provider type. Default to 'file'
type: file
# <bool> disable dashboard deletion
disableDeletion: false
# <int> how often Grafana will scan for changed dashboards
updateIntervalSeconds: 10
# <bool> allow updating provisioned dashboards from the UI
allowUiUpdates: false
options:
# <string, required> path to dashboard files on disk. Required when using the 'file' type
path: /var/lib/grafana/dashboards
# <bool> use folder names from filesystem to create folders in Grafana
foldersFromFilesStructure: true
name必須要唯一很重要,
orgId則是跟Grafana的組織有關連, 如果配置成2, 則只有2號組織能看到這Dashboard.
folder則是dashboard browse內的資料夾分類
allowUiUpdates如果是false, 則不能在WEB UI上直接修改, 會彈出下圖提示您, 該把這些json model, 給更新到dashboard.json內, 生產環境上建議這樣做!
foldersFromFilesStructure如果是true, 則會根據folder欄位給的值, 在dashboard browse上也建立對應的資料夾.
像我昨天的假如改成
provisioning/
dashboards/
dashboard.yml
demo/
dashboard.json
dashboard.yml, 則加上了folder:'demo'
apiVersion: 1
providers:
- name: 'Prometheus'
orgId: 1
folder: 'demo'
folderUid: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10
editable: true
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards # path to dashboard files on disk. Required when using the 'file' type
foldersFromFilesStructure: true
結果如下圖
其他的部份以後有機會在補充,
有的支援動態更新, 有的則是要觸發admin API來進行熱更新
Grafana在很短的時間內把很多設定內容都盡量的做成configuration file.
真的很厲害!
有了這些file, 基本上也很容易在各環境上快速佈署了.
Provision dashboards and data sources