decred / dcrd

Decred daemon in Go (golang).
https://decred.org
ISC License
731 stars 288 forks source link

multi: Add dynamic profile server infrastructure. #3323

Closed davecgh closed 3 months ago

davecgh commented 3 months ago

This adds support for dynamically starting and stopping the profile server via the RPC server by introducing two new rpc commands named startprofiler and stopprofiler and updates the JSON-RPC API documentation accordingly.

It also updates the code that allows the profile to be started via the --profile command line / profile= config file option to use the new infrastructure such that it retains the existing behavior.

As a part of the changes, it expands the capabilities of the aforementioned profile options to allow specifying an interface name so it is more consistent with the other options that deal with listeners.


A high level overview of the changes are:


This consists of a series of commits to help ease the review process. Each commit is intended to be a self-contained and logically easy to follow change such that the code continues to compile and the tests continue to pass at each step.

See the description of each commit for further details.


Example commands showing the changes in action:

$ dcrctl startprofiler 127.0.0.1:5959
{
  "listeners": [
    "127.0.0.1:5959"
  ]
}

# Unable to change port without stopping running profile server first.
$ dcrctl startprofiler 127.0.0.1:1234
-26: profile server is already running
$ go tool pprof http://127.0.0.1:5959
Fetching profile over HTTP from http://127.0.0.1:5959/debug/pprof/profile
...
(pprof) top
Showing nodes accounting for 90ms, 100% of 90ms total
Showing top 10 nodes out of 38
      flat  flat%   sum%        cum   cum%
      40ms 44.44% 44.44%       40ms 44.44%  runtime.stdcall1
      10ms 11.11% 55.56%       10ms 11.11%  github.com/syndtr/goleveldb/leveldb.(*DB).newSnapshot
...
$ dcrctl stopprofiler
profile server stopped

$ dcrctl stopprofiler
-26: profile server is not started
# Unable to listen on non loopback addresses without flag.
$ dcrctl startprofiler :5959
-8: unable to start profile server: not permitted to listen on non loopback address ":5959" without setting the flag to allow it

$ dcrctl startprofiler :5959 true
{
  "listeners": [
    "0.0.0.0:5959",
    "[::]:5959"
  ]
}

$ dcrctl stopprofiler
profile server stopped

# Using a raw port as the address prepends "127.0.0.1:".
$ dcrctl startprofiler 5959
{
  "listeners": [
    "127.0.0.1:5959"
  ]
}