Files
grafana-zabbix/pkg/datasource/problems_alerting.go
Wesley van Tilburg 3d70908285
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
Create Plugin Update / release (push) Has been cancelled
referit changes
2026-01-29 12:12:20 +00:00

126 lines
3.3 KiB
Go

package datasource
import (
"context"
"fmt"
"strings"
"time"
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
"github.com/grafana/grafana-plugin-sdk-go/data"
)
func (ds *ZabbixDatasourceInstance) queryProblemsAlerting(ctx context.Context, query *QueryModel) ([]*data.Frame, error) {
ds.logger.Info("queryProblemsAlerting called", "groupFilter", query.Group.Filter, "hostFilter", query.Host.Filter)
triggers, err := ds.zabbix.GetTriggers(ctx, query.Group.Filter, query.Host.Filter)
if err != nil {
ds.logger.Error("GetTriggers failed", "error", err)
return nil, err
}
ds.logger.Info("GetTriggers returned", "count", len(triggers))
if len(triggers) == 0 {
frame := data.NewFrame("No triggers found")
frame.RefID = query.RefID
return []*data.Frame{frame}, nil
}
triggerIDs := make([]string, len(triggers))
for i, t := range triggers {
triggerIDs[i] = t.ID
}
problems, err := ds.zabbix.GetProblems(ctx, triggerIDs)
if err != nil {
return nil, err
}
// Map trigger ID to problem (includes opdata captured at problem creation)
problemMap := buildProblemMap(problems)
currentTime := time.Now()
frames := make([]*data.Frame, 0)
for _, trigger := range triggers {
for _, host := range trigger.Hosts {
value := 0.0
problemName := ""
opdata := ""
if problem, hasProblem := problemMap[trigger.ID]; hasProblem {
value = 1.0
problemName = problem.Name // Expanded trigger description at problem creation
opdata = problem.Opdata // Operational data if configured
}
frame := createAlertingFrame(trigger, host, value, problemName, opdata, currentTime, query.RefID)
frames = append(frames, frame)
}
}
return frames, nil
}
// buildProblemMap returns a map of trigger ID to Problem object
func buildProblemMap(problems []zabbix.Problem) map[string]zabbix.Problem {
problemMap := make(map[string]zabbix.Problem)
for _, p := range problems {
problemMap[p.ObjectID] = p
}
return problemMap
}
func createAlertingFrame(trigger zabbix.Trigger, host zabbix.ItemHost, value float64, problemName string, opdata string, ts time.Time, refID string) *data.Frame {
labels := data.Labels{
"host": host.Name,
"trigger": trigger.Description,
"trigger_id": trigger.ID,
"severity": mapSeverity(trigger.Priority),
"tags": formatTags(trigger.Tags),
"problem_name": problemName, // Expanded trigger description at problem creation
"opdata": opdata, // Operational data if configured on trigger
}
timeField := data.NewField("time", nil, []time.Time{ts})
valueField := data.NewField("value", labels, []float64{value})
frameName := fmt.Sprintf("%s: %s", host.Name, trigger.Description)
frame := data.NewFrame(frameName, timeField, valueField)
frame.RefID = refID
return frame
}
func mapSeverity(priority string) string {
switch priority {
case "0":
return "Not classified"
case "1":
return "Information"
case "2":
return "Warning"
case "3":
return "Average"
case "4":
return "High"
case "5":
return "Disaster"
default:
return priority
}
}
func formatTags(tags []zabbix.Tag) string {
if len(tags) == 0 {
return ""
}
parts := make([]string, len(tags))
for i, t := range tags {
if t.Value != "" {
parts[i] = fmt.Sprintf("%s:%s", t.Tag, t.Value)
} else {
parts[i] = t.Tag
}
}
return strings.Join(parts, ",")
}