scraper.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package scrape
  2. import (
  3. "github.com/opencost/opencost/modules/collector-source/pkg/metric"
  4. )
  5. type Scraper interface {
  6. // Scrape performs the metrics scrape and returns a slice of `Update` instances to apply.
  7. Scrape() []metric.Update
  8. }
  9. // MetricFilter is a set of metric names to suppress from scrape output.
  10. // An empty or nil filter allows all metrics through.
  11. type MetricFilter map[string]struct{}
  12. // filteredScraper wraps a Scraper and removes any Update whose Name appears in the filter.
  13. type filteredScraper struct {
  14. inner Scraper
  15. filter MetricFilter
  16. }
  17. // withFilter returns s wrapped with f so that denied metric names are stripped from Scrape output.
  18. // If f is empty, s is returned unchanged.
  19. func withFilter(s Scraper, f MetricFilter) Scraper {
  20. if len(f) == 0 {
  21. return s
  22. }
  23. return &filteredScraper{inner: s, filter: f}
  24. }
  25. func (fs *filteredScraper) Scrape() []metric.Update {
  26. results := fs.inner.Scrape()
  27. out := results[:0]
  28. for _, u := range results {
  29. if _, denied := fs.filter[u.Name]; !denied {
  30. out = append(out, u)
  31. }
  32. }
  33. return out
  34. }
  35. type ScrapeFunc func() []metric.Update
  36. func concurrentScrape(scrapeFuncs ...ScrapeFunc) []metric.Update {
  37. resultCh := make(chan []metric.Update)
  38. defer close(resultCh)
  39. for _, scrapeFunc := range scrapeFuncs {
  40. go func() {
  41. scrapeResults := scrapeFunc()
  42. resultCh <- scrapeResults
  43. }()
  44. }
  45. var scrapeResults []metric.Update
  46. for range scrapeFuncs {
  47. targetResults := <-resultCh
  48. scrapeResults = append(scrapeResults, targetResults...)
  49. }
  50. return scrapeResults
  51. }