1// (c) Copyright IBM Corp. 2021 2// (c) Copyright Instana Inc. 2020 3 4package autoprofile 5 6import ( 7 "os" 8 9 "github.com/instana/go-sensor/autoprofile/internal" 10 "github.com/instana/go-sensor/autoprofile/internal/logger" 11 instalogger "github.com/instana/go-sensor/logger" 12) 13 14// Profile represents profiler data sent to the host agent 15// 16// The type alias here is needed to expose the type defined inside the internal package. 17// Ideally this type should've been defined in the same package with instana.agentS, however 18// due to the way we activate profiling, this would introduce a circular dependency. 19type Profile internal.AgentProfile 20 21// SendProfilesFunc is a function that submits profiles to the host agent 22type SendProfilesFunc func(profiles []Profile) error 23 24var ( 25 profileRecorder = internal.NewRecorder() 26 cpuSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewCPUSampler(), internal.SamplerConfig{ 27 LogPrefix: "CPU sampler:", 28 MaxProfileDuration: 20, 29 MaxSpanDuration: 2, 30 MaxSpanCount: 30, 31 SamplingInterval: 8, 32 ReportInterval: 120, 33 }) 34 allocationSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewAllocationSampler(), internal.SamplerConfig{ 35 LogPrefix: "Allocation sampler:", 36 ReportOnly: true, 37 ReportInterval: 120, 38 }) 39 blockSamplerScheduler = internal.NewSamplerScheduler(profileRecorder, internal.NewBlockSampler(), internal.SamplerConfig{ 40 LogPrefix: "Block sampler:", 41 MaxProfileDuration: 20, 42 MaxSpanDuration: 4, 43 MaxSpanCount: 30, 44 SamplingInterval: 16, 45 ReportInterval: 120, 46 }) 47 48 enabled bool 49) 50 51// SetLogLevel sets the min log level for autoprofiler 52// 53// Deprecated: use autoprofile.SetLogger() to set the logger and configure the min log level directly 54func SetLogLevel(level int) { 55 switch logger.Level(level) { 56 case logger.ErrorLevel: 57 logger.SetLogLevel(instalogger.ErrorLevel) 58 case logger.WarnLevel: 59 logger.SetLogLevel(instalogger.WarnLevel) 60 case logger.InfoLevel: 61 logger.SetLogLevel(instalogger.InfoLevel) 62 default: 63 logger.SetLogLevel(instalogger.DebugLevel) 64 } 65} 66 67// SetLogger sets the leveled logger to use to output the diagnostic messages and errors 68func SetLogger(l logger.LeveledLogger) { 69 logger.SetLogger(l) 70} 71 72// Enable enables the auto profiling (disabled by default) 73func Enable() { 74 if enabled { 75 return 76 } 77 78 profileRecorder.Start() 79 cpuSamplerScheduler.Start() 80 allocationSamplerScheduler.Start() 81 blockSamplerScheduler.Start() 82 83 logger.Debug("profiler enabled") 84} 85 86// Disable disables the auto profiling (default) 87func Disable() { 88 if !enabled { 89 return 90 } 91 92 if _, ok := os.LookupEnv("INSTANA_AUTO_PROFILE"); ok { 93 logger.Info("INSTANA_AUTO_PROFILE is set, ignoring the attempt to disable AutoProfile™") 94 return 95 } 96 97 profileRecorder.Stop() 98 cpuSamplerScheduler.Stop() 99 allocationSamplerScheduler.Stop() 100 blockSamplerScheduler.Stop() 101 102 logger.Debug("profiler disabled") 103} 104 105// SetGetExternalPIDFunc configures the profiler to use provided function to retrieve the current PID 106// 107// Deprecated: this is a noop function, the PID is populated by the agent before sending 108func SetGetExternalPIDFunc(fn func() string) {} 109 110// SetSendProfilesFunc configures the profiler to use provided function to write collected profiles 111func SetSendProfilesFunc(fn SendProfilesFunc) { 112 if fn == nil { 113 profileRecorder.SendProfiles = internal.NoopSendProfiles 114 return 115 } 116 117 profileRecorder.SendProfiles = func(data []internal.AgentProfile) error { 118 profiles := make([]Profile, 0, len(data)) 119 for _, p := range data { 120 profiles = append(profiles, Profile(p)) 121 } 122 123 return fn(profiles) 124 } 125} 126 127// Options contains profiler configuration 128type Options struct { 129 IncludeProfilerFrames bool 130 MaxBufferedProfiles int 131} 132 133// DefaultOptions returns profiler defaults 134func DefaultOptions() Options { 135 return Options{ 136 MaxBufferedProfiles: internal.DefaultMaxBufferedProfiles, 137 } 138} 139 140// SetOptions configures the profiler with provided settings 141func SetOptions(opts Options) { 142 if opts.MaxBufferedProfiles < 1 { 143 opts.MaxBufferedProfiles = internal.DefaultMaxBufferedProfiles 144 } 145 146 profileRecorder.MaxBufferedProfiles = opts.MaxBufferedProfiles 147 internal.IncludeProfilerFrames = opts.IncludeProfilerFrames 148} 149