github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/agent/spy/spy.go (about) 1 // Package spy contains an interface (Spy) and functionality to register new spies 2 package spy 3 4 import ( 5 "fmt" 6 "github.com/pyroscope-io/pyroscope/pkg/agent/log" 7 8 "github.com/pyroscope-io/pyroscope/pkg/storage/metadata" 9 ) 10 11 type Spy interface { 12 Stop() error 13 Snapshot(cb func(*Labels, []byte, uint64) error) error 14 } 15 16 type Resettable interface { 17 Reset() 18 } 19 20 type ProfileType string 21 22 const ( 23 ProfileCPU ProfileType = "cpu" 24 ProfileInuseObjects ProfileType = "inuse_objects" 25 ProfileAllocObjects ProfileType = "alloc_objects" 26 ProfileInuseSpace ProfileType = "inuse_space" 27 ProfileAllocSpace ProfileType = "alloc_space" 28 29 Go = "gospy" 30 EBPF = "ebpfspy" 31 Python = "pyspy" 32 Ruby = "rbspy" 33 ) 34 35 func (t ProfileType) IsCumulative() bool { 36 return t == ProfileAllocObjects || t == ProfileAllocSpace 37 } 38 39 func (t ProfileType) Units() metadata.Units { 40 if t == ProfileInuseObjects || t == ProfileAllocObjects { 41 return metadata.ObjectsUnits 42 } 43 if t == ProfileInuseSpace || t == ProfileAllocSpace { 44 return metadata.BytesUnits 45 } 46 47 return metadata.SamplesUnits 48 } 49 50 func (t ProfileType) AggregationType() metadata.AggregationType { 51 if t == ProfileInuseObjects || t == ProfileInuseSpace { 52 return metadata.AverageAggregationType 53 } 54 55 return metadata.SumAggregationType 56 } 57 58 // TODO: this interface is not the best as different spies have different arguments 59 type InitParams struct { 60 Pid int 61 ProfileType ProfileType 62 SampleRate uint32 63 DisableGCRuns bool 64 Logger log.Logger 65 PHPSpyArgs string 66 } 67 type SpyIntitializer func(InitParams) (Spy, error) 68 69 var ( 70 supportedSpiesMap map[string]SpyIntitializer 71 SupportedSpies []string 72 ) 73 74 var autoDetectionMapping = map[string]string{ 75 "php": "phpspy", 76 77 "dotnet": "dotnetspy", 78 } 79 80 func init() { 81 supportedSpiesMap = make(map[string]SpyIntitializer) 82 } 83 84 func RegisterSpy(name string, cb SpyIntitializer) { 85 SupportedSpies = append(SupportedSpies, name) 86 supportedSpiesMap[name] = cb 87 } 88 89 func StartFunc(name string) (SpyIntitializer, error) { 90 if s, ok := supportedSpiesMap[name]; ok { 91 return s, nil 92 } 93 return nil, fmt.Errorf("unknown spy \"%s\". Make sure it's supported (run `pyroscope version` to check if your version supports it)", name) 94 } 95 96 func ResolveAutoName(s string) string { 97 return autoDetectionMapping[s] 98 } 99 100 func SupportedExecSpies() []string { 101 supportedSpies := []string{} 102 for _, s := range SupportedSpies { 103 if s != Go { 104 supportedSpies = append(supportedSpies, s) 105 } 106 } 107 108 return supportedSpies 109 }