mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
profiling: Return goroutines with sleep duration (#12775)
Add a new goroutine file which has another printing format. We need it to see how much time each goroutine was blocked. Easier to detect stops. Co-authored-by: Anis Elleuch <anis@min.io>
This commit is contained in:
parent
9a31030e74
commit
23ef25b57a
44
cmd/utils.go
44
cmd/utils.go
@ -218,25 +218,27 @@ func contains(slice interface{}, elem interface{}) bool {
|
||||
// disk since the name of this latter is randomly generated.
|
||||
type profilerWrapper struct {
|
||||
// Profile recorded at start of benchmark.
|
||||
base []byte
|
||||
stopFn func() ([]byte, error)
|
||||
ext string
|
||||
records map[string][]byte
|
||||
stopFn func() ([]byte, error)
|
||||
ext string
|
||||
}
|
||||
|
||||
// recordBase will record the profile and store it as the base.
|
||||
func (p *profilerWrapper) recordBase(name string, debug int) {
|
||||
// record will record the profile and store it as the base.
|
||||
func (p *profilerWrapper) record(profileType string, debug int, recordName string) {
|
||||
var buf bytes.Buffer
|
||||
p.base = nil
|
||||
err := pprof.Lookup(name).WriteTo(&buf, debug)
|
||||
if p.records == nil {
|
||||
p.records = make(map[string][]byte)
|
||||
}
|
||||
err := pprof.Lookup(profileType).WriteTo(&buf, debug)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
p.base = buf.Bytes()
|
||||
p.records[recordName] = buf.Bytes()
|
||||
}
|
||||
|
||||
// Base returns the recorded base if any.
|
||||
func (p profilerWrapper) Base() []byte {
|
||||
return p.base
|
||||
// Records returns the recorded profiling if any.
|
||||
func (p profilerWrapper) Records() map[string][]byte {
|
||||
return p.records
|
||||
}
|
||||
|
||||
// Stop the currently running benchmark.
|
||||
@ -268,9 +270,10 @@ func getProfileData() (map[string][]byte, error) {
|
||||
if err == nil {
|
||||
dst[typ+"."+prof.Extension()] = buf
|
||||
}
|
||||
buf = prof.Base()
|
||||
if len(buf) > 0 {
|
||||
dst[typ+"-before"+"."+prof.Extension()] = buf
|
||||
for name, buf := range prof.Records() {
|
||||
if len(buf) > 0 {
|
||||
dst[typ+"-"+name+"."+prof.Extension()] = buf
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst, nil
|
||||
@ -314,7 +317,7 @@ func startProfiler(profilerType string) (minioProfiler, error) {
|
||||
}
|
||||
case madmin.ProfilerMEM:
|
||||
runtime.GC()
|
||||
prof.recordBase("heap", 0)
|
||||
prof.record("heap", 0, "before")
|
||||
prof.stopFn = func() ([]byte, error) {
|
||||
runtime.GC()
|
||||
var buf bytes.Buffer
|
||||
@ -330,7 +333,7 @@ func startProfiler(profilerType string) (minioProfiler, error) {
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
case madmin.ProfilerMutex:
|
||||
prof.recordBase("mutex", 0)
|
||||
prof.record("mutex", 0, "before")
|
||||
runtime.SetMutexProfileFraction(1)
|
||||
prof.stopFn = func() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
@ -339,7 +342,7 @@ func startProfiler(profilerType string) (minioProfiler, error) {
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
case madmin.ProfilerThreads:
|
||||
prof.recordBase("threadcreate", 0)
|
||||
prof.record("threadcreate", 0, "before")
|
||||
prof.stopFn = func() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := pprof.Lookup("threadcreate").WriteTo(&buf, 0)
|
||||
@ -347,7 +350,8 @@ func startProfiler(profilerType string) (minioProfiler, error) {
|
||||
}
|
||||
case madmin.ProfilerGoroutines:
|
||||
prof.ext = "txt"
|
||||
prof.recordBase("goroutine", 1)
|
||||
prof.record("goroutine", 1, "before")
|
||||
prof.record("goroutine", 2, "before,debug=2")
|
||||
prof.stopFn = func() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := pprof.Lookup("goroutine").WriteTo(&buf, 1)
|
||||
@ -386,8 +390,8 @@ func startProfiler(profilerType string) (minioProfiler, error) {
|
||||
|
||||
// minioProfiler - minio profiler interface.
|
||||
type minioProfiler interface {
|
||||
// Return base profile. 'nil' if none.
|
||||
Base() []byte
|
||||
// Return recorded profiles, each profile associated with a distinct generic name.
|
||||
Records() map[string][]byte
|
||||
// Stop the profiler
|
||||
Stop() ([]byte, error)
|
||||
// Return extension of profile
|
||||
|
Loading…
Reference in New Issue
Block a user