grafana_gen/template_validator.go

144 lines
4.7 KiB
Go
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import "log"
// validateAndFixTemplate проверяет критичные настройки шаблона и исправляет их если нужно.
// Вызывается после loadTemplate чтобы гарантировать корректность шаблона независимо от его источника.
func validateAndFixTemplate(t *DashboardTemplate) {
fixed := 0
// --- vl_interval для панелей с агрегацией ---
vlIntervalPanels := []string{"rps", "rps_multi", "status_codes", "response_time", "traffic_combined", "traffic_combined_total"}
for _, key := range vlIntervalPanels {
p, ok := t.Panels[key]
if !ok {
continue
}
pm, ok := p.(map[string]interface{})
if !ok {
continue
}
if v, _ := pm["vl_interval"].(string); v == "" {
pm["vl_interval"] = "1m"
log.Printf("[template-validator] Fixed: panels.%s.vl_interval = \"1m\"", key)
fixed++
}
}
// --- spanNulls для status_codes ---
if p, ok := t.Panels["status_codes"]; ok {
if pm, ok := p.(map[string]interface{}); ok {
if fc, ok := pm["fieldConfig"].(map[string]interface{}); ok {
if defaults, ok := fc["defaults"].(map[string]interface{}); ok {
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
if v, _ := custom["spanNulls"].(bool); !v {
custom["spanNulls"] = true
log.Printf("[template-validator] Fixed: panels.status_codes.fieldConfig.defaults.custom.spanNulls = true")
fixed++
}
}
}
}
}
}
// --- vl_base_query для overview_tenant_per_nodes ---
checkOverviewVLQuery(t, "overview_tenant_per_nodes",
"log_type:access TENANT:in(${tenant:csv})",
"log_type:access AND TENANT:${tenant:lucene}",
&fixed,
)
// --- vl_base_query для overview_tenant_per_node ---
checkOverviewVLQuery(t, "overview_tenant_per_node",
"log_type:access node_name:in(${node_name:csv})",
"log_type:access AND node_name:${node_name:lucene}",
&fixed,
)
// --- layout: три столбца ---
checkLayout(t, &fixed)
if fixed > 0 {
log.Printf("[template-validator] Total fixes applied: %d", fixed)
} else {
log.Printf("[template-validator] Template OK, no fixes needed")
}
}
func checkOverviewVLQuery(t *DashboardTemplate, panelKey, expectedVL, expectedOS string, fixed *int) {
p, ok := t.Panels[panelKey]
if !ok {
return
}
pm, ok := p.(map[string]interface{})
if !ok {
return
}
qc, ok := pm["query_config"].(map[string]interface{})
if !ok {
return
}
if v, _ := qc["vl_base_query"].(string); v == "" {
qc["vl_base_query"] = expectedVL
log.Printf("[template-validator] Fixed: panels.%s.query_config.vl_base_query", panelKey)
(*fixed)++
}
if v, _ := qc["base_query"].(string); v == "log_type:access" {
qc["base_query"] = expectedOS
log.Printf("[template-validator] Fixed: panels.%s.query_config.base_query", panelKey)
(*fixed)++
}
}
func checkLayout(t *DashboardTemplate, fixed *int) {
// Проверяем что tenant_panels имеет три столбца по 8
tenantPanels := t.Layout.TenantPanels
hasTraffic := false
wrongWidth := false
for _, p := range tenantPanels {
if p.PanelKey == "traffic_combined_total" {
hasTraffic = true
}
if p.Width == 12 {
wrongWidth = true
}
}
if !hasTraffic || wrongWidth {
log.Printf("[template-validator] Fixed: layout.tenant_panels restored to 3-column (8+8+8)")
t.Layout.TenantPanels = []PanelLayout{
{PanelKey: "status_codes", TitleFormat: "Status Codes {client}", Width: 8, XOffset: 0},
{PanelKey: "rps", TitleFormat: "RPS {client}", Width: 8, XOffset: 8,
Condition: &PanelCondition{Type: "max_domains", Value: 1}},
{PanelKey: "rps_multi", TitleFormat: "RPS {client}", Width: 8, XOffset: 8,
Condition: &PanelCondition{Type: "min_domains", Value: 2}},
{PanelKey: "traffic_combined_total", TitleFormat: "Total Traffic {client}", Width: 8, XOffset: 16,
Condition: &PanelCondition{Type: "min_domains", Value: 1}},
}
(*fixed)++
}
// Проверяем domain_panels
domainPanels := t.Layout.DomainPanels
hasDomainTraffic := false
domainWrongWidth := false
for _, p := range domainPanels {
if p.PanelKey == "traffic_combined" {
hasDomainTraffic = true
}
if p.Width == 12 {
domainWrongWidth = true
}
}
if !hasDomainTraffic || domainWrongWidth {
log.Printf("[template-validator] Fixed: layout.domain_panels restored to 3-column (8+8+8)")
t.Layout.DomainPanels = []PanelLayout{
{PanelKey: "status_codes", TitleSuffix: "{sid} Status Codes", Width: 8, XOffset: 0},
{PanelKey: "response_time", TitleSuffix: "{sid} Response Time", Width: 8, XOffset: 8},
{PanelKey: "traffic_combined", TitleFormat: "{domain} {sid} Traffic", Width: 8, XOffset: 16},
}
(*fixed)++
}
}