package collector import ( "fmt" "strings" "time" "k8s.io/apimachinery/pkg/api/resource" ) // MaxWeightedCollector is a simple aggregator collector that returns the maximum value // of metrics from all collectors. type MaxWeightedCollector struct { collectors []Collector interval time.Duration weight float64 } // NewMaxWeightedCollector initializes a new MaxWeightedCollector. func NewMaxWeightedCollector(interval time.Duration, weight float64, collectors ...Collector) *MaxWeightedCollector { return &MaxWeightedCollector{ collectors: collectors, interval: interval, weight: weight, } } // GetMetrics gets metrics from all collectors and return the higest value. func (c *MaxWeightedCollector) GetMetrics() ([]CollectedMetric, error) { errors := make([]error, 0) collectedMetrics := make([]CollectedMetric, 0) for _, collector := range c.collectors { values, err := collector.GetMetrics() if err != nil { if _, ok := err.(NoResultError); ok { errors = append(errors, err) continue } return nil, err } collectedMetrics = append(collectedMetrics, values...) } if len(collectedMetrics) == 0 { if len(errors) == 0 { return nil, fmt.Errorf("no metrics collected, cannot determine max") } errorStrings := make([]string, len(errors)) for i, e := range errors { errorStrings[i] = e.Error() } allErrors := strings.Join(errorStrings, ",") return nil, fmt.Errorf("could not determine maximum due to errors: %s", allErrors) } max := collectedMetrics[0] for _, value := range collectedMetrics { if value.Custom.Value.MilliValue() > max.Custom.Value.MilliValue() { max = value } } max.Custom.Value = *resource.NewMilliQuantity(int64(c.weight*float64(max.Custom.Value.MilliValue())), resource.DecimalSI) return []CollectedMetric{max}, nil } // Interval returns the interval at which the collector should run. func (c *MaxWeightedCollector) Interval() time.Duration { return c.interval }