diff --git a/config.go b/config.go index 03d5723..57e6b1f 100644 --- a/config.go +++ b/config.go @@ -151,6 +151,8 @@ type LayoutConfig struct { UseCollapsedRows bool `json:"use_collapsed_rows"` OverviewPanels []PanelLayout `json:"overview_panels"` // Панели обзора перед клиентскими строками OverviewRowTitle string `json:"overview_row_title"` // Заголовок collapsed row обзора + ErrorPanels []PanelLayout `json:"error_panels"` // Панели ошибок (только VL) + ErrorRowTitle string `json:"error_row_title"` // Заголовок collapsed row ошибок } type PanelLayout struct { diff --git a/dashboard_vl.go b/dashboard_vl.go index f185b03..16d0baf 100644 --- a/dashboard_vl.go +++ b/dashboard_vl.go @@ -25,6 +25,13 @@ func generateVLDashboard(clients map[string]ClientData, template *DashboardTempl yPos++ } + if len(template.Layout.ErrorPanels) > 0 { + errorsRow := createErrorRowVL(template, datasourceType, datasourceUID, panelID, yPos) + panels = append(panels, errorsRow) + panelID += 10 + yPos++ + } + for _, client := range clients { if len(client.Domains) == 0 { continue @@ -225,6 +232,19 @@ func buildPanelVL( panel["title"] = formatPanelTitle(title, client, domain) } + // Для rps панелей убираем суффикс " rps" из названий серий + if queryMode == "rps" || queryMode == "rps_multi" || queryMode == "rps_var" { + panel["transformations"] = []interface{}{ + map[string]interface{}{ + "id": "renameByRegex", + "options": map[string]interface{}{ + "regex": "^(.+) rps$", + "renamePattern": "", + }, + }, + } + } + // Для range_percent добавляем transformation которая убирает " count(*)" из названий серий if queryMode == "range_percent" { panel["transformations"] = []interface{}{ @@ -394,3 +414,41 @@ func sendVLDashboardToGrafana(dashboard map[string]interface{}, config Config) e // Используем тот же sendToGrafana return sendToGrafana(dashboard, vlConfig) } + +// createErrorRowVL создаёт collapsed row с панелями ошибок (только для VL). +func createErrorRowVL(template *DashboardTemplate, datasourceType, datasourceUID string, panelID, yPos int) map[string]interface{} { + innerPanels := []interface{}{} + currentY := 1 + dummyClient := ClientData{} + + for _, layout := range template.Layout.ErrorPanels { + width := layout.Width + if width == 0 { + width = 24 + } + panel := buildPanelVL(layout.PanelKey, template, DomainInfo{}, dummyClient, datasourceType, datasourceUID, panelID, currentY, layout.XOffset, width) + if panel == nil { + continue + } + if layout.TitleFormat != "" { + panel["title"] = layout.TitleFormat + } + innerPanels = append(innerPanels, panel) + panelID++ + currentY += getGridH(panel) + } + + rowTitle := template.Layout.ErrorRowTitle + if rowTitle == "" { + rowTitle = "Errors" + } + + return map[string]interface{}{ + "type": "row", + "title": rowTitle, + "id": panelID, + "collapsed": true, + "gridPos": map[string]interface{}{"h": 1, "w": 24, "x": 0, "y": yPos}, + "panels": innerPanels, + } +}