Browse Source

*: add pprof flag to grpc proxy

Xiang 8 years ago
parent
commit
fd5984af56
5 changed files with 72 additions and 14 deletions
  1. 2 1
      embed/etcd.go
  2. 4 13
      embed/serve.go
  3. 11 0
      etcdmain/grpc_proxy.go
  4. 16 0
      pkg/debugutil/doc.go
  5. 39 0
      pkg/debugutil/pprof.go

+ 2 - 1
embed/etcd.go

@@ -25,6 +25,7 @@ import (
 	"github.com/coreos/etcd/etcdserver"
 	"github.com/coreos/etcd/etcdserver"
 	"github.com/coreos/etcd/etcdserver/api/v2http"
 	"github.com/coreos/etcd/etcdserver/api/v2http"
 	"github.com/coreos/etcd/pkg/cors"
 	"github.com/coreos/etcd/pkg/cors"
+	"github.com/coreos/etcd/pkg/debugutil"
 	runtimeutil "github.com/coreos/etcd/pkg/runtime"
 	runtimeutil "github.com/coreos/etcd/pkg/runtime"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/pkg/types"
@@ -237,7 +238,7 @@ func startClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
 	}
 	}
 
 
 	if cfg.EnablePprof {
 	if cfg.EnablePprof {
-		plog.Infof("pprof is enabled under %s", pprofPrefix)
+		plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
 	}
 	}
 
 
 	sctxs = make(map[string]*serveCtx)
 	sctxs = make(map[string]*serveCtx)

+ 4 - 13
embed/serve.go

@@ -20,7 +20,6 @@ import (
 	defaultLog "log"
 	defaultLog "log"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
-	"net/http/pprof"
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
@@ -30,6 +29,7 @@ import (
 	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
 	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
 	"github.com/coreos/etcd/etcdserver/api/v3rpc"
 	"github.com/coreos/etcd/etcdserver/api/v3rpc"
 	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/pkg/debugutil"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/pkg/transport"
 
 
 	"github.com/cockroachdb/cmux"
 	"github.com/cockroachdb/cmux"
@@ -40,8 +40,6 @@ import (
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/credentials"
 )
 )
 
 
-const pprofPrefix = "/debug/pprof"
-
 type serveCtx struct {
 type serveCtx struct {
 	l        net.Listener
 	l        net.Listener
 	secure   bool
 	secure   bool
@@ -214,16 +212,9 @@ func (sctx *serveCtx) registerUserHandler(s string, h http.Handler) {
 }
 }
 
 
 func (sctx *serveCtx) registerPprof() {
 func (sctx *serveCtx) registerPprof() {
-	sctx.registerUserHandler(pprofPrefix+"/", http.HandlerFunc(pprof.Index))
-	sctx.registerUserHandler(pprofPrefix+"/profile", http.HandlerFunc(pprof.Profile))
-	sctx.registerUserHandler(pprofPrefix+"/symbol", http.HandlerFunc(pprof.Symbol))
-	sctx.registerUserHandler(pprofPrefix+"/cmdline", http.HandlerFunc(pprof.Cmdline))
-	sctx.registerUserHandler(pprofPrefix+"/trace", http.HandlerFunc(pprof.Trace))
-
-	sctx.registerUserHandler(pprofPrefix+"/heap", pprof.Handler("heap"))
-	sctx.registerUserHandler(pprofPrefix+"/goroutine", pprof.Handler("goroutine"))
-	sctx.registerUserHandler(pprofPrefix+"/threadcreate", pprof.Handler("threadcreate"))
-	sctx.registerUserHandler(pprofPrefix+"/block", pprof.Handler("block"))
+	for p, h := range debugutil.PProfHandlers() {
+		sctx.registerUserHandler(p, h)
+	}
 }
 }
 
 
 func (sctx *serveCtx) registerTrace() {
 func (sctx *serveCtx) registerTrace() {

+ 11 - 0
etcdmain/grpc_proxy.go

@@ -25,6 +25,7 @@ import (
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3/namespace"
 	"github.com/coreos/etcd/clientv3/namespace"
 	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/pkg/debugutil"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/proxy/grpcproxy"
 	"github.com/coreos/etcd/proxy/grpcproxy"
 
 
@@ -47,6 +48,8 @@ var (
 	grpcProxyResolverTTL        int
 	grpcProxyResolverTTL        int
 
 
 	grpcProxyNamespace string
 	grpcProxyNamespace string
+
+	grpcProxyEnablePprof bool
 )
 )
 
 
 func init() {
 func init() {
@@ -80,6 +83,7 @@ func newGRPCProxyStartCommand() *cobra.Command {
 	cmd.Flags().StringVar(&grpcProxyResolverPrefix, "resolver-prefix", "", "prefix to use for registering proxy (must be shared with other grpc-proxy members)")
 	cmd.Flags().StringVar(&grpcProxyResolverPrefix, "resolver-prefix", "", "prefix to use for registering proxy (must be shared with other grpc-proxy members)")
 	cmd.Flags().IntVar(&grpcProxyResolverTTL, "resolver-ttl", 0, "specify TTL, in seconds, when registering proxy endpoints")
 	cmd.Flags().IntVar(&grpcProxyResolverTTL, "resolver-ttl", 0, "specify TTL, in seconds, when registering proxy endpoints")
 	cmd.Flags().StringVar(&grpcProxyNamespace, "namespace", "", "string to prefix to all keys for namespacing requests")
 	cmd.Flags().StringVar(&grpcProxyNamespace, "namespace", "", "string to prefix to all keys for namespacing requests")
+	cmd.Flags().BoolVar(&grpcProxyEnablePprof, "enable-pprof", false, `Enable runtime profiling data via HTTP server. Address is at client URL + "/debug/pprof/"`)
 
 
 	return &cmd
 	return &cmd
 }
 }
@@ -161,6 +165,13 @@ func startGRPCProxy(cmd *cobra.Command, args []string) {
 	httpmux := http.NewServeMux()
 	httpmux := http.NewServeMux()
 	httpmux.HandleFunc("/", http.NotFound)
 	httpmux.HandleFunc("/", http.NotFound)
 	httpmux.Handle("/metrics", prometheus.Handler())
 	httpmux.Handle("/metrics", prometheus.Handler())
+	if grpcProxyEnablePprof {
+		for p, h := range debugutil.PProfHandlers() {
+			httpmux.Handle(p, h)
+		}
+		plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
+	}
+
 	srvhttp := &http.Server{
 	srvhttp := &http.Server{
 		Handler: httpmux,
 		Handler: httpmux,
 	}
 	}

+ 16 - 0
pkg/debugutil/doc.go

@@ -0,0 +1,16 @@
+// Copyright 2017 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package debugutil includes utility functions for debugging.
+package debugutil

+ 39 - 0
pkg/debugutil/pprof.go

@@ -0,0 +1,39 @@
+// Copyright 2017 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package debugutil
+
+import (
+	"net/http"
+	"net/http/pprof"
+)
+
+const HTTPPrefixPProf = "/debug/pprof"
+
+// PProfHandlers returns a map of pprof handlers keyed by the HTTP path.
+func PProfHandlers() map[string]http.Handler {
+	m := make(map[string]http.Handler)
+
+	m[HTTPPrefixPProf+"/"] = http.HandlerFunc(pprof.Index)
+	m[HTTPPrefixPProf+"/profile"] = http.HandlerFunc(pprof.Profile)
+	m[HTTPPrefixPProf+"/symbol"] = http.HandlerFunc(pprof.Symbol)
+	m[HTTPPrefixPProf+"/cmdline"] = http.HandlerFunc(pprof.Cmdline)
+	m[HTTPPrefixPProf+"/trace "] = http.HandlerFunc(pprof.Trace)
+	m[HTTPPrefixPProf+"/heap"] = pprof.Handler("heap")
+	m[HTTPPrefixPProf+"/goroutine"] = pprof.Handler("goroutine")
+	m[HTTPPrefixPProf+"/threadcreate"] = pprof.Handler("threadcreate")
+	m[HTTPPrefixPProf+"/block"] = pprof.Handler("block")
+
+	return m
+}