memory_scraper.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package memoryscraper // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/memoryscraper"
  4. import (
  5. "context"
  6. "errors"
  7. "fmt"
  8. "time"
  9. "github.com/shirou/gopsutil/v3/common"
  10. "github.com/shirou/gopsutil/v3/host"
  11. "github.com/shirou/gopsutil/v3/mem"
  12. "go.opentelemetry.io/collector/component"
  13. "go.opentelemetry.io/collector/pdata/pcommon"
  14. "go.opentelemetry.io/collector/pdata/pmetric"
  15. "go.opentelemetry.io/collector/receiver"
  16. "go.opentelemetry.io/collector/receiver/scrapererror"
  17. "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata"
  18. )
  19. const metricsLen = 2
  20. var ErrInvalidTotalMem = errors.New("invalid total memory")
  21. // scraper for Memory Metrics
  22. type scraper struct {
  23. settings receiver.CreateSettings
  24. config *Config
  25. mb *metadata.MetricsBuilder
  26. envMap common.EnvMap
  27. // for mocking gopsutil mem.VirtualMemory
  28. bootTime func(context.Context) (uint64, error)
  29. virtualMemory func(context.Context) (*mem.VirtualMemoryStat, error)
  30. }
  31. // newMemoryScraper creates a Memory Scraper
  32. func newMemoryScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) *scraper {
  33. return &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, virtualMemory: mem.VirtualMemoryWithContext}
  34. }
  35. func (s *scraper) start(ctx context.Context, _ component.Host) error {
  36. ctx = context.WithValue(ctx, common.EnvKey, s.envMap)
  37. bootTime, err := s.bootTime(ctx)
  38. if err != nil {
  39. return err
  40. }
  41. s.mb = metadata.NewMetricsBuilder(s.config.MetricsBuilderConfig, s.settings, metadata.WithStartTime(pcommon.Timestamp(bootTime*1e9)))
  42. return nil
  43. }
  44. func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
  45. ctx = context.WithValue(ctx, common.EnvKey, s.envMap)
  46. now := pcommon.NewTimestampFromTime(time.Now())
  47. memInfo, err := s.virtualMemory(ctx)
  48. if err != nil {
  49. return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen)
  50. }
  51. if memInfo != nil {
  52. s.recordMemoryUsageMetric(now, memInfo)
  53. if memInfo.Total <= 0 {
  54. return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(fmt.Errorf("%w: %d", ErrInvalidTotalMem,
  55. memInfo.Total), metricsLen)
  56. }
  57. s.recordMemoryUtilizationMetric(now, memInfo)
  58. s.recordSystemSpecificMetrics(now, memInfo)
  59. }
  60. return s.mb.Emit(), nil
  61. }