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