package api
import (
"fmt"
"io/ioutil"
"strconv"
)
// Debug can be used to query the /debug/pprof endpoints to gather
// profiling information about the target agent.Debug
//
// The agent must have enable_debug set to true for profiling to be enabled
// and for these endpoints to function.
type Debug struct {
c * Client
}
// Debug returns a handle that exposes the internal debug endpoints.
func ( c * Client ) Debug ( ) * Debug {
return & Debug { c }
}
// Heap returns a pprof heap dump
func ( d * Debug ) Heap ( ) ( [ ] byte , error ) {
r := d . c . newRequest ( "GET" , "/debug/pprof/heap" )
_ , resp , err := d . c . doRequest ( r )
if err != nil {
return nil , fmt . Errorf ( "error making request: %s" , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != 200 {
return nil , generateUnexpectedResponseCodeError ( resp )
}
// We return a raw response because we're just passing through a response
// from the pprof handlers
body , err := ioutil . ReadAll ( resp . Body )
if err != nil {
return nil , fmt . Errorf ( "error decoding body: %s" , err )
}
return body , nil
}
// Profile returns a pprof CPU profile for the specified number of seconds
func ( d * Debug ) Profile ( seconds int ) ( [ ] byte , error ) {
r := d . c . newRequest ( "GET" , "/debug/pprof/profile" )
// Capture a profile for the specified number of seconds
r . params . Set ( "seconds" , strconv . Itoa ( seconds ) )
_ , resp , err := d . c . doRequest ( r )
if err != nil {
return nil , fmt . Errorf ( "error making request: %s" , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != 200 {
return nil , generateUnexpectedResponseCodeError ( resp )
}
// We return a raw response because we're just passing through a response
// from the pprof handlers
body , err := ioutil . ReadAll ( resp . Body )
if err != nil {
return nil , fmt . Errorf ( "error decoding body: %s" , err )
}
return body , nil
}
// Trace returns an execution trace
func ( d * Debug ) Trace ( seconds int ) ( [ ] byte , error ) {
r := d . c . newRequest ( "GET" , "/debug/pprof/trace" )
// Capture a trace for the specified number of seconds
r . params . Set ( "seconds" , strconv . Itoa ( seconds ) )
_ , resp , err := d . c . doRequest ( r )
if err != nil {
return nil , fmt . Errorf ( "error making request: %s" , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != 200 {
return nil , generateUnexpectedResponseCodeError ( resp )
}
// We return a raw response because we're just passing through a response
// from the pprof handlers
body , err := ioutil . ReadAll ( resp . Body )
if err != nil {
return nil , fmt . Errorf ( "error decoding body: %s" , err )
}
return body , nil
}
// Goroutine returns a pprof goroutine profile
func ( d * Debug ) Goroutine ( ) ( [ ] byte , error ) {
r := d . c . newRequest ( "GET" , "/debug/pprof/goroutine" )
_ , resp , err := d . c . doRequest ( r )
if err != nil {
return nil , fmt . Errorf ( "error making request: %s" , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != 200 {
return nil , generateUnexpectedResponseCodeError ( resp )
}
// We return a raw response because we're just passing through a response
// from the pprof handlers
body , err := ioutil . ReadAll ( resp . Body )
if err != nil {
return nil , fmt . Errorf ( "error decoding body: %s" , err )
}
return body , nil
}