github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/agent/ebpfspy/ebpfspy_linux.go (about)

     1  //go:build ebpfspy
     2  
     3  package ebpfspy
     4  
     5  import (
     6  	"github.com/pyroscope-io/pyroscope/pkg/agent/ebpfspy/sd"
     7  	"github.com/pyroscope-io/pyroscope/pkg/agent/spy"
     8  	"sync"
     9  )
    10  
    11  type EbpfSpy struct {
    12  	mutex  sync.Mutex
    13  	reset  bool
    14  	stop   bool
    15  	stopCh chan struct{}
    16  
    17  	session *Session
    18  }
    19  
    20  func NewEBPFSpy(s *Session) *EbpfSpy {
    21  	return &EbpfSpy{
    22  		session: s,
    23  		stopCh:  make(chan struct{}),
    24  	}
    25  }
    26  
    27  func Start(params spy.InitParams) (spy.Spy, error) {
    28  	s := NewSession(params.Logger, params.Pid, params.SampleRate, 256, sd.NoopServiceDiscovery{}, false)
    29  	err := s.Start()
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	return NewEBPFSpy(s), nil
    34  }
    35  
    36  func (s *EbpfSpy) Snapshot(cb func(*spy.Labels, []byte, uint64) error) error {
    37  	s.mutex.Lock()
    38  	defer s.mutex.Unlock()
    39  
    40  	if !s.reset {
    41  		return nil
    42  	}
    43  
    44  	s.reset = false
    45  
    46  	err := s.session.Reset(func(labels *spy.Labels, name []byte, v uint64, pid uint32) error {
    47  		return cb(labels, name, v)
    48  	})
    49  
    50  	if s.stop {
    51  		s.session.Stop()
    52  		s.stopCh <- struct{}{}
    53  	}
    54  
    55  	return err
    56  }
    57  
    58  func (s *EbpfSpy) Stop() error {
    59  	s.mutex.Lock()
    60  	s.stop = true
    61  	s.mutex.Unlock()
    62  	<-s.stopCh
    63  	return nil
    64  }
    65  
    66  func (s *EbpfSpy) Reset() {
    67  	s.mutex.Lock()
    68  	defer s.mutex.Unlock()
    69  
    70  	s.reset = true
    71  }
    72  
    73  func init() {
    74  	spy.RegisterSpy("ebpfspy", Start)
    75  }