瀏覽代碼

Merge pull request #7273 from heyitsanthony/snip-prom

clientv3: add DialOptions to config
Anthony Romano 9 年之前
父節點
當前提交
23b5a29101
共有 4 個文件被更改,包括 66 次插入18 次删除
  1. 1 4
      clientv3/client.go
  2. 5 0
      clientv3/config.go
  3. 44 6
      clientv3/example_metrics_test.go
  4. 16 8
      clientv3/integration/metrics_test.go

+ 1 - 4
clientv3/client.go

@@ -25,7 +25,6 @@ import (
 	"time"
 
 	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
-	prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
@@ -281,9 +280,7 @@ func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientCo
 		opts = append(opts, grpc.WithPerRPCCredentials(c.tokenCred))
 	}
 
-	// add metrics options
-	opts = append(opts, grpc.WithUnaryInterceptor(prometheus.UnaryClientInterceptor))
-	opts = append(opts, grpc.WithStreamInterceptor(prometheus.StreamClientInterceptor))
+	opts = append(opts, c.cfg.DialOptions...)
 
 	conn, err := grpc.Dial(host, opts...)
 	if err != nil {

+ 5 - 0
clientv3/config.go

@@ -17,6 +17,8 @@ package clientv3
 import (
 	"crypto/tls"
 	"time"
+
+	"google.golang.org/grpc"
 )
 
 type Config struct {
@@ -38,4 +40,7 @@ type Config struct {
 
 	// Password is a password for authentication.
 	Password string `json:"password"`
+
+	// DialOptions is a list of dial options for the grpc client (e.g., for interceptors).
+	DialOptions []grpc.DialOption
 }

+ 44 - 6
clientv3/example_metrics_test.go

@@ -18,21 +18,51 @@ import (
 	"fmt"
 	"io/ioutil"
 	"log"
+	"net"
 	"net/http"
+	"strings"
 
+	"github.com/coreos/etcd/clientv3"
+
+	grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/prometheus/client_golang/prometheus"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
 )
 
-func ExampleMetrics_All() {
+func ExampleMetrics_range() {
+	cli, err := clientv3.New(clientv3.Config{
+		Endpoints: endpoints,
+		DialOptions: []grpc.DialOption{
+			grpc.WithUnaryInterceptor(grpcprom.UnaryClientInterceptor),
+			grpc.WithStreamInterceptor(grpcprom.StreamClientInterceptor),
+		},
+	})
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer cli.Close()
+
+	// get a key so it shows up in the metrics as a range rpc
+	cli.Get(context.TODO(), "test_key")
+
 	// listen for all prometheus metrics
+	ln, err := net.Listen("tcp", ":47989")
+	if err != nil {
+		log.Fatal(err)
+	}
+	donec := make(chan struct{})
 	go func() {
-		http.Handle("/metrics", prometheus.Handler())
-		log.Fatal(http.ListenAndServe(":47989", nil))
+		defer close(donec)
+		http.Serve(ln, prometheus.Handler())
+	}()
+	defer func() {
+		ln.Close()
+		<-donec
 	}()
-
-	url := "http://localhost:47989/metrics"
 
 	// make an http request to fetch all prometheus metrics
+	url := "http://localhost:47989/metrics"
 	resp, err := http.Get(url)
 	if err != nil {
 		log.Fatalf("fetch error: %v", err)
@@ -42,5 +72,13 @@ func ExampleMetrics_All() {
 	if err != nil {
 		log.Fatalf("fetch error: reading %s: %v", url, err)
 	}
-	fmt.Printf("%s", b)
+
+	// confirm range request in metrics
+	for _, l := range strings.Split(string(b), "\n") {
+		if strings.Contains(l, `grpc_client_started_total{grpc_method="Range"`) {
+			fmt.Println(l)
+			break
+		}
+	}
+	// Output: grpc_client_started_total{grpc_method="Range",grpc_service="etcdserverpb.KV",grpc_type="unary"} 1
 }

+ 16 - 8
clientv3/integration/metrics_test.go

@@ -29,8 +29,10 @@ import (
 	"github.com/coreos/etcd/pkg/testutil"
 	"github.com/coreos/etcd/pkg/transport"
 
+	grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/prometheus/client_golang/prometheus"
 	"golang.org/x/net/context"
+	"google.golang.org/grpc"
 )
 
 func TestV3ClientMetrics(t *testing.T) {
@@ -66,20 +68,26 @@ func TestV3ClientMetrics(t *testing.T) {
 	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
 	defer clus.Terminate(t)
 
-	client := clus.Client(0)
-
-	w := clientv3.NewWatcher(client)
-	defer w.Close()
-
-	kv := clientv3.NewKV(client)
+	cfg := clientv3.Config{
+		Endpoints: []string{clus.Members[0].GRPCAddr()},
+		DialOptions: []grpc.DialOption{
+			grpc.WithUnaryInterceptor(grpcprom.UnaryClientInterceptor),
+			grpc.WithStreamInterceptor(grpcprom.StreamClientInterceptor),
+		},
+	}
+	cli, cerr := clientv3.New(cfg)
+	if cerr != nil {
+		t.Fatal(cerr)
+	}
+	defer cli.Close()
 
-	wc := w.Watch(context.Background(), "foo")
+	wc := cli.Watch(context.Background(), "foo")
 
 	wBefore := sumCountersForMetricAndLabels(t, url, "grpc_client_msg_received_total", "Watch", "bidi_stream")
 
 	pBefore := sumCountersForMetricAndLabels(t, url, "grpc_client_started_total", "Put", "unary")
 
-	_, err = kv.Put(context.Background(), "foo", "bar")
+	_, err = cli.Put(context.Background(), "foo", "bar")
 	if err != nil {
 		t.Errorf("Error putting value in key store")
 	}