github.com/marwan-at-work/consul@v1.4.5/api/debug.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "strconv" 7 ) 8 9 // Debug can be used to query the /debug/pprof endpoints to gather 10 // profiling information about the target agent.Debug 11 // 12 // The agent must have enable_debug set to true for profiling to be enabled 13 // and for these endpoints to function. 14 type Debug struct { 15 c *Client 16 } 17 18 // Debug returns a handle that exposes the internal debug endpoints. 19 func (c *Client) Debug() *Debug { 20 return &Debug{c} 21 } 22 23 // Heap returns a pprof heap dump 24 func (d *Debug) Heap() ([]byte, error) { 25 r := d.c.newRequest("GET", "/debug/pprof/heap") 26 _, resp, err := d.c.doRequest(r) 27 if err != nil { 28 return nil, fmt.Errorf("error making request: %s", err) 29 } 30 defer resp.Body.Close() 31 32 // We return a raw response because we're just passing through a response 33 // from the pprof handlers 34 body, err := ioutil.ReadAll(resp.Body) 35 if err != nil { 36 return nil, fmt.Errorf("error decoding body: %s", err) 37 } 38 39 return body, nil 40 } 41 42 // Profile returns a pprof CPU profile for the specified number of seconds 43 func (d *Debug) Profile(seconds int) ([]byte, error) { 44 r := d.c.newRequest("GET", "/debug/pprof/profile") 45 46 // Capture a profile for the specified number of seconds 47 r.params.Set("seconds", strconv.Itoa(seconds)) 48 49 _, resp, err := d.c.doRequest(r) 50 if err != nil { 51 return nil, fmt.Errorf("error making request: %s", err) 52 } 53 defer resp.Body.Close() 54 55 // We return a raw response because we're just passing through a response 56 // from the pprof handlers 57 body, err := ioutil.ReadAll(resp.Body) 58 if err != nil { 59 return nil, fmt.Errorf("error decoding body: %s", err) 60 } 61 62 return body, nil 63 } 64 65 // Trace returns an execution trace 66 func (d *Debug) Trace(seconds int) ([]byte, error) { 67 r := d.c.newRequest("GET", "/debug/pprof/trace") 68 69 // Capture a trace for the specified number of seconds 70 r.params.Set("seconds", strconv.Itoa(seconds)) 71 72 _, resp, err := d.c.doRequest(r) 73 if err != nil { 74 return nil, fmt.Errorf("error making request: %s", err) 75 } 76 defer resp.Body.Close() 77 78 // We return a raw response because we're just passing through a response 79 // from the pprof handlers 80 body, err := ioutil.ReadAll(resp.Body) 81 if err != nil { 82 return nil, fmt.Errorf("error decoding body: %s", err) 83 } 84 85 return body, nil 86 } 87 88 // Goroutine returns a pprof goroutine profile 89 func (d *Debug) Goroutine() ([]byte, error) { 90 r := d.c.newRequest("GET", "/debug/pprof/goroutine") 91 92 _, resp, err := d.c.doRequest(r) 93 if err != nil { 94 return nil, fmt.Errorf("error making request: %s", err) 95 } 96 defer resp.Body.Close() 97 98 // We return a raw response because we're just passing through a response 99 // from the pprof handlers 100 body, err := ioutil.ReadAll(resp.Body) 101 if err != nil { 102 return nil, fmt.Errorf("error decoding body: %s", err) 103 } 104 105 return body, nil 106 }