github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/autoprofile/auto_profiler.go (about)

     1  // (c) Copyright IBM Corp. 2021
     2  // (c) Copyright Instana Inc. 2020
     3  
     4  package autoprofile
     5  
     6  import (
     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.
    19  type Profile internal.AgentProfile
    20  
    21  // SendProfilesFunc is a function that submits profiles to the host agent
    22  type SendProfilesFunc func(profiles []Profile) error
    23  
    24  var (
    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
    54  func 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
    68  func SetLogger(l logger.LeveledLogger) {
    69  	logger.SetLogger(l)
    70  }
    71  
    72  // Enable enables the auto profiling (disabled by default)
    73  func 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)
    87  func 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
   108  func SetGetExternalPIDFunc(fn func() string) {}
   109  
   110  // SetSendProfilesFunc configures the profiler to use provided function to write collected profiles
   111  func 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
   128  type Options struct {
   129  	IncludeProfilerFrames bool
   130  	MaxBufferedProfiles   int
   131  }
   132  
   133  // DefaultOptions returns profiler defaults
   134  func DefaultOptions() Options {
   135  	return Options{
   136  		MaxBufferedProfiles: internal.DefaultMaxBufferedProfiles,
   137  	}
   138  }
   139  
   140  // SetOptions configures the profiler with provided settings
   141  func 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  }