blob: 238046853a01252adf2886c5bb2eee7d52976277 [file] [log] [blame]
William Kurkianea869482019-04-09 15:16:11 -04001package api
2
3import (
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.
14type Debug struct {
15 c *Client
16}
17
18// Debug returns a handle that exposes the internal debug endpoints.
19func (c *Client) Debug() *Debug {
20 return &Debug{c}
21}
22
23// Heap returns a pprof heap dump
24func (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
43func (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
66func (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
89func (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}