安装
brew install graphviz
Check安装
ccli@ccli-mac:perftest$ dot -h
Error: dot: option -h unrecognized
Usage: dot [-Vv?] [-(GNE)name=val] [-(KTlso)<val>] <dot files>
(additional options for neato) [-x] [-n]
(additional options for fdp) [-L(gO)] [-L(nUCT)]
(additional options for memtest) [-m]
(additional options for config) [-cv]
-V - Print version and exit
...
dot已经安装了,并且add into 你的PATH环境变量中
图形生成
编辑文件my1st.dot
digraph d {
A [label="Hello"]
B [label="World"]
C [label="Everyone"]
A -> { B C }
}
ccli@ccli-mac:perftest$ dot -T png -O my1st.dot
ccli@ccli-mac:perftest$ ls
my1st.dot my1st.dot.png
查看png
CPU Profiling
set GOPATH
export GOPATH=/Users/ccli/tool/perftest
Step #1: download github.com/pkg/profile
go get github.com/pkg/profile
Step #2: add profiling into the main() function of your command, Eg:
package main
import (
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"text/template"
"time"
"github.com/pkg/profile"
)
// templateFile defines the contents of a template to be stored in a file, for testing.
type templateFile struct {
name string
contentsstring
}
func createTestDir(files []templateFile) string {
dir, err := ioutil.TempDir("", "template")
if err != nil {
log.Fatal(err)
}
for _, file := range files {
f, err := os.Create(filepath.Join(dir, file.name))
if err != nil {
log.Fatal(err)
}
defer f.Close()
_, err = io.WriteString(f, file.contents)
if err != nil {
log.Fatal(err)
}
}
return dir
}
func testSleep() {
time.Sleep(3 * time.Second)
}
func main() {
defer profile.Start().Stop()
// Here we create a temporary directory and populate it with our sample
// template definition files; usually the template files would already
// exist in some location known to the program.
dir := createTestDir([]templateFile{
// T0.tmpl is a plain template file that just invokes T1.
{"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
// T1.tmpl defines a template, T1 that invokes T2.
{"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
// T2.tmpl defines a template T2.
{"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
})
// Clean up after the test; another quirk of running as an example.
defer os.RemoveAll(dir)
// pattern is the glob pattern used to find all the template files.
pattern := filepath.Join(dir,"*.tmpl")
// Here starts the example proper.
// T0.tmpl is the first name matched, so it becomes the starting template,
// the value returned by ParseGlob.
tmpl := template.Must(template.ParseGlob(pattern))
testSleep()
err := tmpl.Execute(os.Stdout,nil)
if err != nil {
log.Fatalf("template execution: %s", err)
}
}
Step #3: build and run your program
This will generate a *.pprof file in a temp folder, and tell you where it’s located (will be needed later)
ccli@ccli-mac:src$ go build -o text_template text_template.go
ccli@ccli-mac:src$ ./text_template
2019/05/16 15:32:01 profile: cpu profiling enabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof
T0 invokes T1: (T1 invokes T2: (This is T2))2019/05/16 15:32:04 profile: cpu profiling disabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof
Step #4: run go tool pprof
Pass your binary location, and the location of the cpu.pprof file as returned when running your program.
You can generate the analysis in various formats. The PDF one is pretty amazing:
go tool pprof --pdf ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof > text_template.pdf
这里仅仅是为了举例说明,因函数调用简单,没有call diagram,方法步骤是正确的。
You can generate other kind of visualizations as well, e.g. txt:
go tool pprof --text ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof > text_template.txt
Memory Profiling
Memory profiling is essentially the same as CPU profiling, but instead of using the default configuration for profile.Start(), we pass a profile.MemProfile flag:
defer profile.Start(profile.MemProfile).Stop()
thus the code becomes
package main
import (
//...
"github.com/pkg/profile"
)
func main() {
// Memory profiling
defer profile.Start(profile.MemProfile).Stop()
//...
}
and when running the program, it will generate a mem.pprof file instead of cpu.pprof.
ccli@ccli-mac:src$ go build -o text_template text_template.go
ccli@ccli-mac:src$ ./text_template
2019/05/16 15:48:23 profile: memory profiling enabled (rate 4096), /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof
T0 invokes T1: (T1 invokes T2: (This is T2))2019/05/16 15:48:26 profile: memory profiling disabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof
ccli@ccli-mac:src$ go tool pprof --pdf ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof > text_template.pdf
ccli@ccli-mac:src$
Diagram screenshot:
Read more about profiling Go apps
This is just a start. Read more at:
https://blog.golang.org/profiling-go-programs
Lower level: https://golang.org/pkg/runtime/pprof/
More options for advanced usage of github.com/pkg/profilehttp://godoc.org/github.com/pkg/profile
有疑问加站长微信联系(非本文作者)