Exposing pprof and expvars interfaces on default containerd socket
package main
import (
+ _ "expvar"
"fmt"
"net"
"net/http"
+ _ "net/http/pprof"
"net/url"
"os"
"os/signal"
@@ -66,6 +68,11 @@ func main() {
Usage: "socket path for containerd's GRPC server",
Value: "/run/containerd/containerd.sock",
},
+ cli.StringFlag{
+ Name: "debug-socket, d",
+ Usage: "socket path for containerd's debug server",
+ Value: "/run/containerd/containerd-debug.sock",
+ },
cli.StringFlag{
Name: "metrics-address, m",
Usage: "tcp address to serve metrics on",
@@ -101,6 +108,21 @@ func main() {
}
defer s.Shutdown()
+ debugPath := context.GlobalString("debug-socket")
+ if debugPath == "" {
+ return fmt.Errorf("--debug-socket path cannot be empty")
+ }
+ d, err := utils.CreateUnixSocket(debugPath)
+ if err != nil {
+ return err
+ }
+
+ //publish profiling and debug socket.
+ log.G(ctx).WithField("socket", debugPath).Info("starting profiler handlers")
+ log.G(ctx).WithFields(logrus.Fields{"expvars": "/debug/vars", "socket": debugPath}).Debug("serving expvars requests")
+ log.G(ctx).WithFields(logrus.Fields{"pprof": "/debug/pprof", "socket": debugPath}).Debug("serving pprof requests")
+ go serveProfiler(ctx, d)
+
path := context.GlobalString("socket")
if path == "" {
return fmt.Errorf("--socket path cannot be empty")
@@ -194,6 +216,12 @@ func serveGRPC(ctx gocontext.Context, server *grpc.Server, l net.Listener) {
}
}
+func serveProfiler(ctx gocontext.Context, l net.Listener) {
+ if err := http.Serve(l, nil); err != nil {
+ log.G(ctx).WithError(err).Fatal("profiler server failure")
+ }
+}
+
// DumpStacks dumps the runtime stack.
func dumpStacks(ctx gocontext.Context) {
var (
