github.com/kaydxh/golang@v0.0.131/pkg/monitor/opentelemetry/resource/resource.stats.go (about) 1 package resource 2 3 import ( 4 "context" 5 "fmt" 6 "sync" 7 "sync/atomic" 8 "time" 9 10 "github.com/kaydxh/golang/go/errors" 11 time_ "github.com/kaydxh/golang/go/time" 12 "github.com/sirupsen/logrus" 13 ) 14 15 const ( 16 DefaultCheckInterval time.Duration = time.Minute 17 ) 18 19 type ResourceStatsOptions struct { 20 checkInterval time.Duration 21 memoryCallBack func(total, free uint64, usage float64) 22 } 23 24 type ResourceStatsService struct { 25 inShutdown atomic.Bool // true when when server is in shutdown 26 27 opts ResourceStatsOptions 28 29 metrics *ResourceStatsMetrics 30 31 mu sync.Mutex 32 cancel func() 33 } 34 35 func NewResourceStatsService(opts ...ResourceStatsServiceOption) (*ResourceStatsService, error) { 36 var err error 37 r := &ResourceStatsService{} 38 39 m, err := NewResourceStatsMetrics() 40 if err != nil { 41 return nil, err 42 } 43 r.metrics = m 44 r.ApplyOptions(opts...) 45 if r.opts.checkInterval <= 0 { 46 r.opts.checkInterval = DefaultCheckInterval 47 } 48 49 return r, nil 50 } 51 52 // Run will initialize the backend. It must not block, but may run go routines in the background. 53 func (s *ResourceStatsService) Run(ctx context.Context) error { 54 logger := s.getLogger() 55 logger.Infoln("ResourceStatsService Run") 56 if s.inShutdown.Load() { 57 logger.Infoln("ResourceStatsService Shutdown") 58 return fmt.Errorf("server closed") 59 } 60 go func() { 61 errors.HandleError(s.Serve(ctx)) 62 }() 63 return nil 64 } 65 66 func (s *ResourceStatsService) getLogger() *logrus.Entry { 67 return logrus.WithField("module", "ResourceStatsService") 68 } 69 70 // Serve ... 71 func (s *ResourceStatsService) Serve(ctx context.Context) error { 72 logger := s.getLogger() 73 logger.Infoln("ResourceStats Serve") 74 75 if s.inShutdown.Load() { 76 logger.Infoln("ResourceStats Shutdown") 77 return fmt.Errorf("server closed") 78 } 79 80 defer s.inShutdown.Store(true) 81 ctx, cancel := context.WithCancel(ctx) 82 defer cancel() 83 s.mu.Lock() 84 s.cancel = cancel 85 s.mu.Unlock() 86 87 time_.UntilWithContxt(ctx, func(ctx context.Context) error { 88 total, avaiable, usage := s.metrics.ReportMetric(ctx) 89 if s.opts.memoryCallBack != nil { 90 s.opts.memoryCallBack(uint64(total), uint64(avaiable), usage) 91 } 92 return nil 93 }, s.opts.checkInterval) 94 if err := ctx.Err(); err != nil { 95 logger.WithError(err).Errorf("stopped checking") 96 return err 97 } 98 logger.Info("stopped checking") 99 return nil 100 } 101 102 // Shutdown ... 103 func (s *ResourceStatsService) Shutdown() { 104 s.inShutdown.Store(true) 105 s.mu.Lock() 106 defer s.mu.Unlock() 107 if s.cancel != nil { 108 s.cancel() 109 } 110 }