Simple profiling for Go.
- Easy management of Go's built-in profiling and tracing
- Based on the widely-used
pkg/profile
: mostly-compatible API - Supports generating multiple profiles at once
- Configurable with idiomatic flags:
-cpuprofile
,-memprofile
, ... just likego test
- Configurable by environment variable: key-value interface like
GODEBUG
go get github.com/mmcloughlin/profile
Enabling profiling in your application is as simple as one line at the top of your main function.
import "github.com/mmcloughlin/profile"
func main() {
defer profile.Start().Stop()
// ...
}
This will write a CPU profile to the current directory. Generate multiple
profiles by passing options to the Start
function.
defer profile.Start(profile.CPUProfile, profile.MemProfile).Stop()
Profiles can also be configured by the user via flags or environment variable, as demonstrated in the examples below.
The following example shows how to configure profile
via flags with multiple
available profile types.
func main() {
log.SetPrefix("example: ")
log.SetFlags(0)
// Setup profiler.
p := profile.New(
profile.CPUProfile,
profile.MemProfile,
profile.TraceProfile,
)
// Configure flags.
n := flag.Int("n", 1000000, "sum the integers 1 to `n`")
p.SetFlags(flag.CommandLine)
flag.Parse()
// Start profiler.
defer p.Start().Stop()
// Sum 1 to n.
sum := 0
for i := 1; i <= *n; i++ {
sum += i
}
log.Printf("sum: %d", sum)
}
See the registered flags:
Usage of example:
-cpuprofile file
write a cpu profile to file
-memprofile file
write an allocation profile to file
-memprofilerate rate
set memory allocation profiling rate (see runtime.MemProfileRate)
-n n
sum the integers 1 to n (default 1000000)
-trace file
write an execution trace to file
Profile the application with the following flags:
example -n 1000000000 -cpuprofile cpu.out -memprofile mem.out
We'll see additional logging in the output, as well as the profiles cpu.out
and mem.out
written on exit.
example: cpu profile: started
example: mem profile: started
example: sum: 500000000500000000
example: cpu profile: stopped
example: mem profile: stopped
For a user-facing tool you may not want to expose profiling options via flags.
The profile
package also offers configuration by environment variable, similar
to the GODEBUG
option offered by the Go runtime.
// Setup profiler.
defer profile.Start(
profile.AllProfiles,
profile.ConfigEnvVar("PROFILE"),
).Stop()
Now you can enable profiling with an environment variable, as follows:
PROFILE=cpuprofile=cpu.out,memprofile=mem.out example -n 1000000000
The output will be just the same as for the previous flags example. Set the
environment variable to help
to get help on available options:
PROFILE=help example
In this case you'll see:
blockprofile=file
write a goroutine blocking profile to file
blockprofilerate=rate
set blocking profile rate (see runtime.SetBlockProfileRate)
cpuprofile=file
write a cpu profile to file
goroutineprofile=file
write a running goroutine profile to file
memprofile=file
write an allocation profile to file
memprofilerate=rate
set memory allocation profiling rate (see runtime.MemProfileRate)
mutexprofile=string
write a mutex contention profile to the named file after execution
mutexprofilefraction=int
if >= 0, calls runtime.SetMutexProfileFraction()
threadcreateprofile=file
write a thread creation profile to file
trace=file
write an execution trace to file
Thank you to Dave Cheney and
contributors for the
excellent pkg/profile
package, which
provided the inspiration and basis for this work.
profile
is available under the BSD 3-Clause License. The license
retains the copyright notice from
pkg/profile
.