Skip to content

Commit c533a0e

Browse files
authored
feat: add pprof to flintlock (#504)
This change adds the ability to make pprof available via http. By default it won't be available. If you specify a debug endpoint via `--debug-endpoint` then it will start a webserver listening at that endpoint and pprof is available from there. We decided to use an endpoint as that will allow users to only expose the debug endpoint locally or via the network. Signed-off-by: Richard Case <richard.case@outlook.com>
1 parent 95c2fd2 commit c533a0e

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

internal/command/flags/flags.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const (
2727
tlsKeyFlag = "tls-key"
2828
tlsClientValidateFlag = "tls-client-validate"
2929
tlsClientCAFlag = "tls-client-ca"
30+
debugEndpointFlag = "debug-endpoint"
3031
)
3132

3233
// AddGRPCServerFlagsToCommand will add gRPC server flags to the supplied command.
@@ -178,3 +179,10 @@ func AddContainerDFlagsToCommand(cmd *cobra.Command, cfg *config.Config) {
178179
defaults.ContainerdNamespace,
179180
"The name of the containerd namespace to use.")
180181
}
182+
183+
func AddDebugFlagsToCommand(cmd *cobra.Command, cfg *config.Config) {
184+
cmd.Flags().StringVar(&cfg.DebugEndpoint,
185+
debugEndpointFlag,
186+
"",
187+
"The endpoint for the debug web server to listen on. It must include a port (e.g. localhost:10500). An empty string means disable the debug endpoint.")
188+
}

internal/command/run/run.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"os"
1010
"os/signal"
1111
"sync"
12+
"time"
13+
14+
_ "net/http/pprof"
1215

1316
grpc_mw "github.com/grpc-ecosystem/go-grpc-middleware"
1417
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
@@ -59,6 +62,7 @@ func NewCommand(cfg *config.Config) (*cobra.Command, error) {
5962
cmdflags.AddTLSFlagsToCommand(cmd, cfg)
6063
cmdflags.AddContainerDFlagsToCommand(cmd, cfg)
6164
cmdflags.AddFirecrackerFlagsToCommand(cmd, cfg)
65+
cmdflags.AddDebugFlagsToCommand(cmd, cfg)
6266

6367
if err := cmdflags.AddNetworkFlagsToCommand(cmd, cfg); err != nil {
6468
return nil, fmt.Errorf("adding network flags to run command: %w", err)
@@ -81,6 +85,18 @@ func runServer(ctx context.Context, cfg *config.Config) error {
8185
wg := &sync.WaitGroup{}
8286
ctx, cancel := context.WithCancel(log.WithLogger(ctx, logger))
8387

88+
if cfg.DebugEndpoint != "" {
89+
wg.Add(1)
90+
91+
go func() {
92+
defer wg.Done()
93+
94+
if err := runPProf(ctx, cfg); err != nil {
95+
logger.Errorf("failed serving api: %v", err)
96+
}
97+
}()
98+
}
99+
84100
if !cfg.DisableAPI {
85101
wg.Add(1)
86102

@@ -225,3 +241,33 @@ func generateOpts(ctx context.Context, cfg *config.Config) ([]grpc.ServerOption,
225241

226242
return opts, nil
227243
}
244+
245+
func runPProf(ctx context.Context, cfg *config.Config) error {
246+
logger := log.GetLogger(ctx)
247+
logger.Warnf("Debug endpoint is ENABLED at %s", cfg.DebugEndpoint)
248+
249+
srv := &http.Server{
250+
Addr: cfg.DebugEndpoint,
251+
Handler: http.DefaultServeMux,
252+
}
253+
254+
go func() {
255+
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
256+
logger.Fatalf("starting debug endpoint: %v", err)
257+
}
258+
}()
259+
260+
<-ctx.Done()
261+
logger.Debug("Exiting")
262+
263+
shutDownCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
264+
defer func() {
265+
cancel()
266+
}()
267+
268+
if err := srv.Shutdown(shutDownCtx); err != nil {
269+
logger.Warnf("Debug server shutdown failed:%+v", err)
270+
}
271+
272+
return nil
273+
}

internal/config/config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type Config struct {
1414
Logging log.Config
1515
// GRPCEndpoint is the endpoint for the gRPC server.
1616
GRPCAPIEndpoint string
17-
// HTTPAPIEndpoint is the endpoint for the HTTP proxy for the gRPC service..
17+
// HTTPAPIEndpoint is the endpoint for the HTTP proxy for the gRPC service
1818
HTTPAPIEndpoint string
1919
// FirecrackerBin is the firecracker binary to use.
2020
FirecrackerBin string
@@ -46,6 +46,8 @@ type Config struct {
4646
BasicAuthToken string
4747
// TLS holds the TLS related configuration.
4848
TLS TLSConfig
49+
// DebugEndpoint is the endpoint for the debug web server. An empty string means disable the debug endpoint.
50+
DebugEndpoint string
4951
}
5052

5153
// TLSConfig holds the configuration for TLS.

0 commit comments

Comments
 (0)