Skip to content

Commit 9aafe95

Browse files
authored
chore: add pprof and debug docs (#72)
* chore: add pprof and debug docs Signed-off-by: Justin Alvarez <[email protected]> * update docs Signed-off-by: Justin Alvarez <[email protected]> --------- Signed-off-by: Justin Alvarez <[email protected]>
1 parent ad26173 commit 9aafe95

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

cmd/finch-daemon/main.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import (
1717
"syscall"
1818
"time"
1919

20+
// #nosec
21+
// register HTTP handler for /debug/pprof on the DefaultServeMux.
22+
_ "net/http/pprof"
23+
2024
"github.com/containerd/containerd"
2125
"github.com/containerd/nerdctl/pkg/api/types"
2226
"github.com/containerd/nerdctl/pkg/config"
@@ -47,9 +51,10 @@ const (
4751
)
4852

4953
type DaemonOptions struct {
50-
debug bool
51-
socketAddr string
52-
socketOwner int
54+
debug bool
55+
socketAddr string
56+
socketOwner int
57+
debugAddress string
5358
}
5459

5560
var options = new(DaemonOptions)
@@ -65,6 +70,7 @@ func main() {
6570
rootCmd.Flags().StringVar(&options.socketAddr, "socket-addr", defaultFinchAddr, "server listening Unix socket address")
6671
rootCmd.Flags().BoolVar(&options.debug, "debug", false, "turn on debug log level")
6772
rootCmd.Flags().IntVar(&options.socketOwner, "socket-owner", -1, "Uid and Gid of the server socket")
73+
rootCmd.Flags().StringVar(&options.debugAddress, "debug-addr", "", "")
6874
if err := rootCmd.Execute(); err != nil {
6975
log.Printf("got error: %v", err)
7076
log.Fatal(err)
@@ -99,6 +105,24 @@ func run(options *DaemonOptions) error {
99105
if err := os.Chown(options.socketAddr, options.socketOwner, options.socketOwner); err != nil {
100106
return fmt.Errorf("failed to chown the finch-daemon socket: %w", err)
101107
}
108+
109+
if options.debugAddress != "" {
110+
logger.Infof("Serving debugging endpoint on %q", options.debugAddress)
111+
go func() {
112+
debugListener, err := net.Listen("tcp", options.debugAddress)
113+
if err != nil {
114+
logger.Fatal(err)
115+
}
116+
debugServer := &http.Server{
117+
Handler: http.DefaultServeMux,
118+
ReadHeaderTimeout: 5 * time.Second,
119+
}
120+
if err := debugServer.Serve(debugListener); err != nil && !errors.Is(err, http.ErrServerClosed) {
121+
logger.Fatal(err)
122+
}
123+
}()
124+
}
125+
102126
server := &http.Server{
103127
Handler: r,
104128
ReadHeaderTimeout: 5 * time.Minute,

docs/debug.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Debugging the finch daemon
2+
3+
This document outlines where to find/access logs and how to configure profiling tools for finch daemon.
4+
5+
## Logs
6+
7+
Logs are the first place to check when you suspect a problem with finch-daemon. If `finch-daemon` was started via `systemd` then you can obtain logs using `journalctl`:
8+
9+
```shell
10+
sudo journalctl -u finch
11+
```
12+
13+
> **Note**
14+
> The command above assumes that you have used the unit file definition [finch.service](../finch.service) we have provided. If you have created your own unit file for `finch-daemon` and replace `finch-daemon` with the one you have made. Amazon Linux distributions of Finch also use the name `finch` for the finch-daemon service.
15+
16+
If you have started `finch-daemon` manually, logs will either be emitted to stderr/stdout.
17+
18+
## CPU Profiling
19+
20+
We can use Golangs `pprof` tool to profile the daemon. To enable profiling you must set the `--debug-addr` CLI parameter when invoking `finch-daemon`:
21+
22+
```shell
23+
./finch-daemon --debug-addr localhost:6060
24+
```
25+
26+
> **Note**
27+
> Similarly to adding the command line option for a local run of finch-daemon, any systemd service file can also be modified to include the `--debug-addr` option.
28+
29+
30+
Once you have configured the debug address you can send a `GET` to the `/debug/pprof/profile` endpoint to receive a CPU profile of the daemon. You can specify an optional argument `seconds` to limit the results to a certain time span:
31+
32+
```shell
33+
curl http://localhost:6060/debug/pprof/profile?seconds=40 > out.pprof
34+
```
35+
36+
You can use the `pprof` tool provided by the Go CLI to visualize the data within a web browser:
37+
38+
```shell
39+
go tool pprof -http=:8080 out.pprof
40+
```
41+
42+
For more information on pprof, [see its documentation here](https://pkg.go.dev/net/http/pprof).

0 commit comments

Comments
 (0)