github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/pprof/socket.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package pprof 5 6 import ( 7 "fmt" 8 "net" 9 "net/http" 10 "os" 11 "path/filepath" 12 "runtime" 13 14 "github.com/juju/loggo" 15 ) 16 17 var logger = loggo.GetLogger("juju.cmd.pprof") 18 19 // Start starts a pprof server listening on a unix socket in /tmp. 20 // The name of the file is derived from the name of the process, as 21 // provided by os.Args[0], and the pid of the process. 22 // Start returns a function which will stop the pprof server and clean 23 // up the socket file. 24 func Start() func() error { 25 if runtime.GOOS != "linux" { 26 logger.Infof("pprof debugging not supported on %q", runtime.GOOS) 27 return func() error { return nil } 28 } 29 30 mux := http.NewServeMux() 31 mux.Handle("/debug/pprof/", http.HandlerFunc(Index)) 32 mux.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline)) 33 mux.Handle("/debug/pprof/profile", http.HandlerFunc(Profile)) 34 mux.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol)) 35 36 srv := http.Server{ 37 Handler: mux, 38 } 39 40 path := socketpath() 41 addr, err := net.ResolveUnixAddr("unix", path) 42 if err != nil { 43 logger.Errorf("unable to resolve unix socket: %v", err) 44 return func() error { return nil } 45 } 46 47 // Try to remove the socket if already present. 48 os.Remove(path) 49 50 l, err := net.ListenUnix("unix", addr) 51 if err != nil { 52 logger.Errorf("unable to listen on unix socket: %v", err) 53 return func() error { return nil } 54 } 55 56 go func() { 57 defer os.Remove(path) 58 59 // Ignore the error from calling l.Close. 60 srv.Serve(l) 61 }() 62 63 return l.Close 64 } 65 66 // socketpath returns the path for this processes' pprof socket. 67 func socketpath() string { 68 cmd := filepath.Base(os.Args[0]) 69 name := fmt.Sprintf("pprof.%s.%d", cmd, os.Getpid()) 70 path := filepath.Join(os.TempDir(), name) 71 return path 72 }