diff --git a/cmd/collectors/zapi/plugins/shelf/shelf.go b/cmd/collectors/zapi/plugins/shelf/shelf.go index 82d0ba319..5cb527f46 100644 --- a/cmd/collectors/zapi/plugins/shelf/shelf.go +++ b/cmd/collectors/zapi/plugins/shelf/shelf.go @@ -17,12 +17,21 @@ const BatchSize = "500" type Shelf struct { *plugin.AbstractPlugin - data map[string]*matrix.Matrix - instanceKeys map[string]string - instanceLabels map[string]*dict.Dict - batchSize string - client *zapi.Client - query string + data map[string]*matrix.Matrix + shelfData *matrix.Matrix + instanceKeys map[string]string + instanceLabels map[string]*dict.Dict + shelfInstanceKeys []string + shelfInstanceLabels []shelfInstanceLabel + batchSize string + client *zapi.Client + query string +} + +type shelfInstanceLabel struct { + label string + labelDisplay string + parent string } func New(p *plugin.AbstractPlugin) plugin.Plugin { @@ -38,7 +47,7 @@ func (my *Shelf) Init() error { } if my.client, err = zapi.New(conf.ZapiPoller(my.ParentParams), my.Auth); err != nil { - my.Logger.Error().Stack().Err(err).Msg("connecting") + my.Logger.Error().Err(err).Msg("connecting") return err } @@ -50,6 +59,8 @@ func (my *Shelf) Init() error { my.Logger.Debug().Msg("plugin connected!") + my.create7ModeShelfMetrics() + my.data = make(map[string]*matrix.Matrix) my.instanceKeys = make(map[string]string) my.instanceLabels = make(map[string]*dict.Dict) @@ -102,7 +113,7 @@ func (my *Shelf) Init() error { case "float": _, err := my.data[attribute].NewMetricFloat64(metricName, display) if err != nil { - my.Logger.Error().Stack().Err(err).Msg("add metric") + my.Logger.Error().Err(err).Msg("add metric") return err } my.Logger.Debug().Msgf("added metric: (%s) (%s) [%s]", attribute, x.GetNameS(), display) @@ -110,12 +121,12 @@ func (my *Shelf) Init() error { } } - my.Logger.Debug().Msgf("added data for [%s] with %d metrics", attribute, len(my.data[attribute].GetMetrics())) + my.Logger.Debug().Str("attribute", attribute).Int("metrics count", len(my.data[attribute].GetMetrics())).Msg("added") my.data[attribute].SetExportOptions(exportOptions) } - my.Logger.Debug().Msgf("initialized with data [%d] objects", len(my.data)) + my.Logger.Debug().Int("objects count", len(my.data)).Msg("initialized") // setup batchSize for request my.batchSize = BatchSize @@ -154,16 +165,18 @@ func (my *Shelf) Run(dataMap map[string]*matrix.Matrix) ([]*matrix.Matrix, error return nil, err } - output, err = my.handle7Mode(result) + output, err = my.handle7Mode(data, result) if err != nil { return output, err } + my.Logger.Debug().Int("Shelves instance count", len(my.shelfData.GetInstances())).Send() + output = append(output, my.shelfData) return output, nil } -func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { +func (my *Shelf) handle7Mode(data *matrix.Matrix, result []*node.Node) ([]*matrix.Matrix, error) { var ( shelves []*node.Node channels []*node.Node @@ -189,6 +202,15 @@ func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { data1.Reset() } + // Purge and reset data + my.shelfData.PurgeInstances() + my.shelfData.Reset() + + my.shelfData.SetGlobalLabels(data.GetGlobalLabels()) + for _, instance := range data.GetInstances() { + instance.SetExportable(false) + } + for _, channel := range channels { channelName := channel.GetChildContentS("channel-name") shelves = channel.SearchChildren([]string{"shelf-environ-shelf-list", "shelf-environ-shelf-info"}) @@ -199,11 +221,43 @@ func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { } for _, shelf := range shelves { - uid := shelf.GetChildContentS("shelf-id") shelfName := uid // no shelf name in 7mode shelfID := uid + shelfInstanceKey := shelfID + "." + channelName + newShelfInstance, err := my.shelfData.NewInstance(shelfInstanceKey) + if err != nil { + my.Logger.Error().Err(err).Msg("Error while creating shelf instance") + return nil, err + } + + for _, key := range my.shelfInstanceKeys { + newShelfInstance.SetLabel(key, shelf.GetChildContentS(key)) + } + for _, shelfLabelData := range my.shelfInstanceLabels { + if shelfLabelData.parent == "" { + newShelfInstance.SetLabel(shelfLabelData.labelDisplay, shelf.GetChildContentS(shelfLabelData.label)) + } else { + child := shelf.GetChildS(shelfLabelData.parent) + newShelfInstance.SetLabel(shelfLabelData.labelDisplay, child.GetChildContentS(shelfLabelData.label)) + } + } + + newShelfInstance.SetLabel("channel", channelName) + newShelfInstance.SetLabel("shelf", newShelfInstance.GetLabel("shelf_id")) + + // populate numeric data + for metricKey, m := range my.shelfData.GetMetrics() { + if value := strings.Split(shelf.GetChildContentS(metricKey), " ")[0]; value != "" { + if err := m.SetValueString(newShelfInstance, value); err != nil { + my.Logger.Debug().Str("metricKey", metricKey).Str("value", value).Err(err).Msg("failed to parse") + } else { + my.Logger.Debug().Str("metricKey", metricKey).Str("value", value).Msg("added") + } + } + } + for attribute, data1 := range my.data { if statusMetric := data1.GetMetric("status"); statusMetric != nil { @@ -252,7 +306,6 @@ func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { // populate numeric data for metricKey, m := range data1.GetMetrics() { - if value := strings.Split(obj.GetChildContentS(metricKey), " ")[0]; value != "" { if err := m.SetValueString(instance, value); err != nil { my.Logger.Debug().Msgf("(%s) failed to parse value (%s): %v", metricKey, value, err) @@ -261,7 +314,6 @@ func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { } } } - } else { my.Logger.Debug().Msgf("instance without [%s], skipping", my.instanceKeys[attribute]) } @@ -274,3 +326,53 @@ func (my *Shelf) handle7Mode(result []*node.Node) ([]*matrix.Matrix, error) { } return output, nil } + +func (my *Shelf) create7ModeShelfMetrics() { + my.shelfData = matrix.New(my.Parent+".Shelf", "shelf", "shelf") + my.shelfInstanceKeys = make([]string, 0) + my.shelfInstanceLabels = []shelfInstanceLabel{} + shelfExportOptions := node.NewS("export_options") + shelfInstanceKeys := shelfExportOptions.NewChildS("instance_keys", "") + shelfInstanceLabels := shelfExportOptions.NewChildS("instance_labels", "") + + if counters := my.ParentParams.GetChildS("counters"); counters != nil { + if channelInfo := counters.GetChildS("shelf-environ-channel-info"); channelInfo != nil { + if shelfList := channelInfo.GetChildS("shelf-environ-shelf-list"); shelfList != nil { + if shelfInfo := shelfList.GetChildS("shelf-environ-shelf-info"); shelfInfo != nil { + my.parse7ModeTemplate(shelfInfo, shelfInstanceKeys, shelfInstanceLabels, "") + } + } + } + } + + shelfInstanceKeys.NewChildS("", "channel") + shelfInstanceKeys.NewChildS("", "shelf") + my.shelfData.SetExportOptions(shelfExportOptions) +} + +func (my *Shelf) parse7ModeTemplate(shelfInfo *node.Node, shelfInstanceKeys, shelfInstanceLabels *node.Node, parent string) { + for _, shelfProp := range shelfInfo.GetChildren() { + if len(shelfProp.GetChildren()) > 0 { + my.parse7ModeTemplate(shelfInfo.GetChildS(shelfProp.GetNameS()), shelfInstanceKeys, shelfInstanceLabels, shelfProp.GetNameS()) + } else { + metricName, display, kind, _ := util.ParseMetric(shelfProp.GetContentS()) + switch kind { + case "key": + my.shelfInstanceKeys = append(my.shelfInstanceKeys, metricName) + my.shelfInstanceLabels = append(my.shelfInstanceLabels, shelfInstanceLabel{label: metricName, labelDisplay: display, parent: parent}) + shelfInstanceKeys.NewChildS("", display) + my.Logger.Debug().Str("instance key", display).Msg("added") + case "label": + my.shelfInstanceLabels = append(my.shelfInstanceLabels, shelfInstanceLabel{label: metricName, labelDisplay: display, parent: parent}) + shelfInstanceLabels.NewChildS("", display) + my.Logger.Debug().Str("instance label", display).Msg("added") + case "float": + _, err := my.shelfData.NewMetricFloat64(metricName, display) + if err != nil { + my.Logger.Error().Err(err).Msg("add metric") + } + my.Logger.Debug().Str("metric", display).Msg("added") + } + } + } +}