diff --git a/go.mod b/go.mod index 08932f3..6dd15d7 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/pkg/profile go 1.13 + +require github.com/felixge/fgprof v0.9.3 diff --git a/profile.go b/profile.go index ec66e30..ea4e853 100644 --- a/profile.go +++ b/profile.go @@ -12,6 +12,8 @@ import ( "runtime/pprof" "runtime/trace" "sync/atomic" + + "github.com/felixge/fgprof" ) const ( @@ -22,6 +24,7 @@ const ( traceMode threadCreateMode goroutineMode + clockMode ) // Profile represents an active profiling session. @@ -122,6 +125,10 @@ func ThreadcreationProfile(p *Profile) { p.mode = threadCreateMode } // It disables any previous profiling settings. func GoroutineProfile(p *Profile) { p.mode = goroutineMode } +// ClockProfile enables wall clock (fgprof) profiling. +// It disables any previous profiling settings. +func ClockProfile(p *Profile) { p.mode = clockMode } + // ProfilePath controls the base path where various profiling // files are written. If blank, the base path will be generated // by ioutil.TempDir. @@ -287,6 +294,20 @@ func Start(options ...func(*Profile)) interface { f.Close() logf("profile: goroutine profiling disabled, %s", fn) } + + case clockMode: + fn := filepath.Join(path, "clock.pprof") + f, err := os.Create(fn) + if err != nil { + log.Fatalf("profile: could not create clock profile %q: %v", fn, err) + } + logf("profile: clock profiling enabled, %s", fn) + stop := fgprof.Start(f, fgprof.FormatPprof) + prof.closer = func() { + stop() + f.Close() + logf("profile: clock profiling disabled, %s", fn) + } } if !prof.noShutdownHook { diff --git a/profile_test.go b/profile_test.go index e33012c..b4cd651 100644 --- a/profile_test.go +++ b/profile_test.go @@ -122,6 +122,22 @@ func main() { Stderr("profile: mutex profiling enabled"), NoErr, }, + }, { + name: "clock profile", + code: ` +package main + +import "github.com/pkg/profile" + +func main() { + defer profile.Start(profile.ClockProfile).Stop() +} +`, + checks: []checkFn{ + NoStdout, + Stderr("profile: clock profiling enabled"), + NoErr, + }, }, { name: "profile path", code: `