diff --git a/pkg/datasource/problems_alerting.go b/pkg/datasource/problems_alerting.go new file mode 100644 index 0000000..5abf02c --- /dev/null +++ b/pkg/datasource/problems_alerting.go @@ -0,0 +1,91 @@ +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) { + triggers, err := ds.zabbix.GetTriggers(ctx, query.Group.Filter, query.Host.Filter) + if err != nil { + return nil, err + } + + if len(triggers) == 0 { + return []*data.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 + } + + problemMap := buildProblemMap(problems) + currentTime := time.Now() + + frames := make([]*data.Frame, 0) + for _, trigger := range triggers { + for _, host := range trigger.Hosts { + value := 0.0 + if problemMap[trigger.ID] { + value = 1.0 + } + frame := createAlertingFrame(trigger, host, value, currentTime, query.RefID) + frames = append(frames, frame) + } + } + + return frames, nil +} + +func buildProblemMap(problems []zabbix.Problem) map[string]bool { + problemMap := make(map[string]bool) + for _, p := range problems { + problemMap[p.ObjectID] = true + } + return problemMap +} + +func createAlertingFrame(trigger zabbix.Trigger, host zabbix.ItemHost, value float64, ts time.Time, refID string) *data.Frame { + labels := data.Labels{ + "host": host.Name, + "trigger": trigger.Description, + "trigger_id": trigger.ID, + "severity": trigger.Priority, + "tags": formatTags(trigger.Tags), + } + + 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 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, ",") +}