github.com/google/cadvisor@v0.49.1/collector/collector_manager.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package collector 16 17 import ( 18 "fmt" 19 "strings" 20 "time" 21 22 v1 "github.com/google/cadvisor/info/v1" 23 ) 24 25 const metricLabelPrefix = "io.cadvisor.metric." 26 27 type GenericCollectorManager struct { 28 Collectors []*collectorData 29 NextCollectionTime time.Time 30 } 31 32 type collectorData struct { 33 collector Collector 34 nextCollectionTime time.Time 35 } 36 37 // Returns a new CollectorManager that is thread-compatible. 38 func NewCollectorManager() (CollectorManager, error) { 39 return &GenericCollectorManager{ 40 Collectors: []*collectorData{}, 41 NextCollectionTime: time.Now(), 42 }, nil 43 } 44 45 func GetCollectorConfigs(labels map[string]string) map[string]string { 46 configs := map[string]string{} 47 for k, v := range labels { 48 if strings.HasPrefix(k, metricLabelPrefix) { 49 name := strings.TrimPrefix(k, metricLabelPrefix) 50 configs[name] = v 51 } 52 } 53 return configs 54 } 55 56 func (cm *GenericCollectorManager) RegisterCollector(collector Collector) error { 57 cm.Collectors = append(cm.Collectors, &collectorData{ 58 collector: collector, 59 nextCollectionTime: time.Now(), 60 }) 61 return nil 62 } 63 64 func (cm *GenericCollectorManager) GetSpec() ([]v1.MetricSpec, error) { 65 metricSpec := []v1.MetricSpec{} 66 for _, c := range cm.Collectors { 67 specs := c.collector.GetSpec() 68 metricSpec = append(metricSpec, specs...) 69 } 70 71 return metricSpec, nil 72 } 73 74 func (cm *GenericCollectorManager) Collect() (time.Time, map[string][]v1.MetricVal, error) { 75 var errors []error 76 77 // Collect from all collectors that are ready. 78 var next time.Time 79 metrics := map[string][]v1.MetricVal{} 80 for _, c := range cm.Collectors { 81 if c.nextCollectionTime.Before(time.Now()) { 82 var err error 83 c.nextCollectionTime, metrics, err = c.collector.Collect(metrics) 84 if err != nil { 85 errors = append(errors, err) 86 } 87 } 88 89 // Keep track of the next collector that will be ready. 90 if next.IsZero() || next.After(c.nextCollectionTime) { 91 next = c.nextCollectionTime 92 } 93 } 94 cm.NextCollectionTime = next 95 return next, metrics, compileErrors(errors) 96 } 97 98 // Make an error slice into a single error. 99 func compileErrors(errors []error) error { 100 if len(errors) == 0 { 101 return nil 102 } 103 104 res := make([]string, len(errors)) 105 for i := range errors { 106 res[i] = fmt.Sprintf("Error %d: %v", i, errors[i].Error()) 107 } 108 return fmt.Errorf("%s", strings.Join(res, ",")) 109 }