diff --git a/Makefile b/Makefile index 41a6cf40fd7..1298894b476 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ TOP_PKGS := $(shell glide novendor | \ grep -v \ -e ./thrift-gen/... \ -e ./swagger-gen/... \ + -e ./proto-gen/... \ -e ./examples/... \ -e ./scripts/...\ ) @@ -17,6 +18,7 @@ ALL_SRC := $(shell find . -name "*.go" | \ -e vendor \ -e /thrift-gen/ \ -e /swagger-gen/ \ + -e /proto-gen/ \ -e /examples/ \ -e doc.go \ -e model.pb.go \ @@ -335,6 +337,20 @@ generate-mocks: install-mockery echo-version: @echo $(GIT_CLOSEST_TAG) +PROTO_INCLUDES := \ + -I model/proto \ + -I vendor/github.com/grpc-ecosystem/grpc-gateway \ + -I vendor/github.com/gogo/googleapis \ + -I vendor/github.com/gogo/protobuf +# Remapping of std types to gogo types (must not contain spaces) +PROTO_GOGO_MAPPINGS := $(shell echo \ + Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types, \ + Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types, \ + Mgoogle/protobuf/empty.proto=github.com/gogo/protobuf/types, \ + Mgoogle/api/annotations.proto=github.com/gogo/googleapis/google/api, \ + Mmodel.proto=github.com/jaegertracing/jaeger/model \ + | sed 's/ //g') + .PHONY: proto proto: # Generate gogo, gRPC-Gateway, swagger, go-validators output. @@ -362,31 +378,25 @@ proto: # (https://medium.com/@linchenon/generate-grpc-and-protobuf-libraries-with-containers-c15ba4e4f3ad) # protoc \ - -I model/proto \ - -I vendor/github.com/grpc-ecosystem/grpc-gateway/ \ - -I vendor/github.com/gogo/googleapis/ \ - -I vendor/ \ - --gogo_out=plugins=grpc,\ -Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,\ -Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,\ -Mgoogle/protobuf/empty.proto=github.com/gogo/protobuf/types,\ -Mgoogle/api/annotations.proto=github.com/gogo/googleapis/google/api:\ -$$GOPATH/src/github.com/jaegertracing/jaeger/model/ \ - --grpc-gateway_out=\ -Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,\ -Mgoogle/protobuf/empty.proto=github.com/gogo/protobuf/types,\ -Mgoogle/api/annotations.proto=github.com/gogo/googleapis/google/api:\ -$$GOPATH/src/github.com/jaegertracing/jaeger/model \ - --swagger_out=model/proto/openapi/ \ + $(PROTO_INCLUDES) \ + --gogo_out=plugins=grpc,$(PROTO_GOGO_MAPPINGS):$(PWD)/model/ \ model/proto/model.proto + protoc \ + $(PROTO_INCLUDES) \ + --gogo_out=plugins=grpc,$(PROTO_GOGO_MAPPINGS):$(PWD)/proto-gen/api_v2/ \ + --grpc-gateway_out=$(PROTO_GOGO_MAPPINGS):$(PWD)/proto-gen/api_v2/ \ + --swagger_out=$(PWD)/proto-gen/openapi/ \ + model/proto/api_v2.proto + protoc \ -I model/proto \ - --go_out=$$GOPATH/src/github.com/jaegertracing/jaeger/model/prototest/ \ + --go_out=$(PWD)/model/prototest/ \ model/proto/model_test.proto .PHONY: proto-install proto-install: + go get -u github.com/golang/glog go install \ ./vendor/github.com/golang/protobuf/protoc-gen-go \ ./vendor/github.com/gogo/protobuf/protoc-gen-gogo \ diff --git a/cmd/agent/app/agent_test.go b/cmd/agent/app/agent_test.go index 0d9612f1d20..804d41425eb 100644 --- a/cmd/agent/app/agent_test.go +++ b/cmd/agent/app/agent_test.go @@ -65,7 +65,7 @@ func TestAgentSamplingEndpoint(t *testing.T) { require.NoError(t, err) body, err := ioutil.ReadAll(resp.Body) assert.NoError(t, err) - assert.Equal(t, "tcollector error: no peers available\n", string(body)) + assert.Equal(t, "collector error: no peers available\n", string(body)) }) } diff --git a/cmd/agent/app/flags.go b/cmd/agent/app/flags.go index f9b5dbde689..a9341f80c20 100644 --- a/cmd/agent/app/flags.go +++ b/cmd/agent/app/flags.go @@ -51,7 +51,7 @@ func AddFlags(flags *flag.FlagSet) { flags.String( httpServerHostPort, defaultHTTPServerHostPort, - "host:port of the http server (e.g. for /sampling point and /baggage endpoint)") + "host:port of the http server (e.g. for /sampling point and /baggageRestrictions endpoint)") } // InitFromViper initializes Builder with properties retrieved from Viper. diff --git a/cmd/agent/app/httpserver/server.go b/cmd/agent/app/httpserver/server.go index 18c11a4143c..68df255ef1e 100644 --- a/cmd/agent/app/httpserver/server.go +++ b/cmd/agent/app/httpserver/server.go @@ -108,7 +108,7 @@ func (h *httpHandler) serveSamplingHTTP(w http.ResponseWriter, r *http.Request, resp, err := h.manager.GetSamplingStrategy(service) if err != nil { h.metrics.TCollectorProxyFailures.Inc(1) - http.Error(w, fmt.Sprintf("tcollector error: %+v", err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("collector error: %+v", err), http.StatusInternalServerError) return } jsonBytes, err := json.Marshal(resp) @@ -138,7 +138,7 @@ func (h *httpHandler) serveBaggageHTTP(w http.ResponseWriter, r *http.Request) { resp, err := h.manager.GetBaggageRestrictions(service) if err != nil { h.metrics.TCollectorProxyFailures.Inc(1) - http.Error(w, fmt.Sprintf("tcollector error: %+v", err), http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("collector error: %+v", err), http.StatusInternalServerError) return } // NB. it's literally impossible for this Marshal to fail diff --git a/cmd/agent/app/httpserver/server_test.go b/cmd/agent/app/httpserver/server_test.go index 12006d34681..3c744f98640 100644 --- a/cmd/agent/app/httpserver/server_test.go +++ b/cmd/agent/app/httpserver/server_test.go @@ -146,10 +146,10 @@ func TestHTTPHandlerErrors(t *testing.T) { }, }, { - description: "sampler tcollector error", + description: "sampler collector error", url: "?service=Y", statusCode: http.StatusInternalServerError, - body: "tcollector error: no mock response provided\n", + body: "collector error: no mock response provided\n", metrics: []mTestutils.ExpectedMetric{ {Name: "http-server.errors", Tags: map[string]string{"source": "tcollector-proxy", "status": "5xx"}, Value: 1}, }, @@ -158,7 +158,7 @@ func TestHTTPHandlerErrors(t *testing.T) { description: "baggage tcollector error", url: "/baggageRestrictions?service=Y", statusCode: http.StatusInternalServerError, - body: "tcollector error: no mock response provided\n", + body: "collector error: no mock response provided\n", metrics: []mTestutils.ExpectedMetric{ {Name: "http-server.errors", Tags: map[string]string{"source": "tcollector-proxy", "status": "5xx"}, Value: 1}, }, diff --git a/cmd/agent/app/reporter/flags.go b/cmd/agent/app/reporter/flags.go new file mode 100644 index 00000000000..fa6aa44e788 --- /dev/null +++ b/cmd/agent/app/reporter/flags.go @@ -0,0 +1,49 @@ +// Copyright (c) 2018 The Jaeger 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 reporter + +import ( + "flag" + "fmt" + + "github.com/spf13/viper" +) + +const ( + reporterType = "reporter.type" + // TCHANNEL is name of tchannel reporter. + TCHANNEL Type = "tchannel" + // GRPC is name of gRPC reporter. + GRPC Type = "grpc" +) + +// Type defines type of reporter. +type Type string + +// Options holds generic reporter configuration. +type Options struct { + ReporterType Type +} + +// AddFlags adds flags for Options. +func AddFlags(flags *flag.FlagSet) { + flags.String(reporterType, string(TCHANNEL), fmt.Sprintf("Reporter type to use e.g. %s, %s", string(TCHANNEL), string(GRPC))) +} + +// InitFromViper initializes Options with properties retrieved from Viper. +func (b *Options) InitFromViper(v *viper.Viper) *Options { + b.ReporterType = Type(v.GetString(reporterType)) + return b +} diff --git a/cmd/agent/app/reporter/flags_test.go b/cmd/agent/app/reporter/flags_test.go new file mode 100644 index 00000000000..e47b236581d --- /dev/null +++ b/cmd/agent/app/reporter/flags_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2018 The Jaeger 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 reporter + +import ( + "flag" + "testing" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBingFlags(t *testing.T) { + v := viper.New() + command := cobra.Command{} + flags := &flag.FlagSet{} + AddFlags(flags) + command.PersistentFlags().AddGoFlagSet(flags) + v.BindPFlags(command.PersistentFlags()) + + err := command.ParseFlags([]string{ + "--reporter.type=grpc", + }) + require.NoError(t, err) + + b := &Options{} + b.InitFromViper(v) + assert.Equal(t, Type("grpc"), b.ReporterType) +} diff --git a/cmd/agent/app/reporter/grpc/collector_proxy.go b/cmd/agent/app/reporter/grpc/collector_proxy.go new file mode 100644 index 00000000000..5046ffbdc21 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/collector_proxy.go @@ -0,0 +1,63 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/balancer/roundrobin" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/resolver/manual" + + "github.com/jaegertracing/jaeger/cmd/agent/app/httpserver" + aReporter "github.com/jaegertracing/jaeger/cmd/agent/app/reporter" +) + +// ProxyBuilder holds objects communicating with collector +type ProxyBuilder struct { + reporter aReporter.Reporter + manager httpserver.ClientConfigManager +} + +// NewCollectorProxy creates ProxyBuilder +func NewCollectorProxy(o *Options, logger *zap.Logger) *ProxyBuilder { + // It does not return error if the collector is not running + // a way to fail immediately is to call WithBlock and WithTimeout + var conn *grpc.ClientConn + if len(o.CollectorHostPort) > 1 { + r, _ := manual.GenerateAndRegisterManualResolver() + var resolvedAddrs []resolver.Address + for _, addr := range o.CollectorHostPort { + resolvedAddrs = append(resolvedAddrs, resolver.Address{Addr: addr}) + } + r.InitialAddrs(resolvedAddrs) + conn, _ = grpc.Dial(r.Scheme()+":///round_robin", grpc.WithInsecure(), grpc.WithBalancerName(roundrobin.Name)) + } else { + conn, _ = grpc.Dial(o.CollectorHostPort[0], grpc.WithInsecure()) + } + return &ProxyBuilder{ + reporter: NewReporter(conn, logger), + manager: NewSamplingManager(conn)} +} + +// GetReporter returns Reporter +func (b ProxyBuilder) GetReporter() aReporter.Reporter { + return b.reporter +} + +// GetManager returns manager +func (b ProxyBuilder) GetManager() httpserver.ClientConfigManager { + return b.manager +} diff --git a/cmd/agent/app/reporter/grpc/collector_proxy_test.go b/cmd/agent/app/reporter/grpc/collector_proxy_test.go new file mode 100644 index 00000000000..039992ac19d --- /dev/null +++ b/cmd/agent/app/reporter/grpc/collector_proxy_test.go @@ -0,0 +1,65 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/jaeger" +) + +func TestProxyBuilder(t *testing.T) { + proxy := NewCollectorProxy(&Options{CollectorHostPort: []string{"localhost:0000"}}, zap.NewNop()) + require.NotNil(t, proxy) + assert.NotNil(t, proxy.GetReporter()) + assert.NotNil(t, proxy.GetManager()) +} + +func TestMultipleCollectors(t *testing.T) { + spanHandler1 := &mockSpanHandler{} + s1, addr1 := initializeGRPCTestServer(t, func(s *grpc.Server) { + api_v2.RegisterCollectorServiceServer(s, spanHandler1) + }) + defer s1.Stop() + spanHandler2 := &mockSpanHandler{} + s2, addr2 := initializeGRPCTestServer(t, func(s *grpc.Server) { + api_v2.RegisterCollectorServiceServer(s, spanHandler2) + }) + defer s2.Stop() + + proxy := NewCollectorProxy(&Options{CollectorHostPort: []string{addr1.String(), addr2.String()}}, zap.NewNop()) + require.NotNil(t, proxy) + assert.NotNil(t, proxy.GetReporter()) + assert.NotNil(t, proxy.GetManager()) + + var bothServers = false + // TODO do not iterate, just create two batches + for i := 0; i < 10; i++ { + r := proxy.GetReporter() + err := r.EmitBatch(&jaeger.Batch{Spans: []*jaeger.Span{{OperationName: "op"}}, Process: &jaeger.Process{ServiceName: "service"}}) + require.NoError(t, err) + if len(spanHandler1.getRequests()) > 0 && len(spanHandler2.getRequests()) > 0 { + bothServers = true + break + } + } + assert.Equal(t, true, bothServers) +} diff --git a/cmd/agent/app/reporter/grpc/flags.go b/cmd/agent/app/reporter/grpc/flags.go new file mode 100644 index 00000000000..c250a599a09 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/flags.go @@ -0,0 +1,44 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "flag" + "strings" + + "github.com/spf13/viper" +) + +const ( + gRPCPrefix = "reporter.grpc." + collectorHostPort = gRPCPrefix + "host-port" +) + +// Options Struct to hold configurations +type Options struct { + // CollectorHostPort is list of host:port Jaeger Collectors. + CollectorHostPort []string +} + +// AddFlags adds flags for Options. +func AddFlags(flags *flag.FlagSet) { + flags.String(collectorHostPort, "", "(experimental) Comma-separated string representing host:port of a static list of collectors to connect to directly.") +} + +// InitFromViper initializes Options with properties retrieved from Viper. +func (o *Options) InitFromViper(v *viper.Viper) *Options { + o.CollectorHostPort = strings.Split(v.GetString(collectorHostPort), ",") + return o +} diff --git a/cmd/agent/app/reporter/grpc/flags_test.go b/cmd/agent/app/reporter/grpc/flags_test.go new file mode 100644 index 00000000000..2285b0d2681 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/flags_test.go @@ -0,0 +1,50 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "flag" + "testing" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBingFlags(t *testing.T) { + v := viper.New() + command := cobra.Command{} + flags := &flag.FlagSet{} + AddFlags(flags) + command.PersistentFlags().AddGoFlagSet(flags) + v.BindPFlags(command.PersistentFlags()) + + tests := []struct { + cOpts []string + expected *Options + }{ + {cOpts: []string{"--reporter.grpc.host-port=localhost:1111"}, + expected: &Options{CollectorHostPort: []string{"localhost:1111"}}}, + {cOpts: []string{"--reporter.grpc.host-port=localhost:1111,localhost:2222"}, + expected: &Options{CollectorHostPort: []string{"localhost:1111", "localhost:2222"}}}, + } + for _, test := range tests { + err := command.ParseFlags(test.cOpts) + require.NoError(t, err) + b := new(Options).InitFromViper(v) + assert.Equal(t, test.expected, b) + } +} diff --git a/cmd/agent/app/reporter/grpc/reporter.go b/cmd/agent/app/reporter/grpc/reporter.go new file mode 100644 index 00000000000..88d63235890 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/reporter.go @@ -0,0 +1,73 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 grpc + +import ( + "context" + + "go.uber.org/zap" + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/model" + jConverter "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" + "github.com/jaegertracing/jaeger/model/converter/thrift/zipkin" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + thrift "github.com/jaegertracing/jaeger/thrift-gen/jaeger" + "github.com/jaegertracing/jaeger/thrift-gen/zipkincore" +) + +// Reporter reports data to collector over gRPC. +type Reporter struct { + collector api_v2.CollectorServiceClient + logger *zap.Logger +} + +// NewReporter creates gRPC reporter. +func NewReporter(conn *grpc.ClientConn, logger *zap.Logger) *Reporter { + return &Reporter{ + collector: api_v2.NewCollectorServiceClient(conn), + logger: logger, + } +} + +// EmitBatch implements EmitBatch() of Reporter +func (r *Reporter) EmitBatch(b *thrift.Batch) error { + // TODO pass process to r.send() - do not convert it for every span + spans := jConverter.ToDomain(b.Spans, b.Process) + return r.send(spans) +} + +// EmitZipkinBatch implements EmitZipkinBatch() of Reporter +func (r *Reporter) EmitZipkinBatch(zSpans []*zipkincore.Span) error { + trace, err := zipkin.ToDomain(zSpans) + if err != nil { + return err + } + return r.send(trace.Spans) +} + +func (r *Reporter) send(spans []*model.Span) error { + var process model.Process + if len(spans) > 0 { + process = *spans[0].Process + } + batch := model.Batch{Spans: spans, Process: process} + req := &api_v2.PostSpansRequest{Batch: batch} + _, err := r.collector.PostSpans(context.Background(), req) + if err != nil { + r.logger.Error("Could not send spans over gRPC", zap.Error(err), zap.String("service", batch.Process.ServiceName)) + } + return err +} diff --git a/cmd/agent/app/reporter/grpc/reporter_test.go b/cmd/agent/app/reporter/grpc/reporter_test.go new file mode 100644 index 00000000000..c38e78707b0 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/reporter_test.go @@ -0,0 +1,124 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + jThrift "github.com/jaegertracing/jaeger/thrift-gen/jaeger" + "github.com/jaegertracing/jaeger/thrift-gen/zipkincore" +) + +type mockSpanHandler struct { + mux sync.Mutex + requests []*api_v2.PostSpansRequest +} + +func (h *mockSpanHandler) getRequests() []*api_v2.PostSpansRequest { + h.mux.Lock() + defer h.mux.Unlock() + return h.requests +} + +func (h *mockSpanHandler) PostSpans(c context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { + h.mux.Lock() + defer h.mux.Unlock() + h.requests = append(h.requests, r) + return &api_v2.PostSpansResponse{}, nil +} + +func TestReporter_EmitZipkinBatch(t *testing.T) { + handler := &mockSpanHandler{} + s, addr := initializeGRPCTestServer(t, func(s *grpc.Server) { + api_v2.RegisterCollectorServiceServer(s, handler) + }) + defer s.Stop() + conn, err := grpc.Dial(addr.String(), grpc.WithInsecure()) + defer conn.Close() + require.NoError(t, err) + rep := NewReporter(conn, zap.NewNop()) + + tm := time.Unix(158, 0) + a := tm.Unix() * 1000 * 1000 + tests := []struct { + in *zipkincore.Span + expected model.Batch + err string + }{ + {in: &zipkincore.Span{}, err: "Cannot find service name in Zipkin span [traceID=0, spanID=0]"}, + {in: &zipkincore.Span{Name: "jonatan", TraceID: 1, ID: 2, Timestamp: &a, Annotations: []*zipkincore.Annotation{{Value: zipkincore.CLIENT_SEND, Host: &zipkincore.Endpoint{ServiceName: "spring"}}}}, + expected: model.Batch{Process: model.Process{ServiceName: "spring"}, + Spans: []*model.Span{{TraceID: model.NewTraceID(0, 1), SpanID: model.NewSpanID(2), OperationName: "jonatan", + Tags: model.KeyValues{{Key: "span.kind", VStr: "client", VType: model.StringType}}, Process: &model.Process{ServiceName: "spring"}, StartTime: tm.UTC()}}}}, + } + for _, test := range tests { + err = rep.EmitZipkinBatch([]*zipkincore.Span{test.in}) + if test.err != "" { + assert.EqualError(t, err, test.err) + } else { + assert.Equal(t, 1, len(handler.requests)) + assert.Equal(t, test.expected, handler.requests[0].GetBatch()) + } + } +} + +func TestReporter_EmitBatch(t *testing.T) { + handler := &mockSpanHandler{} + s, addr := initializeGRPCTestServer(t, func(s *grpc.Server) { + api_v2.RegisterCollectorServiceServer(s, handler) + }) + defer s.Stop() + conn, err := grpc.Dial(addr.String(), grpc.WithInsecure()) + defer conn.Close() + require.NoError(t, err) + rep := NewReporter(conn, zap.NewNop()) + + tm := time.Unix(158, 0) + tests := []struct { + in *jThrift.Batch + expected model.Batch + err string + }{ + {in: &jThrift.Batch{Process: &jThrift.Process{ServiceName: "node"}, Spans: []*jThrift.Span{{OperationName: "foo", StartTime: int64(model.TimeAsEpochMicroseconds(tm))}}}, + expected: model.Batch{Process: model.Process{ServiceName: "node"}, Spans: []*model.Span{{OperationName: "foo", StartTime: tm.UTC(), Process: &model.Process{ServiceName: "node"}}}}}, + } + for _, test := range tests { + err = rep.EmitBatch(test.in) + if test.err != "" { + assert.EqualError(t, err, test.err) + } else { + assert.Equal(t, 1, len(handler.requests)) + assert.Equal(t, test.expected, handler.requests[0].GetBatch()) + } + } +} + +func TestReporter_SendFailure(t *testing.T) { + conn, err := grpc.Dial("", grpc.WithInsecure()) + require.NoError(t, err) + rep := NewReporter(conn, zap.NewNop()) + err = rep.send(nil) + assert.EqualError(t, err, "rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp: missing address\"") +} diff --git a/cmd/agent/app/reporter/grpc/sampling_manager.go b/cmd/agent/app/reporter/grpc/sampling_manager.go new file mode 100644 index 00000000000..2bf580f2a34 --- /dev/null +++ b/cmd/agent/app/reporter/grpc/sampling_manager.go @@ -0,0 +1,53 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "context" + "errors" + + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/baggage" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +// SamplingManager returns sampling decisions from collector over gRPC. +type SamplingManager struct { + client api_v2.SamplingManagerClient +} + +// NewSamplingManager creates gRPC sampling manager. +func NewSamplingManager(conn *grpc.ClientConn) *SamplingManager { + return &SamplingManager{ + client: api_v2.NewSamplingManagerClient(conn), + } +} + +// GetSamplingStrategy returns sampling strategies from collector. +func (s *SamplingManager) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) { + r, err := s.client.GetSamplingStrategy(context.Background(), &api_v2.SamplingStrategyParameters{ServiceName: serviceName}) + if err != nil { + return nil, err + } + return jaeger.ConvertSamplingResponseFromDomain(r) +} + +// GetBaggageRestrictions returns baggage restrictions from collector. +func (s *SamplingManager) GetBaggageRestrictions(serviceName string) ([]*baggage.BaggageRestriction, error) { + return nil, errors.New("baggage not implemented") +} diff --git a/cmd/agent/app/reporter/grpc/sampling_manager_test.go b/cmd/agent/app/reporter/grpc/sampling_manager_test.go new file mode 100644 index 00000000000..d09ccefee5c --- /dev/null +++ b/cmd/agent/app/reporter/grpc/sampling_manager_test.go @@ -0,0 +1,78 @@ +// Copyright (c) 2018 The Jaeger 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 grpc + +import ( + "context" + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +func TestSamplingManager_GetSamplingStrategy(t *testing.T) { + s, addr := initializeGRPCTestServer(t, func(s *grpc.Server) { + api_v2.RegisterSamplingManagerServer(s, &mockSamplingHandler{}) + }) + conn, err := grpc.Dial(addr.String(), grpc.WithInsecure()) + defer conn.Close() + require.NoError(t, err) + defer s.GracefulStop() + manager := NewSamplingManager(conn) + resp, err := manager.GetSamplingStrategy("any") + require.NoError(t, err) + assert.Equal(t, &sampling.SamplingStrategyResponse{StrategyType: sampling.SamplingStrategyType_PROBABILISTIC}, resp) +} + +func TestSamplingManager_GetSamplingStrategy_error(t *testing.T) { + conn, err := grpc.Dial("foo", grpc.WithInsecure()) + defer conn.Close() + require.NoError(t, err) + manager := NewSamplingManager(conn) + resp, err := manager.GetSamplingStrategy("any") + require.Nil(t, resp) + assert.EqualError(t, err, "rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp: address foo: missing port in address\"") +} + +func TestSamplingManager_GetBaggageRestrictions(t *testing.T) { + manager := NewSamplingManager(nil) + rest, err := manager.GetBaggageRestrictions("foo") + require.Nil(t, rest) + assert.EqualError(t, err, "baggage not implemented") +} + +type mockSamplingHandler struct { +} + +func (*mockSamplingHandler) GetSamplingStrategy(context.Context, *api_v2.SamplingStrategyParameters) (*api_v2.SamplingStrategyResponse, error) { + return &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC}, nil +} + +func initializeGRPCTestServer(t *testing.T, beforeServe func(server *grpc.Server)) (*grpc.Server, net.Addr) { + server := grpc.NewServer() + lis, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + beforeServe(server) + go func() { + err := server.Serve(lis) + require.NoError(t, err) + }() + return server, lis.Addr() +} diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 0a0b7ecae23..a3c2d5147c1 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -16,14 +16,19 @@ package main import ( "fmt" + "io/ioutil" "os" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" + jMetrics "github.com/uber/jaeger-lib/metrics" "go.uber.org/zap" + "google.golang.org/grpc/grpclog" "github.com/jaegertracing/jaeger/cmd/agent/app" + "github.com/jaegertracing/jaeger/cmd/agent/app/reporter" + "github.com/jaegertracing/jaeger/cmd/agent/app/reporter/grpc" "github.com/jaegertracing/jaeger/cmd/agent/app/reporter/tchannel" "github.com/jaegertracing/jaeger/cmd/flags" "github.com/jaegertracing/jaeger/pkg/config" @@ -51,7 +56,6 @@ func main() { builder := &app.Builder{} builder.InitFromViper(v) - tchanRep := tchannel.NewBuilder().InitFromViper(v, logger) mBldr := new(metrics.Builder).InitFromViper(v) mFactory, err := mBldr.CreateMetricsFactory("jaeger") @@ -60,7 +64,10 @@ func main() { } mFactory = mFactory.Namespace("agent", nil) - cp, err := tchannel.NewCollectorProxy(tchanRep, mFactory, logger) + rOpts := new(reporter.Options).InitFromViper(v) + tChanOpts := new(tchannel.Builder).InitFromViper(v, logger) + grpcOpts := new(grpc.Options).InitFromViper(v) + cp, err := createCollectorProxy(rOpts, tChanOpts, grpcOpts, logger, mFactory) if err != nil { logger.Fatal("Could not create collector proxy", zap.Error(err)) } @@ -88,7 +95,9 @@ func main() { flags.AddConfigFileFlag, flags.AddLoggingFlag, app.AddFlags, + reporter.AddFlags, tchannel.AddFlags, + grpc.AddFlags, metrics.AddFlags, ) @@ -97,3 +106,21 @@ func main() { os.Exit(1) } } + +func createCollectorProxy( + opts *reporter.Options, + tchanRep *tchannel.Builder, + grpcRepOpts *grpc.Options, + logger *zap.Logger, + mFactory jMetrics.Factory, +) (app.CollectorProxy, error) { + switch opts.ReporterType { + case reporter.GRPC: + grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr)) + return grpc.NewCollectorProxy(grpcRepOpts, logger), nil + case reporter.TCHANNEL: + return tchannel.NewCollectorProxy(tchanRep, mFactory, logger) + default: + return nil, errors.New(fmt.Sprintf("unknown reporter type %s", string(opts.ReporterType))) + } +} diff --git a/cmd/all-in-one/Dockerfile b/cmd/all-in-one/Dockerfile index 271bae939fc..1798cfb342d 100644 --- a/cmd/all-in-one/Dockerfile +++ b/cmd/all-in-one/Dockerfile @@ -15,6 +15,9 @@ EXPOSE 5778 # Collector HTTP EXPOSE 14268 +# Collector gRPC +EXPOSE 14250 + # Web HTTP EXPOSE 16686 diff --git a/cmd/all-in-one/main.go b/cmd/all-in-one/main.go index 5877be903ae..3ddad11c572 100644 --- a/cmd/all-in-one/main.go +++ b/cmd/all-in-one/main.go @@ -36,13 +36,18 @@ import ( "github.com/uber/tchannel-go" "github.com/uber/tchannel-go/thrift" "go.uber.org/zap" + "google.golang.org/grpc" agentApp "github.com/jaegertracing/jaeger/cmd/agent/app" + agentRep "github.com/jaegertracing/jaeger/cmd/agent/app/reporter" + agentGrpcRep "github.com/jaegertracing/jaeger/cmd/agent/app/reporter/grpc" agentTchanRep "github.com/jaegertracing/jaeger/cmd/agent/app/reporter/tchannel" basic "github.com/jaegertracing/jaeger/cmd/builder" collectorApp "github.com/jaegertracing/jaeger/cmd/collector/app" collector "github.com/jaegertracing/jaeger/cmd/collector/app/builder" + "github.com/jaegertracing/jaeger/cmd/collector/app/grpcserver" "github.com/jaegertracing/jaeger/cmd/collector/app/sampling" + "github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore" "github.com/jaegertracing/jaeger/cmd/collector/app/zipkin" "github.com/jaegertracing/jaeger/cmd/env" "github.com/jaegertracing/jaeger/cmd/flags" @@ -122,15 +127,19 @@ func main() { if err != nil { logger.Fatal("Failed to create dependency reader", zap.Error(err)) } - samplingHandler := initializeSamplingHandler(strategyStoreFactory, v, metricsFactory, logger) + + strategyStoreFactory.InitFromViper(v) + strategyStore := initSamplingStrategyStore(strategyStoreFactory, metricsFactory, logger) aOpts := new(agentApp.Builder).InitFromViper(v) - tchannelRep := agentTchanRep.NewBuilder().InitFromViper(v, logger) + repOpts := new(agentRep.Options).InitFromViper(v) + tchannelRepOpts := agentTchanRep.NewBuilder().InitFromViper(v, logger) + grpcRepOpts := new(agentGrpcRep.Options).InitFromViper(v) cOpts := new(collector.CollectorOptions).InitFromViper(v) qOpts := new(queryApp.QueryOptions).InitFromViper(v) - startAgent(aOpts, tchannelRep, cOpts, logger, metricsFactory) - startCollector(cOpts, spanWriter, logger, metricsFactory, samplingHandler, hc) + startAgent(aOpts, repOpts, tchannelRepOpts, grpcRepOpts, cOpts, logger, metricsFactory) + startCollector(cOpts, spanWriter, logger, metricsFactory, strategyStore, hc) startQuery(qOpts, spanReader, dependencyReader, logger, metricsFactory, mBldr, hc) hc.Ready() <-signalsChannel @@ -158,7 +167,9 @@ func main() { flags.AddFlags, storageFactory.AddFlags, agentApp.AddFlags, + agentRep.AddFlags, agentTchanRep.AddFlags, + agentGrpcRep.AddFlags, collector.AddFlags, queryApp.AddFlags, pMetrics.AddFlags, @@ -173,15 +184,16 @@ func main() { func startAgent( b *agentApp.Builder, + repOpts *agentRep.Options, tchanRep *agentTchanRep.Builder, + grpcRepOpts *agentGrpcRep.Options, cOpts *collector.CollectorOptions, logger *zap.Logger, baseFactory metrics.Factory, ) { metricsFactory := baseFactory.Namespace("agent", nil) - tchanRep.CollectorHostPorts = append(tchanRep.CollectorHostPorts, fmt.Sprintf("127.0.0.1:%d", cOpts.CollectorPort)) - cp, err := agentTchanRep.NewCollectorProxy(tchanRep, metricsFactory, logger) + cp, err := createCollectorProxy(cOpts, repOpts, tchanRep, grpcRepOpts, logger, metricsFactory) if err != nil { logger.Fatal("Could not create collector proxy", zap.Error(err)) } @@ -197,12 +209,32 @@ func startAgent( } } +func createCollectorProxy( + cOpts *collector.CollectorOptions, + repOpts *agentRep.Options, + tchanRepOpts *agentTchanRep.Builder, + grpcRepOpts *agentGrpcRep.Options, + logger *zap.Logger, + mFactory metrics.Factory, +) (agentApp.CollectorProxy, error) { + switch repOpts.ReporterType { + case agentRep.GRPC: + grpcRepOpts.CollectorHostPort = append(grpcRepOpts.CollectorHostPort, fmt.Sprintf("127.0.0.1:%d", cOpts.CollectorGRPCPort)) + return agentGrpcRep.NewCollectorProxy(grpcRepOpts, logger), nil + case agentRep.TCHANNEL: + tchanRepOpts.CollectorHostPorts = append(tchanRepOpts.CollectorHostPorts, fmt.Sprintf("127.0.0.1:%d", cOpts.CollectorPort)) + return agentTchanRep.NewCollectorProxy(tchanRepOpts, mFactory, logger) + default: + return nil, errors.New(fmt.Sprintf("unknown reporter type %s", string(repOpts.ReporterType))) + } +} + func startCollector( cOpts *collector.CollectorOptions, spanWriter spanstore.Writer, logger *zap.Logger, baseFactory metrics.Factory, - samplingHandler sampling.Handler, + strategyStore strategystore.StrategyStore, hc *healthcheck.HealthCheck, ) { metricsFactory := baseFactory.Namespace("collector", nil) @@ -216,38 +248,51 @@ func startCollector( if err != nil { logger.Fatal("Unable to set up builder", zap.Error(err)) } - ch, err := tchannel.NewChannel("jaeger-collector", &tchannel.ChannelOptions{}) - if err != nil { - logger.Fatal("Unable to create new TChannel", zap.Error(err)) + + zipkinSpansHandler, jaegerBatchesHandler, grpcHandler := spanBuilder.BuildHandlers() + + { + ch, err := tchannel.NewChannel("jaeger-collector", &tchannel.ChannelOptions{}) + if err != nil { + logger.Fatal("Unable to create new TChannel", zap.Error(err)) + } + server := thrift.NewServer(ch) + server.Register(jc.NewTChanCollectorServer(jaegerBatchesHandler)) + server.Register(zc.NewTChanZipkinCollectorServer(zipkinSpansHandler)) + server.Register(sc.NewTChanSamplingManagerServer(sampling.NewHandler(strategyStore))) + portStr := ":" + strconv.Itoa(cOpts.CollectorPort) + listener, err := net.Listen("tcp", portStr) + if err != nil { + logger.Fatal("Unable to start listening on channel", zap.Error(err)) + } + logger.Info("Starting jaeger-collector TChannel server", zap.Int("port", cOpts.CollectorPort)) + ch.Serve(listener) } - server := thrift.NewServer(ch) - zipkinSpansHandler, jaegerBatchesHandler := spanBuilder.BuildHandlers() - server.Register(jc.NewTChanCollectorServer(jaegerBatchesHandler)) - server.Register(zc.NewTChanZipkinCollectorServer(zipkinSpansHandler)) - server.Register(sc.NewTChanSamplingManagerServer(samplingHandler)) - portStr := ":" + strconv.Itoa(cOpts.CollectorPort) - listener, err := net.Listen("tcp", portStr) - if err != nil { - logger.Fatal("Unable to start listening on channel", zap.Error(err)) + + { + grpcserver.StartGRPCCollector(cOpts.CollectorGRPCPort, grpc.NewServer(), grpcHandler, strategyStore, logger, + func(err error) { + logger.Fatal("gRPC collector failed", zap.Error(err)) + }) } - ch.Serve(listener) - logger.Info("Starting jaeger-collector TChannel server", zap.Int("port", cOpts.CollectorPort)) - r := mux.NewRouter() - apiHandler := collectorApp.NewAPIHandler(jaegerBatchesHandler) - apiHandler.RegisterRoutes(r) - httpPortStr := ":" + strconv.Itoa(cOpts.CollectorHTTPPort) - recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true) + { + r := mux.NewRouter() + apiHandler := collectorApp.NewAPIHandler(jaegerBatchesHandler) + apiHandler.RegisterRoutes(r) + httpPortStr := ":" + strconv.Itoa(cOpts.CollectorHTTPPort) + recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true) - go startZipkinHTTPAPI(logger, cOpts.CollectorZipkinHTTPPort, zipkinSpansHandler, recoveryHandler) + go startZipkinHTTPAPI(logger, cOpts.CollectorZipkinHTTPPort, zipkinSpansHandler, recoveryHandler) - logger.Info("Starting jaeger-collector HTTP server", zap.Int("http-port", cOpts.CollectorHTTPPort)) - go func() { - if err := http.ListenAndServe(httpPortStr, recoveryHandler(r)); err != nil { - logger.Fatal("Could not launch jaeger-collector HTTP server", zap.Error(err)) - } - hc.Set(healthcheck.Unavailable) - }() + logger.Info("Starting jaeger-collector HTTP server", zap.Int("http-port", cOpts.CollectorHTTPPort)) + go func() { + if err := http.ListenAndServe(httpPortStr, recoveryHandler(r)); err != nil { + logger.Fatal("Could not launch jaeger-collector HTTP server", zap.Error(err)) + } + hc.Set(healthcheck.Unavailable) + }() + } } func startZipkinHTTPAPI( @@ -326,13 +371,11 @@ func startQuery( }() } -func initializeSamplingHandler( +func initSamplingStrategyStore( samplingStrategyStoreFactory *ss.Factory, - v *viper.Viper, metricsFactory metrics.Factory, logger *zap.Logger, -) sampling.Handler { - samplingStrategyStoreFactory.InitFromViper(v) +) strategystore.StrategyStore { if err := samplingStrategyStoreFactory.Initialize(metricsFactory, logger); err != nil { logger.Fatal("Failed to init sampling strategy store factory", zap.Error(err)) } @@ -340,5 +383,5 @@ func initializeSamplingHandler( if err != nil { logger.Fatal("Failed to create sampling strategy store", zap.Error(err)) } - return sampling.NewHandler(strategyStore) + return strategyStore } diff --git a/cmd/collector/Dockerfile b/cmd/collector/Dockerfile index 2015a5702cb..0c9f80d67e7 100644 --- a/cmd/collector/Dockerfile +++ b/cmd/collector/Dockerfile @@ -6,5 +6,6 @@ FROM scratch COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt EXPOSE 14267 +EXPOSE 14250 COPY collector-linux /go/bin/ ENTRYPOINT ["/go/bin/collector-linux"] diff --git a/cmd/collector/app/builder/builder_flags.go b/cmd/collector/app/builder/builder_flags.go index 4fcfcad56c9..b33337c155d 100644 --- a/cmd/collector/app/builder/builder_flags.go +++ b/cmd/collector/app/builder/builder_flags.go @@ -23,12 +23,16 @@ import ( ) const ( - collectorQueueSize = "collector.queue-size" - collectorNumWorkers = "collector.num-workers" - collectorWriteCacheTTL = "collector.write-cache-ttl" - collectorPort = "collector.port" - collectorHTTPPort = "collector.http-port" - collectorZipkinHTTPPort = "collector.zipkin.http-port" + collectorQueueSize = "collector.queue-size" + collectorNumWorkers = "collector.num-workers" + collectorPort = "collector.port" + collectorHTTPPort = "collector.http-port" + collectorGRPCPort = "collector.grpc-port" + collectorZipkinHTTPort = "collector.zipkin.http-port" + + defaultTChannelPort = 14267 + defaultHTTPPort = 14268 + defaultGRPCPort = 14250 // CollectorDefaultHealthCheckHTTPPort is the default HTTP Port for health check CollectorDefaultHealthCheckHTTPPort = 14269 ) @@ -43,6 +47,8 @@ type CollectorOptions struct { CollectorPort int // CollectorHTTPPort is the port that the collector service listens in on for http requests CollectorHTTPPort int + // CollectorGRPCPort is the port that the collector service listens in on for gRPC requests + CollectorGRPCPort int // CollectorZipkinHTTPPort is the port that the Zipkin collector service listens in on for http requests CollectorZipkinHTTPPort int } @@ -51,9 +57,10 @@ type CollectorOptions struct { func AddFlags(flags *flag.FlagSet) { flags.Int(collectorQueueSize, app.DefaultQueueSize, "The queue size of the collector") flags.Int(collectorNumWorkers, app.DefaultNumWorkers, "The number of workers pulling items from the queue") - flags.Int(collectorPort, 14267, "The tchannel port for the collector service") - flags.Int(collectorHTTPPort, 14268, "The http port for the collector service") - flags.Int(collectorZipkinHTTPPort, 0, "The http port for the Zipkin collector service e.g. 9411") + flags.Int(collectorPort, defaultTChannelPort, "The TChannel port for the collector service") + flags.Int(collectorHTTPPort, defaultHTTPPort, "The HTTP port for the collector service") + flags.Int(collectorGRPCPort, defaultGRPCPort, "(experimental) The gRPC port for the collector service") + flags.Int(collectorZipkinHTTPort, 0, "The HTTP port for the Zipkin collector service e.g. 9411") } // InitFromViper initializes CollectorOptions with properties from viper @@ -62,6 +69,7 @@ func (cOpts *CollectorOptions) InitFromViper(v *viper.Viper) *CollectorOptions { cOpts.NumWorkers = v.GetInt(collectorNumWorkers) cOpts.CollectorPort = v.GetInt(collectorPort) cOpts.CollectorHTTPPort = v.GetInt(collectorHTTPPort) - cOpts.CollectorZipkinHTTPPort = v.GetInt(collectorZipkinHTTPPort) + cOpts.CollectorGRPCPort = v.GetInt(collectorGRPCPort) + cOpts.CollectorZipkinHTTPPort = v.GetInt(collectorZipkinHTTPort) return cOpts } diff --git a/cmd/collector/app/builder/span_handler_builder.go b/cmd/collector/app/builder/span_handler_builder.go index a6ede197db2..3a5d4f0ff5e 100644 --- a/cmd/collector/app/builder/span_handler_builder.go +++ b/cmd/collector/app/builder/span_handler_builder.go @@ -57,7 +57,11 @@ func NewSpanHandlerBuilder(cOpts *CollectorOptions, spanWriter spanstore.Writer, } // BuildHandlers builds span handlers (Zipkin, Jaeger) -func (spanHb *SpanHandlerBuilder) BuildHandlers() (app.ZipkinSpansHandler, app.JaegerBatchesHandler) { +func (spanHb *SpanHandlerBuilder) BuildHandlers() ( + app.ZipkinSpansHandler, + app.JaegerBatchesHandler, + *app.GRPCHandler, +) { hostname, _ := os.Hostname() hostMetrics := spanHb.metricsFactory.Namespace("", map[string]string{"host": hostname}) @@ -79,7 +83,8 @@ func (spanHb *SpanHandlerBuilder) BuildHandlers() (app.ZipkinSpansHandler, app.J ) return app.NewZipkinSpanHandler(spanHb.logger, spanProcessor, zSanitizer), - app.NewJaegerSpanHandler(spanHb.logger, spanProcessor) + app.NewJaegerSpanHandler(spanHb.logger, spanProcessor), + app.NewGRPCHandler(spanHb.logger, spanProcessor) } func defaultSpanFilter(*model.Span) bool { diff --git a/cmd/collector/app/builder/span_handler_builder_test.go b/cmd/collector/app/builder/span_handler_builder_test.go index bc41e6cf89f..c1cdaeef51a 100644 --- a/cmd/collector/app/builder/span_handler_builder_test.go +++ b/cmd/collector/app/builder/span_handler_builder_test.go @@ -44,9 +44,10 @@ func TestNewSpanHandlerBuilder(t *testing.T) { ) require.NoError(t, err) assert.NotNil(t, handler) - zipkin, jaeger := handler.BuildHandlers() + zipkin, jaeger, grpc := handler.BuildHandlers() assert.NotNil(t, zipkin) assert.NotNil(t, jaeger) + assert.NotNil(t, grpc) } func TestDefaultSpanFilter(t *testing.T) { diff --git a/cmd/collector/app/grpc_handler.go b/cmd/collector/app/grpc_handler.go new file mode 100644 index 00000000000..7d59f6268e2 --- /dev/null +++ b/cmd/collector/app/grpc_handler.go @@ -0,0 +1,52 @@ +// Copyright (c) 2018 The Jaeger 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 app + +import ( + "context" + + "go.uber.org/zap" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" +) + +// GRPCHandler implements gRPC CollectorService. +type GRPCHandler struct { + logger *zap.Logger + spanProcessor SpanProcessor +} + +// NewGRPCHandler registers routes for this handler on the given router. +func NewGRPCHandler(logger *zap.Logger, spanProcessor SpanProcessor) *GRPCHandler { + return &GRPCHandler{ + logger: logger, + spanProcessor: spanProcessor, + } +} + +// PostSpans implements gRPC CollectorService. +func (g *GRPCHandler) PostSpans(ctx context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { + for _, span := range r.GetBatch().Spans { + if span.GetProcess() == nil { + span.Process = &r.Batch.Process + } + } + _, err := g.spanProcessor.ProcessSpans(r.GetBatch().Spans, JaegerFormatType) + if err != nil { + g.logger.Error("cannot process spans", zap.Error(err)) + return nil, err + } + return &api_v2.PostSpansResponse{}, nil +} diff --git a/cmd/collector/app/grpc_handler_test.go b/cmd/collector/app/grpc_handler_test.go new file mode 100644 index 00000000000..d1b1606ef24 --- /dev/null +++ b/cmd/collector/app/grpc_handler_test.go @@ -0,0 +1,131 @@ +// Copyright (c) 2018 The Jaeger 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 app + +import ( + "context" + "errors" + "net" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "google.golang.org/grpc" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" +) + +type mockSpanProcessor struct { + expectedError error + mux sync.Mutex + spans []*model.Span +} + +func (p *mockSpanProcessor) ProcessSpans(spans []*model.Span, spanFormat string) ([]bool, error) { + p.mux.Lock() + defer p.mux.Unlock() + p.spans = append(p.spans, spans...) + oks := make([]bool, len(spans)) + return oks, p.expectedError +} + +func (p *mockSpanProcessor) getSpans() []*model.Span { + p.mux.Lock() + defer p.mux.Unlock() + return p.spans +} + +func (p *mockSpanProcessor) reset() { + p.mux.Lock() + defer p.mux.Unlock() + p.spans = nil +} + +func initializeGRPCTestServer(t *testing.T, beforeServe func(s *grpc.Server)) (*grpc.Server, net.Addr) { + server := grpc.NewServer() + beforeServe(server) + lis, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + go func() { + err := server.Serve(lis) + require.NoError(t, err) + }() + return server, lis.Addr() +} + +func newClient(t *testing.T, addr net.Addr) (api_v2.CollectorServiceClient, *grpc.ClientConn) { + conn, err := grpc.Dial(addr.String(), grpc.WithInsecure()) + require.NoError(t, err) + return api_v2.NewCollectorServiceClient(conn), conn +} + +func TestPostSpans(t *testing.T) { + processor := &mockSpanProcessor{} + server, addr := initializeGRPCTestServer(t, func(s *grpc.Server) { + handler := NewGRPCHandler(zap.NewNop(), processor) + api_v2.RegisterCollectorServiceServer(s, handler) + }) + defer server.Stop() + client, conn := newClient(t, addr) + defer conn.Close() + + tests := []struct { + batch model.Batch + expected []*model.Span + }{ + {batch: model.Batch{Process: model.Process{ServiceName: "batch-process"}, Spans: []*model.Span{{OperationName: "test-op", Process: &model.Process{ServiceName: "bar"}}}}, + expected: []*model.Span{{OperationName: "test-op", Process: &model.Process{ServiceName: "bar"}}}}, + {batch: model.Batch{Process: model.Process{ServiceName: "batch-process"}, Spans: []*model.Span{{OperationName: "test-op"}}}, + expected: []*model.Span{{OperationName: "test-op", Process: &model.Process{ServiceName: "batch-process"}}}}, + } + for _, test := range tests { + _, err := client.PostSpans(context.Background(), &api_v2.PostSpansRequest{ + Batch: test.batch, + }) + require.NoError(t, err) + got := processor.getSpans() + require.Equal(t, len(test.batch.GetSpans()), len(got)) + assert.Equal(t, test.expected, got) + processor.reset() + } +} + +func TestPostSpansWithError(t *testing.T) { + expectedError := errors.New("test-error") + processor := &mockSpanProcessor{expectedError: expectedError} + server, addr := initializeGRPCTestServer(t, func(s *grpc.Server) { + handler := NewGRPCHandler(zap.NewNop(), processor) + api_v2.RegisterCollectorServiceServer(s, handler) + }) + defer server.Stop() + client, conn := newClient(t, addr) + defer conn.Close() + r, err := client.PostSpans(context.Background(), &api_v2.PostSpansRequest{ + Batch: model.Batch{ + Spans: []*model.Span{ + { + OperationName: "fake-operation", + }, + }, + }, + }) + require.Error(t, err) + require.Nil(t, r) + require.Contains(t, err.Error(), expectedError.Error()) + require.Len(t, processor.getSpans(), 1) +} diff --git a/cmd/collector/app/grpcserver/grpc_server.go b/cmd/collector/app/grpcserver/grpc_server.go new file mode 100644 index 00000000000..e1c99d80fa7 --- /dev/null +++ b/cmd/collector/app/grpcserver/grpc_server.go @@ -0,0 +1,71 @@ +// Copyright (c) 2018 The Jaeger 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 grpcserver + +import ( + "io/ioutil" + "net" + "os" + "strconv" + + "github.com/pkg/errors" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + + "github.com/jaegertracing/jaeger/cmd/collector/app" + "github.com/jaegertracing/jaeger/cmd/collector/app/sampling" + "github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" +) + +// StartGRPCCollector configures and starts gRPC endpoints exposed by collector. +func StartGRPCCollector( + port int, + server *grpc.Server, + handler *app.GRPCHandler, + samplingStrategy strategystore.StrategyStore, + logger *zap.Logger, + serveErr func(error), +) (net.Addr, error) { + grpcPortStr := ":" + strconv.Itoa(port) + lis, err := net.Listen("tcp", grpcPortStr) + if err != nil { + return nil, errors.Wrap(err, "Failed to listen on gRPC port") + } + + grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr)) + + api_v2.RegisterCollectorServiceServer(server, handler) + api_v2.RegisterSamplingManagerServer(server, sampling.NewGRPCHandler(samplingStrategy)) + starServer(server, lis, logger, serveErr) + return lis.Addr(), nil +} + +func starServer(server *grpc.Server, lis net.Listener, logger *zap.Logger, serveErr func(error)) { + var port string + if tcpAddr, ok := lis.Addr().(*net.TCPAddr); ok { + port = strconv.Itoa(tcpAddr.Port) + } else { + port = lis.Addr().Network() + } + logger.Info("Starting jaeger-collector gRPC server", zap.String("grpc-port", port)) + go func() { + if err := server.Serve(lis); err != nil { + logger.Error("Could not launch gRPC service", zap.Error(err)) + serveErr(err) + } + }() +} diff --git a/cmd/collector/app/grpcserver/grpc_server_test.go b/cmd/collector/app/grpcserver/grpc_server_test.go new file mode 100644 index 00000000000..5c5f45cb4ff --- /dev/null +++ b/cmd/collector/app/grpcserver/grpc_server_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2018 The Jaeger 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 grpcserver + +import ( + "context" + "sync" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" + + "github.com/jaegertracing/jaeger/cmd/collector/app" + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +// test wrong port number +func TestFailToListen(t *testing.T) { + l, _ := zap.NewDevelopment() + handler := app.NewGRPCHandler(l, &mockSpanProcessor{}) + server := grpc.NewServer() + addr, err := StartGRPCCollector(1, server, handler, &mockSamplingStore{}, l, func(e error) { + }) + require.Nil(t, addr) + assert.EqualError(t, err, "Failed to listen on gRPC port: listen tcp :1: bind: permission denied") +} + +func TestFailServe(t *testing.T) { + lis := bufconn.Listen(0) + lis.Close() + core, logs := observer.New(zap.NewAtomicLevelAt(zapcore.ErrorLevel)) + wg := &sync.WaitGroup{} + wg.Add(1) + starServer(grpc.NewServer(), lis, zap.New(core), func(e error) { + assert.Equal(t, 1, len(logs.All())) + assert.Equal(t, "Could not launch gRPC service", logs.All()[0].Message) + wg.Done() + }) + wg.Wait() +} + +func TestSpanCollector(t *testing.T) { + l, _ := zap.NewDevelopment() + handler := app.NewGRPCHandler(l, &mockSpanProcessor{}) + server := grpc.NewServer() + addr, err := StartGRPCCollector(0, server, handler, &mockSamplingStore{}, l, func(e error) { + }) + require.NoError(t, err) + + conn, err := grpc.Dial(addr.String(), grpc.WithInsecure()) + defer conn.Close() + defer server.Stop() + require.NoError(t, err) + c := api_v2.NewCollectorServiceClient(conn) + response, err := c.PostSpans(context.Background(), &api_v2.PostSpansRequest{}) + require.NoError(t, err) + require.NotNil(t, response) +} + +type mockSamplingStore struct{} + +func (s mockSamplingStore) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) { + return nil, nil +} + +type mockSpanProcessor struct { +} + +func (p *mockSpanProcessor) ProcessSpans(spans []*model.Span, spanFormat string) ([]bool, error) { + return []bool{}, nil +} diff --git a/cmd/collector/app/sampling/gprc_handler.go b/cmd/collector/app/sampling/gprc_handler.go new file mode 100644 index 00000000000..cf0f5f924cd --- /dev/null +++ b/cmd/collector/app/sampling/gprc_handler.go @@ -0,0 +1,44 @@ +// Copyright (c) 2018 The Jaeger 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 sampling + +import ( + "context" + + "github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore" + "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" +) + +// GRPCHandler is sampling strategy handler for gRPC. +type GRPCHandler struct { + store strategystore.StrategyStore +} + +// NewGRPCHandler creates a handler that controls sampling strategies for services. +func NewGRPCHandler(store strategystore.StrategyStore) GRPCHandler { + return GRPCHandler{ + store: store, + } +} + +// GetSamplingStrategy returns sampling decision from store. +func (s GRPCHandler) GetSamplingStrategy(c context.Context, param *api_v2.SamplingStrategyParameters) (*api_v2.SamplingStrategyResponse, error) { + r, err := s.store.GetSamplingStrategy(param.GetServiceName()) + if err != nil { + return nil, err + } + return jaeger.ConvertSamplingResponseToDomain(r) +} diff --git a/cmd/collector/app/sampling/grpc_handler_test.go b/cmd/collector/app/sampling/grpc_handler_test.go new file mode 100644 index 00000000000..6cb947805e1 --- /dev/null +++ b/cmd/collector/app/sampling/grpc_handler_test.go @@ -0,0 +1,61 @@ +// Copyright (c) 2018 The Jaeger 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 sampling + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +type mockSamplingStore struct{} + +func (s mockSamplingStore) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) { + if serviceName == "error" { + return nil, errors.New("some error") + } else if serviceName == "nil" { + return nil, nil + } + return &sampling.SamplingStrategyResponse{StrategyType: sampling.SamplingStrategyType_PROBABILISTIC}, nil +} + +func TestNewGRPCHandler(t *testing.T) { + tests := []struct { + req *api_v2.SamplingStrategyParameters + resp *api_v2.SamplingStrategyResponse + err string + }{ + {req: &api_v2.SamplingStrategyParameters{ServiceName: "error"}, err: "some error"}, + {req: &api_v2.SamplingStrategyParameters{ServiceName: "nil"}, resp: nil}, + {req: &api_v2.SamplingStrategyParameters{ServiceName: "foo"}, resp: &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC}}, + } + h := NewGRPCHandler(mockSamplingStore{}) + for _, test := range tests { + resp, err := h.GetSamplingStrategy(context.Background(), test.req) + if test.err != "" { + assert.EqualError(t, err, test.err) + require.Nil(t, resp) + } else { + require.NoError(t, err) + assert.Equal(t, test.resp, resp) + } + } +} diff --git a/cmd/collector/main.go b/cmd/collector/main.go index 9fa23afdb75..d7d0b6a63b7 100644 --- a/cmd/collector/main.go +++ b/cmd/collector/main.go @@ -32,11 +32,14 @@ import ( "github.com/uber/tchannel-go" "github.com/uber/tchannel-go/thrift" "go.uber.org/zap" + "google.golang.org/grpc" basicB "github.com/jaegertracing/jaeger/cmd/builder" "github.com/jaegertracing/jaeger/cmd/collector/app" "github.com/jaegertracing/jaeger/cmd/collector/app/builder" + "github.com/jaegertracing/jaeger/cmd/collector/app/grpcserver" "github.com/jaegertracing/jaeger/cmd/collector/app/sampling" + "github.com/jaegertracing/jaeger/cmd/collector/app/sampling/strategystore" "github.com/jaegertracing/jaeger/cmd/collector/app/zipkin" "github.com/jaegertracing/jaeger/cmd/env" "github.com/jaegertracing/jaeger/cmd/flags" @@ -115,47 +118,57 @@ func main() { logger.Fatal("Unable to set up builder", zap.Error(err)) } - ch, err := tchannel.NewChannel(serviceName, &tchannel.ChannelOptions{}) - if err != nil { - logger.Fatal("Unable to create new TChannel", zap.Error(err)) - } - server := thrift.NewServer(ch) - zipkinSpansHandler, jaegerBatchesHandler := handlerBuilder.BuildHandlers() - server.Register(jc.NewTChanCollectorServer(jaegerBatchesHandler)) - server.Register(zc.NewTChanZipkinCollectorServer(zipkinSpansHandler)) - - samplingHandler := initializeSamplingHandler(strategyStoreFactory, v, metricsFactory, logger) - server.Register(sc.NewTChanSamplingManagerServer(samplingHandler)) - - portStr := ":" + strconv.Itoa(builderOpts.CollectorPort) - logger.Info("Starting jaeger-collector TChannel server", zap.Int("port", builderOpts.CollectorPort)) + zipkinSpansHandler, jaegerBatchesHandler, grpcHandler := handlerBuilder.BuildHandlers() + strategyStoreFactory.InitFromViper(v) + strategyStore := initSamplingStrategyStore(strategyStoreFactory, metricsFactory, logger) - listener, err := net.Listen("tcp", portStr) - if err != nil { - logger.Fatal("Unable to start listening on channel", zap.Error(err)) - } - ch.Serve(listener) - - r := mux.NewRouter() - apiHandler := app.NewAPIHandler(jaegerBatchesHandler) - apiHandler.RegisterRoutes(r) - if h := mBldr.Handler(); h != nil { - logger.Info("Registering metrics handler with HTTP server", zap.String("route", mBldr.HTTPRoute)) - r.Handle(mBldr.HTTPRoute, h) + { + ch, err := tchannel.NewChannel(serviceName, &tchannel.ChannelOptions{}) + if err != nil { + logger.Fatal("Unable to create new TChannel", zap.Error(err)) + } + server := thrift.NewServer(ch) + server.Register(jc.NewTChanCollectorServer(jaegerBatchesHandler)) + server.Register(zc.NewTChanZipkinCollectorServer(zipkinSpansHandler)) + server.Register(sc.NewTChanSamplingManagerServer(sampling.NewHandler(strategyStore))) + portStr := ":" + strconv.Itoa(builderOpts.CollectorPort) + listener, err := net.Listen("tcp", portStr) + if err != nil { + logger.Fatal("Unable to start listening on channel", zap.Error(err)) + } + logger.Info("Starting jaeger-collector TChannel server", zap.Int("port", builderOpts.CollectorPort)) + ch.Serve(listener) } - httpPortStr := ":" + strconv.Itoa(builderOpts.CollectorHTTPPort) - recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true) - go startZipkinHTTPAPI(logger, builderOpts.CollectorZipkinHTTPPort, zipkinSpansHandler, recoveryHandler) - - logger.Info("Starting jaeger-collector HTTP server", zap.Int("http-port", builderOpts.CollectorHTTPPort)) + { + grpcserver.StartGRPCCollector(builderOpts.CollectorGRPCPort, grpc.NewServer(), grpcHandler, strategyStore, logger, + func(err error) { + logger.Fatal("gRPC collector failed", zap.Error(err)) + }) + } - go func() { - if err := http.ListenAndServe(httpPortStr, recoveryHandler(r)); err != nil { - logger.Fatal("Could not launch service", zap.Error(err)) + { + r := mux.NewRouter() + apiHandler := app.NewAPIHandler(jaegerBatchesHandler) + apiHandler.RegisterRoutes(r) + if h := mBldr.Handler(); h != nil { + logger.Info("Registering metrics handler with HTTP server", zap.String("route", mBldr.HTTPRoute)) + r.Handle(mBldr.HTTPRoute, h) } - hc.Set(healthcheck.Unavailable) - }() + httpPortStr := ":" + strconv.Itoa(builderOpts.CollectorHTTPPort) + recoveryHandler := recoveryhandler.NewRecoveryHandler(logger, true) + httpHandler := recoveryHandler(r) + + go startZipkinHTTPAPI(logger, builderOpts.CollectorZipkinHTTPPort, zipkinSpansHandler, recoveryHandler) + + logger.Info("Starting jaeger-collector HTTP server", zap.Int("http-port", builderOpts.CollectorHTTPPort)) + go func() { + if err := http.ListenAndServe(httpPortStr, httpHandler); err != nil { + logger.Fatal("Could not launch service", zap.Error(err)) + } + hc.Set(healthcheck.Unavailable) + }() + } hc.Ready() <-signalsChannel @@ -214,13 +227,11 @@ func startZipkinHTTPAPI( } } -func initializeSamplingHandler( +func initSamplingStrategyStore( samplingStrategyStoreFactory *ss.Factory, - v *viper.Viper, metricsFactory metrics.Factory, logger *zap.Logger, -) sampling.Handler { - samplingStrategyStoreFactory.InitFromViper(v) +) strategystore.StrategyStore { if err := samplingStrategyStoreFactory.Initialize(metricsFactory, logger); err != nil { logger.Fatal("Failed to init sampling strategy store factory", zap.Error(err)) } @@ -228,5 +239,5 @@ func initializeSamplingHandler( if err != nil { logger.Fatal("Failed to create sampling strategy store", zap.Error(err)) } - return sampling.NewHandler(strategyStore) + return strategyStore } diff --git a/docker-compose/jaeger-docker-compose.yml b/docker-compose/jaeger-docker-compose.yml index 12728dc8a6c..02a40336ad3 100644 --- a/docker-compose/jaeger-docker-compose.yml +++ b/docker-compose/jaeger-docker-compose.yml @@ -8,6 +8,7 @@ services: - "14269" - "14268:14268" - "14267" + - "14250" - "9411:9411" restart: on-failure depends_on: @@ -25,7 +26,7 @@ services: jaeger-agent: image: jaegertracing/jaeger-agent - command: ["--reporter.tchannel.host-port=jaeger-collector:14267"] + command: ["--reporter.type=grpc", "--reporter.grpc.host-port=jaeger-collector:14250"] ports: - "5775:5775/udp" - "6831:6831/udp" diff --git a/model/converter/thrift/jaeger/sampling_from_domain.go b/model/converter/thrift/jaeger/sampling_from_domain.go new file mode 100644 index 00000000000..8f511da1e03 --- /dev/null +++ b/model/converter/thrift/jaeger/sampling_from_domain.go @@ -0,0 +1,100 @@ +// Copyright (c) 2018 The Jaeger 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 jaeger + +import ( + "errors" + "fmt" + "math" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +// ConvertSamplingResponseFromDomain converts proto sampling response to its thrift representation. +func ConvertSamplingResponseFromDomain(r *api_v2.SamplingStrategyResponse) (*sampling.SamplingStrategyResponse, error) { + typ, err := convertStrategyTypeFromDomain(r.GetStrategyType()) + if err != nil { + return nil, err + } + rl, err := convertRateLimitingFromDomain(r.GetRateLimitingSampling()) + if err != nil { + return nil, err + } + thriftResp := &sampling.SamplingStrategyResponse{StrategyType: typ, + ProbabilisticSampling: convertProbabilisticFromDomain(r.GetProbabilisticSampling()), + RateLimitingSampling: rl, + OperationSampling: convertPerOperationFromDomain(r.GetOperationSampling()), + } + return thriftResp, nil +} + +func convertProbabilisticFromDomain(s *api_v2.ProbabilisticSamplingStrategy) *sampling.ProbabilisticSamplingStrategy { + if s == nil { + return nil + } + return &sampling.ProbabilisticSamplingStrategy{SamplingRate: s.GetSamplingRate()} +} + +func convertRateLimitingFromDomain(s *api_v2.RateLimitingSamplingStrategy) (*sampling.RateLimitingSamplingStrategy, error) { + if s == nil { + return nil, nil + } + if s.MaxTracesPerSecond > math.MaxInt16 { + return nil, errors.New("maxTracesPerSecond is higher than int16") + } + return &sampling.RateLimitingSamplingStrategy{MaxTracesPerSecond: int16(s.GetMaxTracesPerSecond())}, nil +} + +func convertPerOperationFromDomain(s *api_v2.PerOperationSamplingStrategies) *sampling.PerOperationSamplingStrategies { + if s == nil { + return nil + } + r := &sampling.PerOperationSamplingStrategies{ + DefaultSamplingProbability: s.GetDefaultSamplingProbability(), + DefaultLowerBoundTracesPerSecond: s.GetDefaultLowerBoundTracesPerSecond(), + DefaultUpperBoundTracesPerSecond: &s.DefaultUpperBoundTracesPerSecond, + } + fmt.Println(s.GetDefaultUpperBoundTracesPerSecond()) + //if s.GetDefaultUpperBoundTracesPerSecond() > 0 {} + if s.GetPerOperationStrategies() != nil { + r.PerOperationStrategies = make([]*sampling.OperationSamplingStrategy, len(s.GetPerOperationStrategies())) + for i, k := range s.PerOperationStrategies { + r.PerOperationStrategies[i] = convertOperationFromDomain(k) + } + } + return r +} + +func convertOperationFromDomain(s *api_v2.OperationSamplingStrategy) *sampling.OperationSamplingStrategy { + if s == nil { + return nil + } + return &sampling.OperationSamplingStrategy{ + Operation: s.GetOperation(), + ProbabilisticSampling: convertProbabilisticFromDomain(s.GetProbabilisticSampling()), + } +} + +func convertStrategyTypeFromDomain(s api_v2.SamplingStrategyType) (sampling.SamplingStrategyType, error) { + switch s { + case api_v2.SamplingStrategyType_PROBABILISTIC: + return sampling.SamplingStrategyType_PROBABILISTIC, nil + case api_v2.SamplingStrategyType_RATE_LIMITING: + return sampling.SamplingStrategyType_RATE_LIMITING, nil + default: + return sampling.SamplingStrategyType_PROBABILISTIC, errors.New("could not convert sampling strategy type") + } +} diff --git a/model/converter/thrift/jaeger/sampling_from_domain_test.go b/model/converter/thrift/jaeger/sampling_from_domain_test.go new file mode 100644 index 00000000000..910ddd317b0 --- /dev/null +++ b/model/converter/thrift/jaeger/sampling_from_domain_test.go @@ -0,0 +1,140 @@ +// Copyright (c) 2018 The Jaeger 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 jaeger + +import ( + "math" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +func TestConvertStrategyTypeFromDomain(t *testing.T) { + tests := []struct { + expected sampling.SamplingStrategyType + in api_v2.SamplingStrategyType + err string + }{ + {expected: sampling.SamplingStrategyType_PROBABILISTIC, in: api_v2.SamplingStrategyType_PROBABILISTIC}, + {expected: sampling.SamplingStrategyType_RATE_LIMITING, in: api_v2.SamplingStrategyType_RATE_LIMITING}, + {in: 44, err: "could not convert sampling strategy type"}, + } + for _, test := range tests { + st, err := convertStrategyTypeFromDomain(test.in) + if test.err != "" { + assert.EqualError(t, err, test.err) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected, st) + } + } +} + +func TestConvertProbabilisticFromDomain(t *testing.T) { + tests := []struct { + in *api_v2.ProbabilisticSamplingStrategy + expected *sampling.ProbabilisticSamplingStrategy + }{ + {in: &api_v2.ProbabilisticSamplingStrategy{SamplingRate: 21}, expected: &sampling.ProbabilisticSamplingStrategy{SamplingRate: 21}}, + {}, + } + for _, test := range tests { + st := convertProbabilisticFromDomain(test.in) + assert.Equal(t, test.expected, st) + } +} + +func TestConvertRateLimitingFromDomain(t *testing.T) { + tests := []struct { + in *api_v2.RateLimitingSamplingStrategy + expected *sampling.RateLimitingSamplingStrategy + err string + }{ + {in: &api_v2.RateLimitingSamplingStrategy{MaxTracesPerSecond: 21}, expected: &sampling.RateLimitingSamplingStrategy{MaxTracesPerSecond: 21}}, + {in: &api_v2.RateLimitingSamplingStrategy{MaxTracesPerSecond: math.MaxInt32}, err: "maxTracesPerSecond is higher than int16"}, + {}, + } + for _, test := range tests { + st, err := convertRateLimitingFromDomain(test.in) + if test.err != "" { + assert.EqualError(t, err, test.err) + require.Nil(t, st) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected, st) + } + } +} + +func TestConvertOperationStrategyFromDomain(t *testing.T) { + tests := []struct { + in *api_v2.OperationSamplingStrategy + expected *sampling.OperationSamplingStrategy + }{ + {in: &api_v2.OperationSamplingStrategy{Operation: "foo"}, expected: &sampling.OperationSamplingStrategy{Operation: "foo"}}, + {in: &api_v2.OperationSamplingStrategy{Operation: "foo", ProbabilisticSampling: &api_v2.ProbabilisticSamplingStrategy{SamplingRate: 2}}, + expected: &sampling.OperationSamplingStrategy{Operation: "foo", ProbabilisticSampling: &sampling.ProbabilisticSamplingStrategy{SamplingRate: 2}}}, + {}, + } + for _, test := range tests { + o := convertOperationFromDomain(test.in) + assert.Equal(t, test.expected, o) + } +} + +func TestConvertPerOperationStrategyFromDomain(t *testing.T) { + var a = 11.2 + tests := []struct { + in *api_v2.PerOperationSamplingStrategies + expected *sampling.PerOperationSamplingStrategies + }{ + {in: &api_v2.PerOperationSamplingStrategies{DefaultSamplingProbability: 15.2, DefaultUpperBoundTracesPerSecond: a, DefaultLowerBoundTracesPerSecond: 2, + PerOperationStrategies: []*api_v2.OperationSamplingStrategy{{Operation: "fao"}}}, + expected: &sampling.PerOperationSamplingStrategies{DefaultSamplingProbability: 15.2, DefaultUpperBoundTracesPerSecond: &a, DefaultLowerBoundTracesPerSecond: 2, + PerOperationStrategies: []*sampling.OperationSamplingStrategy{{Operation: "fao"}}}}, + {}, + } + for _, test := range tests { + o := convertPerOperationFromDomain(test.in) + assert.Equal(t, test.expected, o) + } +} + +func TestConvertSamplingResponseFromDomain(t *testing.T) { + tests := []struct { + in *api_v2.SamplingStrategyResponse + expected *sampling.SamplingStrategyResponse + err string + }{ + {in: &api_v2.SamplingStrategyResponse{StrategyType: 55}, err: "could not convert sampling strategy type"}, + {in: &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC, RateLimitingSampling: &api_v2.RateLimitingSamplingStrategy{MaxTracesPerSecond: math.MaxInt32}}, + err: "maxTracesPerSecond is higher than int16"}, + {in: &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC}, expected: &sampling.SamplingStrategyResponse{StrategyType: sampling.SamplingStrategyType_PROBABILISTIC}}, + } + for _, test := range tests { + r, err := ConvertSamplingResponseFromDomain(test.in) + if test.err != "" { + assert.EqualError(t, err, test.err) + require.Nil(t, r) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected, r) + } + } +} diff --git a/model/converter/thrift/jaeger/sampling_to_domain.go b/model/converter/thrift/jaeger/sampling_to_domain.go new file mode 100644 index 00000000000..876e50a4a83 --- /dev/null +++ b/model/converter/thrift/jaeger/sampling_to_domain.go @@ -0,0 +1,84 @@ +// Copyright (c) 2018 The Jaeger 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 jaeger + +import ( + "errors" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +// ConvertSamplingResponseToDomain converts thrift sampling response to its proto representation. +func ConvertSamplingResponseToDomain(r *sampling.SamplingStrategyResponse) (*api_v2.SamplingStrategyResponse, error) { + if r == nil { + return nil, nil + } + t, err := convertStrategyTypeToDomain(r.GetStrategyType()) + if err != nil { + return nil, err + } + response := &api_v2.SamplingStrategyResponse{ + StrategyType: t, + ProbabilisticSampling: convertProbabilisticToDomain(r.GetProbabilisticSampling()), + RateLimitingSampling: convertRateLimitingToDomain(r.GetRateLimitingSampling()), + OperationSampling: convertPerOperationToDomain(r.GetOperationSampling()), + } + return response, nil +} + +func convertRateLimitingToDomain(s *sampling.RateLimitingSamplingStrategy) *api_v2.RateLimitingSamplingStrategy { + if s == nil { + return nil + } + return &api_v2.RateLimitingSamplingStrategy{MaxTracesPerSecond: int32(s.GetMaxTracesPerSecond())} +} + +func convertProbabilisticToDomain(s *sampling.ProbabilisticSamplingStrategy) *api_v2.ProbabilisticSamplingStrategy { + if s == nil { + return nil + } + return &api_v2.ProbabilisticSamplingStrategy{SamplingRate: s.GetSamplingRate()} +} + +func convertPerOperationToDomain(s *sampling.PerOperationSamplingStrategies) *api_v2.PerOperationSamplingStrategies { + if s == nil { + return nil + } + poss := make([]*api_v2.OperationSamplingStrategy, len(s.PerOperationStrategies)) + for i, pos := range s.PerOperationStrategies { + poss[i] = &api_v2.OperationSamplingStrategy{ + Operation: pos.Operation, + ProbabilisticSampling: convertProbabilisticToDomain(pos.GetProbabilisticSampling()), + } + } + return &api_v2.PerOperationSamplingStrategies{ + DefaultSamplingProbability: s.GetDefaultSamplingProbability(), + DefaultUpperBoundTracesPerSecond: s.GetDefaultUpperBoundTracesPerSecond(), + DefaultLowerBoundTracesPerSecond: s.GetDefaultLowerBoundTracesPerSecond(), + PerOperationStrategies: poss, + } +} + +func convertStrategyTypeToDomain(t sampling.SamplingStrategyType) (api_v2.SamplingStrategyType, error) { + switch t { + case sampling.SamplingStrategyType_PROBABILISTIC: + return api_v2.SamplingStrategyType_PROBABILISTIC, nil + case sampling.SamplingStrategyType_RATE_LIMITING: + return api_v2.SamplingStrategyType_RATE_LIMITING, nil + default: + return api_v2.SamplingStrategyType_PROBABILISTIC, errors.New("could not convert sampling strategy type") + } +} diff --git a/model/converter/thrift/jaeger/sampling_to_domain_test.go b/model/converter/thrift/jaeger/sampling_to_domain_test.go new file mode 100644 index 00000000000..94b5167c94e --- /dev/null +++ b/model/converter/thrift/jaeger/sampling_to_domain_test.go @@ -0,0 +1,115 @@ +// Copyright (c) 2018 The Jaeger 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 jaeger + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "github.com/jaegertracing/jaeger/thrift-gen/sampling" +) + +func TestConvertStrategyTypeToDomain(t *testing.T) { + tests := []struct { + in sampling.SamplingStrategyType + expected api_v2.SamplingStrategyType + err error + }{ + {in: sampling.SamplingStrategyType_PROBABILISTIC, expected: api_v2.SamplingStrategyType_PROBABILISTIC}, + {in: sampling.SamplingStrategyType_RATE_LIMITING, expected: api_v2.SamplingStrategyType_RATE_LIMITING}, + {in: 44, err: errors.New("could not convert sampling strategy type")}, + } + for _, test := range tests { + st, err := convertStrategyTypeToDomain(test.in) + if test.err != nil { + assert.EqualError(t, test.err, err.Error()) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected, st) + } + } +} + +func TestConvertProbabilisticToDomain(t *testing.T) { + tests := []struct { + expected *api_v2.ProbabilisticSamplingStrategy + in *sampling.ProbabilisticSamplingStrategy + }{ + {expected: &api_v2.ProbabilisticSamplingStrategy{SamplingRate: 21}, in: &sampling.ProbabilisticSamplingStrategy{SamplingRate: 21}}, + {}, + } + for _, test := range tests { + st := convertProbabilisticToDomain(test.in) + assert.Equal(t, test.expected, st) + } +} + +func TestConvertRateLimitingToDomain(t *testing.T) { + tests := []struct { + expected *api_v2.RateLimitingSamplingStrategy + in *sampling.RateLimitingSamplingStrategy + }{ + {expected: &api_v2.RateLimitingSamplingStrategy{MaxTracesPerSecond: 21}, in: &sampling.RateLimitingSamplingStrategy{MaxTracesPerSecond: 21}}, + {}, + } + for _, test := range tests { + st := convertRateLimitingToDomain(test.in) + assert.Equal(t, test.expected, st) + } +} + +func TestConvertPerOperationStrategyToDomain(t *testing.T) { + var a = 11.2 + tests := []struct { + expected *api_v2.PerOperationSamplingStrategies + in *sampling.PerOperationSamplingStrategies + }{ + {expected: &api_v2.PerOperationSamplingStrategies{DefaultSamplingProbability: 15.2, DefaultUpperBoundTracesPerSecond: a, DefaultLowerBoundTracesPerSecond: 2, + PerOperationStrategies: []*api_v2.OperationSamplingStrategy{{Operation: "fao"}}}, + in: &sampling.PerOperationSamplingStrategies{DefaultSamplingProbability: 15.2, DefaultUpperBoundTracesPerSecond: &a, DefaultLowerBoundTracesPerSecond: 2, + PerOperationStrategies: []*sampling.OperationSamplingStrategy{{Operation: "fao"}}}}, + {}, + } + for _, test := range tests { + o := convertPerOperationToDomain(test.in) + assert.Equal(t, test.expected, o) + } +} + +func TestConvertSamplingResponseToDomain(t *testing.T) { + tests := []struct { + expected *api_v2.SamplingStrategyResponse + in *sampling.SamplingStrategyResponse + err string + }{ + {in: &sampling.SamplingStrategyResponse{StrategyType: 55}, err: "could not convert sampling strategy type"}, + {expected: &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC}, in: &sampling.SamplingStrategyResponse{StrategyType: sampling.SamplingStrategyType_PROBABILISTIC}}, + {}, + } + for _, test := range tests { + r, err := ConvertSamplingResponseToDomain(test.in) + if test.err != "" { + assert.EqualError(t, err, test.err) + require.Nil(t, r) + } else { + require.NoError(t, err) + assert.Equal(t, test.expected, r) + } + } +} diff --git a/model/model.pb.go b/model/model.pb.go index 05ad2248898..a28b54c1cd5 100644 --- a/model/model.pb.go +++ b/model/model.pb.go @@ -15,10 +15,6 @@ Span Trace Batch - PostSpansRequest - PostSpansResponse - GetTraceRequest - GetTraceResponse */ package model @@ -26,19 +22,15 @@ import proto "github.com/gogo/protobuf/proto" import golang_proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "github.com/gogo/googleapis/google/api" import _ "github.com/gogo/protobuf/types" import _ "github.com/gogo/protobuf/types" -import _ "github.com/gogo/googleapis/google/api" -import _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" -import _ "github.com/gogo/protobuf/gogoproto" import time "time" import bytes "bytes" -import context "golang.org/x/net/context" -import grpc "google.golang.org/grpc" - import binary "encoding/binary" import types "github.com/gogo/protobuf/types" @@ -110,7 +102,7 @@ func (SpanRefType) EnumDescriptor() ([]byte, []int) { return fileDescriptorModel type KeyValue struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - VType ValueType `protobuf:"varint,2,opt,name=v_type,json=vType,proto3,enum=jaeger.model.ValueType" json:"v_type,omitempty"` + VType ValueType `protobuf:"varint,2,opt,name=v_type,json=vType,proto3,enum=jaeger.api_v2.ValueType" json:"v_type,omitempty"` VStr string `protobuf:"bytes,3,opt,name=v_str,json=vStr,proto3" json:"v_str,omitempty"` VBool bool `protobuf:"varint,4,opt,name=v_bool,json=vBool,proto3" json:"v_bool,omitempty"` VInt64 int64 `protobuf:"varint,5,opt,name=v_int64,json=vInt64,proto3" json:"v_int64,omitempty"` @@ -199,7 +191,7 @@ func (m *Log) GetFields() []KeyValue { type SpanRef struct { TraceID TraceID `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3,customtype=TraceID" json:"trace_id"` SpanID SpanID `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3,customtype=SpanID" json:"span_id"` - RefType SpanRefType `protobuf:"varint,3,opt,name=ref_type,json=refType,proto3,enum=jaeger.model.SpanRefType" json:"ref_type,omitempty"` + RefType SpanRefType `protobuf:"varint,3,opt,name=ref_type,json=refType,proto3,enum=jaeger.api_v2.SpanRefType" json:"ref_type,omitempty"` } func (m *SpanRef) Reset() { *m = SpanRef{} } @@ -401,99 +393,27 @@ func (m *Batch) GetProcess() Process { return Process{} } -type PostSpansRequest struct { - Batch *Batch `protobuf:"bytes,1,opt,name=batch" json:"batch,omitempty"` -} - -func (m *PostSpansRequest) Reset() { *m = PostSpansRequest{} } -func (m *PostSpansRequest) String() string { return proto.CompactTextString(m) } -func (*PostSpansRequest) ProtoMessage() {} -func (*PostSpansRequest) Descriptor() ([]byte, []int) { return fileDescriptorModel, []int{7} } - -func (m *PostSpansRequest) GetBatch() *Batch { - if m != nil { - return m.Batch - } - return nil -} - -type PostSpansResponse struct { - Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` -} - -func (m *PostSpansResponse) Reset() { *m = PostSpansResponse{} } -func (m *PostSpansResponse) String() string { return proto.CompactTextString(m) } -func (*PostSpansResponse) ProtoMessage() {} -func (*PostSpansResponse) Descriptor() ([]byte, []int) { return fileDescriptorModel, []int{8} } - -func (m *PostSpansResponse) GetOk() bool { - if m != nil { - return m.Ok - } - return false -} - -type GetTraceRequest struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (m *GetTraceRequest) Reset() { *m = GetTraceRequest{} } -func (m *GetTraceRequest) String() string { return proto.CompactTextString(m) } -func (*GetTraceRequest) ProtoMessage() {} -func (*GetTraceRequest) Descriptor() ([]byte, []int) { return fileDescriptorModel, []int{9} } - -func (m *GetTraceRequest) GetId() string { - if m != nil { - return m.Id - } - return "" -} - -type GetTraceResponse struct { - Trace *Trace `protobuf:"bytes,1,opt,name=trace" json:"trace,omitempty"` -} - -func (m *GetTraceResponse) Reset() { *m = GetTraceResponse{} } -func (m *GetTraceResponse) String() string { return proto.CompactTextString(m) } -func (*GetTraceResponse) ProtoMessage() {} -func (*GetTraceResponse) Descriptor() ([]byte, []int) { return fileDescriptorModel, []int{10} } - -func (m *GetTraceResponse) GetTrace() *Trace { - if m != nil { - return m.Trace - } - return nil -} - func init() { - proto.RegisterType((*KeyValue)(nil), "jaeger.model.KeyValue") - golang_proto.RegisterType((*KeyValue)(nil), "jaeger.model.KeyValue") - proto.RegisterType((*Log)(nil), "jaeger.model.Log") - golang_proto.RegisterType((*Log)(nil), "jaeger.model.Log") - proto.RegisterType((*SpanRef)(nil), "jaeger.model.SpanRef") - golang_proto.RegisterType((*SpanRef)(nil), "jaeger.model.SpanRef") - proto.RegisterType((*Process)(nil), "jaeger.model.Process") - golang_proto.RegisterType((*Process)(nil), "jaeger.model.Process") - proto.RegisterType((*Span)(nil), "jaeger.model.Span") - golang_proto.RegisterType((*Span)(nil), "jaeger.model.Span") - proto.RegisterType((*Trace)(nil), "jaeger.model.Trace") - golang_proto.RegisterType((*Trace)(nil), "jaeger.model.Trace") - proto.RegisterType((*Trace_ProcessMapping)(nil), "jaeger.model.Trace.ProcessMapping") - golang_proto.RegisterType((*Trace_ProcessMapping)(nil), "jaeger.model.Trace.ProcessMapping") - proto.RegisterType((*Batch)(nil), "jaeger.model.Batch") - golang_proto.RegisterType((*Batch)(nil), "jaeger.model.Batch") - proto.RegisterType((*PostSpansRequest)(nil), "jaeger.model.PostSpansRequest") - golang_proto.RegisterType((*PostSpansRequest)(nil), "jaeger.model.PostSpansRequest") - proto.RegisterType((*PostSpansResponse)(nil), "jaeger.model.PostSpansResponse") - golang_proto.RegisterType((*PostSpansResponse)(nil), "jaeger.model.PostSpansResponse") - proto.RegisterType((*GetTraceRequest)(nil), "jaeger.model.GetTraceRequest") - golang_proto.RegisterType((*GetTraceRequest)(nil), "jaeger.model.GetTraceRequest") - proto.RegisterType((*GetTraceResponse)(nil), "jaeger.model.GetTraceResponse") - golang_proto.RegisterType((*GetTraceResponse)(nil), "jaeger.model.GetTraceResponse") - proto.RegisterEnum("jaeger.model.ValueType", ValueType_name, ValueType_value) - golang_proto.RegisterEnum("jaeger.model.ValueType", ValueType_name, ValueType_value) - proto.RegisterEnum("jaeger.model.SpanRefType", SpanRefType_name, SpanRefType_value) - golang_proto.RegisterEnum("jaeger.model.SpanRefType", SpanRefType_name, SpanRefType_value) + proto.RegisterType((*KeyValue)(nil), "jaeger.api_v2.KeyValue") + golang_proto.RegisterType((*KeyValue)(nil), "jaeger.api_v2.KeyValue") + proto.RegisterType((*Log)(nil), "jaeger.api_v2.Log") + golang_proto.RegisterType((*Log)(nil), "jaeger.api_v2.Log") + proto.RegisterType((*SpanRef)(nil), "jaeger.api_v2.SpanRef") + golang_proto.RegisterType((*SpanRef)(nil), "jaeger.api_v2.SpanRef") + proto.RegisterType((*Process)(nil), "jaeger.api_v2.Process") + golang_proto.RegisterType((*Process)(nil), "jaeger.api_v2.Process") + proto.RegisterType((*Span)(nil), "jaeger.api_v2.Span") + golang_proto.RegisterType((*Span)(nil), "jaeger.api_v2.Span") + proto.RegisterType((*Trace)(nil), "jaeger.api_v2.Trace") + golang_proto.RegisterType((*Trace)(nil), "jaeger.api_v2.Trace") + proto.RegisterType((*Trace_ProcessMapping)(nil), "jaeger.api_v2.Trace.ProcessMapping") + golang_proto.RegisterType((*Trace_ProcessMapping)(nil), "jaeger.api_v2.Trace.ProcessMapping") + proto.RegisterType((*Batch)(nil), "jaeger.api_v2.Batch") + golang_proto.RegisterType((*Batch)(nil), "jaeger.api_v2.Batch") + proto.RegisterEnum("jaeger.api_v2.ValueType", ValueType_name, ValueType_value) + golang_proto.RegisterEnum("jaeger.api_v2.ValueType", ValueType_name, ValueType_value) + proto.RegisterEnum("jaeger.api_v2.SpanRefType", SpanRefType_name, SpanRefType_value) + golang_proto.RegisterEnum("jaeger.api_v2.SpanRefType", SpanRefType_name, SpanRefType_value) } func (this *KeyValue) Compare(that interface{}) int { if that == nil { @@ -609,143 +529,6 @@ func (this *KeyValue) Equal(that interface{}) bool { } return true } - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// Client API for CollectorServiceV2 service - -type CollectorServiceV2Client interface { - PostSpans(ctx context.Context, in *PostSpansRequest, opts ...grpc.CallOption) (*PostSpansResponse, error) -} - -type collectorServiceV2Client struct { - cc *grpc.ClientConn -} - -func NewCollectorServiceV2Client(cc *grpc.ClientConn) CollectorServiceV2Client { - return &collectorServiceV2Client{cc} -} - -func (c *collectorServiceV2Client) PostSpans(ctx context.Context, in *PostSpansRequest, opts ...grpc.CallOption) (*PostSpansResponse, error) { - out := new(PostSpansResponse) - err := grpc.Invoke(ctx, "/jaeger.model.CollectorServiceV2/PostSpans", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for CollectorServiceV2 service - -type CollectorServiceV2Server interface { - PostSpans(context.Context, *PostSpansRequest) (*PostSpansResponse, error) -} - -func RegisterCollectorServiceV2Server(s *grpc.Server, srv CollectorServiceV2Server) { - s.RegisterService(&_CollectorServiceV2_serviceDesc, srv) -} - -func _CollectorServiceV2_PostSpans_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PostSpansRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(CollectorServiceV2Server).PostSpans(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/jaeger.model.CollectorServiceV2/PostSpans", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CollectorServiceV2Server).PostSpans(ctx, req.(*PostSpansRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _CollectorServiceV2_serviceDesc = grpc.ServiceDesc{ - ServiceName: "jaeger.model.CollectorServiceV2", - HandlerType: (*CollectorServiceV2Server)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "PostSpans", - Handler: _CollectorServiceV2_PostSpans_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "model.proto", -} - -// Client API for QueryServiceV2 service - -type QueryServiceV2Client interface { - GetTrace(ctx context.Context, in *GetTraceRequest, opts ...grpc.CallOption) (*GetTraceResponse, error) -} - -type queryServiceV2Client struct { - cc *grpc.ClientConn -} - -func NewQueryServiceV2Client(cc *grpc.ClientConn) QueryServiceV2Client { - return &queryServiceV2Client{cc} -} - -func (c *queryServiceV2Client) GetTrace(ctx context.Context, in *GetTraceRequest, opts ...grpc.CallOption) (*GetTraceResponse, error) { - out := new(GetTraceResponse) - err := grpc.Invoke(ctx, "/jaeger.model.QueryServiceV2/GetTrace", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for QueryServiceV2 service - -type QueryServiceV2Server interface { - GetTrace(context.Context, *GetTraceRequest) (*GetTraceResponse, error) -} - -func RegisterQueryServiceV2Server(s *grpc.Server, srv QueryServiceV2Server) { - s.RegisterService(&_QueryServiceV2_serviceDesc, srv) -} - -func _QueryServiceV2_GetTrace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetTraceRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServiceV2Server).GetTrace(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/jaeger.model.QueryServiceV2/GetTrace", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServiceV2Server).GetTrace(ctx, req.(*GetTraceRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _QueryServiceV2_serviceDesc = grpc.ServiceDesc{ - ServiceName: "jaeger.model.QueryServiceV2", - HandlerType: (*QueryServiceV2Server)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetTrace", - Handler: _QueryServiceV2_GetTrace_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "model.proto", -} - func (m *KeyValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1176,114 +959,6 @@ func (m *Batch) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *PostSpansRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PostSpansRequest) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Batch != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintModel(dAtA, i, uint64(m.Batch.Size())) - n11, err := m.Batch.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n11 - } - return i, nil -} - -func (m *PostSpansResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PostSpansResponse) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Ok { - dAtA[i] = 0x8 - i++ - if m.Ok { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } - return i, nil -} - -func (m *GetTraceRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GetTraceRequest) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Id) > 0 { - dAtA[i] = 0xa - i++ - i = encodeVarintModel(dAtA, i, uint64(len(m.Id))) - i += copy(dAtA[i:], m.Id) - } - return i, nil -} - -func (m *GetTraceResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *GetTraceResponse) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Trace != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintModel(dAtA, i, uint64(m.Trace.Size())) - n12, err := m.Trace.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n12 - } - return i, nil -} - func encodeVarintModel(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -1469,45 +1144,6 @@ func (m *Batch) Size() (n int) { return n } -func (m *PostSpansRequest) Size() (n int) { - var l int - _ = l - if m.Batch != nil { - l = m.Batch.Size() - n += 1 + l + sovModel(uint64(l)) - } - return n -} - -func (m *PostSpansResponse) Size() (n int) { - var l int - _ = l - if m.Ok { - n += 2 - } - return n -} - -func (m *GetTraceRequest) Size() (n int) { - var l int - _ = l - l = len(m.Id) - if l > 0 { - n += 1 + l + sovModel(uint64(l)) - } - return n -} - -func (m *GetTraceResponse) Size() (n int) { - var l int - _ = l - if m.Trace != nil { - l = m.Trace.Size() - n += 1 + l + sovModel(uint64(l)) - } - return n -} - func sovModel(x uint64) (n int) { for { n++ @@ -2842,321 +2478,6 @@ func (m *Batch) Unmarshal(dAtA []byte) error { } return nil } -func (m *PostSpansRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PostSpansRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PostSpansRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Batch", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthModel - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Batch == nil { - m.Batch = &Batch{} - } - if err := m.Batch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipModel(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthModel - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PostSpansResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PostSpansResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PostSpansResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ok", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Ok = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipModel(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthModel - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *GetTraceRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GetTraceRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GetTraceRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModel - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipModel(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthModel - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *GetTraceResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: GetTraceResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: GetTraceResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Trace", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModel - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthModel - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Trace == nil { - m.Trace = &Trace{} - } - if err := m.Trace.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipModel(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthModel - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipModel(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -3266,79 +2587,62 @@ func init() { proto.RegisterFile("model.proto", fileDescriptorModel) } func init() { golang_proto.RegisterFile("model.proto", fileDescriptorModel) } var fileDescriptorModel = []byte{ - // 1173 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x41, 0x73, 0xdb, 0xc4, - 0x17, 0xaf, 0x64, 0xcb, 0x96, 0x9f, 0x1d, 0xff, 0xdd, 0xed, 0xb4, 0x55, 0xdc, 0x3f, 0xb6, 0xab, - 0x0e, 0x83, 0x1b, 0x88, 0xdd, 0x9a, 0xa4, 0x87, 0x30, 0x0c, 0x13, 0x25, 0xb8, 0x08, 0x9c, 0x38, - 0xc8, 0x99, 0x32, 0x70, 0xc0, 0x23, 0xdb, 0x6b, 0x45, 0xc4, 0xd6, 0x0a, 0x69, 0xad, 0xe0, 0x01, - 0x86, 0x19, 0xbe, 0x00, 0x0c, 0x5c, 0x38, 0xc2, 0x91, 0x6f, 0xc1, 0xb1, 0x47, 0x66, 0x7a, 0x82, - 0x43, 0x60, 0x02, 0x87, 0x7e, 0x0c, 0x66, 0x57, 0x92, 0x63, 0x9b, 0x14, 0x02, 0x07, 0x4e, 0xde, - 0xb7, 0xef, 0xf7, 0x7e, 0xef, 0xbd, 0xdf, 0x7b, 0xd9, 0x08, 0xb2, 0x63, 0x32, 0xc0, 0xa3, 0x9a, - 0xeb, 0x11, 0x4a, 0x50, 0xee, 0x03, 0x13, 0x5b, 0xd8, 0xab, 0xf1, 0xbb, 0x62, 0xd9, 0x22, 0xc4, - 0x1a, 0xe1, 0x3a, 0xf7, 0xf5, 0x26, 0xc3, 0x3a, 0xb5, 0xc7, 0xd8, 0xa7, 0xe6, 0xd8, 0x0d, 0xe1, - 0xc5, 0xd2, 0x32, 0x60, 0x30, 0xf1, 0x4c, 0x6a, 0x13, 0x27, 0xf2, 0xff, 0x3f, 0xf2, 0x9b, 0xae, - 0x5d, 0x37, 0x1d, 0x87, 0x50, 0xee, 0xf4, 0x23, 0x6f, 0xc7, 0xb2, 0xe9, 0xd1, 0xa4, 0x57, 0xeb, - 0x93, 0x71, 0xdd, 0xf2, 0xdc, 0xfe, 0x3a, 0xee, 0x13, 0x7f, 0xea, 0x53, 0x1c, 0x99, 0x96, 0x49, - 0xf1, 0x89, 0x39, 0x0d, 0xd9, 0xfb, 0xeb, 0x16, 0x76, 0xd6, 0xfd, 0x13, 0xd3, 0xb2, 0xb0, 0x57, - 0x27, 0x2e, 0x27, 0xba, 0x80, 0x74, 0x7d, 0x9e, 0x94, 0x58, 0xe4, 0xbc, 0x36, 0x66, 0x71, 0x83, - 0x9f, 0x42, 0xb8, 0xfa, 0x44, 0x00, 0xf9, 0x2d, 0x3c, 0x7d, 0x64, 0x8e, 0x26, 0x18, 0x15, 0x20, - 0x71, 0x8c, 0xa7, 0x8a, 0x50, 0x11, 0xaa, 0x19, 0x83, 0x1d, 0x51, 0x0d, 0x52, 0x41, 0x97, 0x4e, - 0x5d, 0xac, 0x88, 0x15, 0xa1, 0x9a, 0x6f, 0xdc, 0xac, 0xcd, 0x0b, 0x54, 0xe3, 0x61, 0x87, 0x53, - 0x17, 0x1b, 0x52, 0xc0, 0x7e, 0xd0, 0x35, 0x90, 0x82, 0xae, 0x4f, 0x3d, 0x25, 0xc1, 0x39, 0x92, - 0x41, 0x87, 0x7a, 0xe8, 0x3a, 0x23, 0xe9, 0x11, 0x32, 0x52, 0x92, 0x15, 0xa1, 0x2a, 0x1b, 0x52, - 0xa0, 0x11, 0x32, 0x42, 0x37, 0x21, 0x1d, 0x74, 0x6d, 0x87, 0x3e, 0xd8, 0x50, 0xa4, 0x8a, 0x50, - 0x4d, 0x18, 0xa9, 0x40, 0x67, 0x16, 0xba, 0x05, 0x99, 0xa0, 0x3b, 0x1c, 0x11, 0x93, 0xb9, 0x52, - 0x15, 0xa1, 0x2a, 0x18, 0x72, 0xd0, 0x0c, 0x6d, 0xb4, 0x0a, 0x72, 0xd0, 0xed, 0xd9, 0x8e, 0xe9, - 0x4d, 0x95, 0x74, 0x45, 0xa8, 0xe6, 0x8c, 0x74, 0xa0, 0x71, 0x73, 0x4b, 0x7e, 0xfa, 0x6d, 0x59, - 0x78, 0xfa, 0x5d, 0x59, 0x50, 0x3f, 0x83, 0x44, 0x8b, 0x58, 0x48, 0x83, 0xcc, 0x6c, 0x62, 0xbc, - 0xab, 0x6c, 0xa3, 0x58, 0x0b, 0x47, 0x52, 0x8b, 0x65, 0xa9, 0x1d, 0xc6, 0x08, 0x4d, 0x7e, 0x7c, - 0x5a, 0xbe, 0xf2, 0xe5, 0x2f, 0x65, 0xc1, 0x38, 0x0f, 0x43, 0x1b, 0x90, 0x1a, 0xda, 0x78, 0x34, - 0xf0, 0x15, 0xb1, 0x92, 0xa8, 0x66, 0x1b, 0x37, 0x16, 0x15, 0x88, 0xb5, 0xd3, 0x92, 0x2c, 0xd8, - 0x88, 0xb0, 0xea, 0xf7, 0x02, 0xa4, 0x3b, 0xae, 0xe9, 0x18, 0x78, 0x88, 0x36, 0x41, 0xa6, 0x9e, - 0xd9, 0xc7, 0x5d, 0x7b, 0xc0, 0x8b, 0xc8, 0x69, 0x45, 0x86, 0xfd, 0xf9, 0xb4, 0x9c, 0x3e, 0x64, - 0xf7, 0xfa, 0xee, 0xd9, 0xf9, 0xd1, 0x48, 0x73, 0xac, 0x3e, 0x40, 0xf7, 0x21, 0xed, 0xbb, 0xa6, - 0xc3, 0xa2, 0x44, 0x1e, 0xa5, 0x44, 0x51, 0x29, 0x46, 0xcc, 0x83, 0xa2, 0x93, 0x91, 0x62, 0x40, - 0x7d, 0x80, 0x36, 0x40, 0xf6, 0xf0, 0x30, 0x9c, 0x57, 0x82, 0xcf, 0x6b, 0x75, 0xb1, 0xda, 0xa8, - 0x24, 0x3e, 0xb1, 0xb4, 0x17, 0x1e, 0xd4, 0xf7, 0x21, 0x7d, 0xe0, 0x91, 0x3e, 0xf6, 0x7d, 0x74, - 0x1b, 0x72, 0x3e, 0xf6, 0x02, 0xbb, 0x8f, 0xbb, 0x8e, 0x39, 0xc6, 0xd1, 0x26, 0x64, 0xa3, 0xbb, - 0x7d, 0x73, 0x8c, 0xd1, 0x3d, 0x48, 0x52, 0xd3, 0xba, 0x9c, 0x1a, 0x1c, 0xa9, 0xfe, 0x94, 0x84, - 0x24, 0x4b, 0xfc, 0x1f, 0x0a, 0xf1, 0x3c, 0xe4, 0x89, 0x8b, 0xc3, 0x3f, 0xc5, 0xb0, 0x93, 0x70, - 0x1f, 0x57, 0x66, 0xb7, 0xbc, 0x97, 0x57, 0x00, 0x3c, 0x3c, 0xc4, 0x1e, 0x76, 0xfa, 0xd8, 0x57, - 0x92, 0xbc, 0xa3, 0xeb, 0x17, 0x2a, 0x16, 0x35, 0x34, 0x07, 0x47, 0x77, 0x40, 0x1a, 0x8e, 0x98, - 0x12, 0x6c, 0x79, 0x57, 0xb4, 0x95, 0xa8, 0x28, 0xa9, 0xc9, 0x2e, 0x8d, 0xd0, 0x87, 0x76, 0x00, - 0x7c, 0x6a, 0x7a, 0xb4, 0xcb, 0x16, 0x8a, 0xef, 0xf2, 0xa5, 0x57, 0x90, 0xc7, 0x31, 0x0f, 0x7a, - 0x0d, 0xe4, 0xf8, 0x5d, 0xe1, 0x2b, 0x9f, 0x6d, 0xac, 0xfe, 0x89, 0x62, 0x37, 0x02, 0x84, 0x0c, - 0xdf, 0x30, 0x86, 0x59, 0xd0, 0x6c, 0x66, 0xf2, 0x65, 0x67, 0x86, 0x5e, 0x84, 0xe4, 0x88, 0x58, - 0xbe, 0x92, 0xe1, 0x11, 0x57, 0x17, 0x23, 0x5a, 0xc4, 0x8a, 0xc1, 0x0c, 0x84, 0xea, 0x90, 0x76, - 0xc3, 0x05, 0x52, 0x80, 0x97, 0xb7, 0xa4, 0x61, 0xb4, 0x5d, 0x46, 0x8c, 0x42, 0x2f, 0x01, 0x44, - 0x47, 0x36, 0xd4, 0x2c, 0x1b, 0x8d, 0xb6, 0x72, 0x76, 0x5a, 0xce, 0x44, 0x48, 0x7d, 0xd7, 0xc8, - 0x44, 0x00, 0x7d, 0x80, 0x8a, 0x20, 0x9f, 0x98, 0x9e, 0x63, 0x3b, 0x96, 0xaf, 0xe4, 0x2a, 0x89, - 0x6a, 0xc6, 0x98, 0xd9, 0xea, 0x17, 0x22, 0x48, 0x7c, 0x61, 0x50, 0x15, 0x24, 0x36, 0x7c, 0x5f, - 0x11, 0x78, 0xc9, 0xe8, 0x82, 0x31, 0x86, 0x00, 0xa4, 0x43, 0x36, 0xce, 0x3e, 0x36, 0xdd, 0x68, - 0x91, 0xd5, 0x45, 0x3c, 0xe7, 0x8c, 0x0b, 0xdf, 0x33, 0x5d, 0xd7, 0x76, 0xe2, 0x9e, 0xe3, 0xd2, - 0xf7, 0x4c, 0x77, 0xa1, 0xb4, 0xc4, 0x62, 0x69, 0xc5, 0x09, 0xe4, 0x17, 0xe3, 0x97, 0xda, 0x16, - 0xfe, 0xa6, 0xed, 0xcd, 0x73, 0x55, 0xc5, 0xbf, 0x50, 0x35, 0xaa, 0x2a, 0xc6, 0xaa, 0x47, 0x20, - 0x69, 0x26, 0xed, 0x1f, 0xfd, 0x03, 0x41, 0xfe, 0x65, 0xa6, 0x57, 0xa1, 0x70, 0x40, 0x7c, 0xca, - 0x98, 0x7c, 0x03, 0x7f, 0x38, 0xc1, 0x3e, 0x45, 0x77, 0x41, 0xea, 0xb1, 0xec, 0xd1, 0x6b, 0x7b, - 0x6d, 0x91, 0x88, 0x17, 0x66, 0x84, 0x08, 0xf5, 0x0e, 0x5c, 0x9d, 0x0b, 0xf7, 0x5d, 0xe2, 0xf8, - 0x18, 0xe5, 0x41, 0x24, 0xc7, 0x3c, 0x58, 0x36, 0x44, 0x72, 0xac, 0xde, 0x86, 0xff, 0x3d, 0xc4, - 0x94, 0x4f, 0x23, 0x4e, 0x91, 0x07, 0x31, 0x56, 0xcf, 0x10, 0xed, 0x01, 0x2b, 0xe3, 0x1c, 0x12, - 0xd1, 0xdc, 0x05, 0x89, 0xbf, 0x1e, 0x17, 0x97, 0x11, 0x62, 0x43, 0xc4, 0xda, 0xeb, 0x90, 0x99, - 0xfd, 0x17, 0x43, 0x00, 0xa9, 0xce, 0xa1, 0xa1, 0xef, 0x3f, 0x2c, 0x5c, 0x41, 0x32, 0x24, 0xb5, - 0x76, 0xbb, 0x55, 0x10, 0x50, 0x06, 0x24, 0x7d, 0xff, 0xf0, 0xc1, 0x46, 0x41, 0x44, 0x59, 0x48, - 0x37, 0x5b, 0xed, 0x6d, 0x66, 0x24, 0x18, 0x5a, 0xd3, 0xf7, 0xb7, 0x8d, 0x77, 0x0b, 0xc9, 0xb5, - 0x75, 0xc8, 0xce, 0x3d, 0xae, 0x28, 0x07, 0xf2, 0xce, 0x1b, 0x7a, 0x6b, 0xb7, 0xdb, 0x6e, 0x16, - 0xae, 0xa0, 0x02, 0xe4, 0x9a, 0xed, 0x56, 0xab, 0xfd, 0x4e, 0xa7, 0xdb, 0x34, 0xda, 0x7b, 0x05, - 0xa1, 0xf1, 0x09, 0xa0, 0x1d, 0x32, 0x1a, 0xe1, 0x3e, 0x25, 0x5e, 0x27, 0x7c, 0x5d, 0x1f, 0x35, - 0xd0, 0x10, 0x32, 0x33, 0x49, 0x50, 0x69, 0x69, 0x08, 0x4b, 0x52, 0x17, 0xcb, 0xcf, 0xf4, 0x87, - 0x22, 0xa8, 0xca, 0xe7, 0x4f, 0x7e, 0xff, 0x5a, 0x44, 0xea, 0x0a, 0xff, 0xfc, 0x08, 0x1a, 0x75, - 0x3e, 0xed, 0x2d, 0x61, 0xad, 0xf1, 0x11, 0xe4, 0xdf, 0x9e, 0x60, 0x6f, 0x3a, 0x9f, 0x59, 0x8e, - 0x45, 0x44, 0xcf, 0x2d, 0x12, 0x2f, 0xe9, 0x5f, 0x2c, 0x3d, 0xcb, 0x1d, 0xa5, 0xbd, 0xc5, 0xd3, - 0x5e, 0x47, 0xd7, 0xe2, 0xb4, 0x5c, 0x67, 0xbf, 0xfe, 0xb1, 0x3d, 0xf8, 0x54, 0xa3, 0x5f, 0x6d, - 0x6b, 0x48, 0x6a, 0x24, 0xee, 0xd7, 0xee, 0xad, 0x89, 0x82, 0xe8, 0x6d, 0x02, 0xbc, 0xc9, 0xd9, - 0x2a, 0xdb, 0x07, 0x3a, 0x7a, 0xe1, 0x88, 0x52, 0xd7, 0xdf, 0xaa, 0xd7, 0xe7, 0xbe, 0x61, 0xc2, - 0x64, 0x8c, 0xc3, 0x76, 0xac, 0xc8, 0x7a, 0x7c, 0x56, 0x12, 0x7e, 0x3c, 0x2b, 0x09, 0xbf, 0x9e, - 0x95, 0x84, 0x1f, 0x7e, 0x2b, 0x09, 0x70, 0xc3, 0x26, 0xb5, 0x05, 0x60, 0x58, 0xdc, 0x7b, 0x12, - 0xff, 0xe9, 0xa5, 0xf8, 0x33, 0xf9, 0xf2, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x29, 0x88, - 0x10, 0xeb, 0x09, 0x00, 0x00, + // 903 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x41, 0x8f, 0xdb, 0x44, + 0x14, 0xde, 0x49, 0xec, 0xd8, 0x79, 0x49, 0x56, 0xd1, 0x14, 0x58, 0x37, 0xa0, 0x24, 0xa4, 0x42, + 0x0a, 0x55, 0x49, 0xda, 0xd0, 0xee, 0x01, 0x21, 0xa1, 0xba, 0x4b, 0xc0, 0x90, 0xdd, 0xa0, 0xd9, + 0x08, 0x04, 0x17, 0x6b, 0x36, 0x99, 0x18, 0x17, 0xc7, 0x63, 0xd9, 0x5e, 0xa3, 0xdc, 0xf8, 0x09, + 0x88, 0x13, 0x47, 0xb8, 0xf2, 0x2b, 0x38, 0xf6, 0xc8, 0x81, 0x13, 0x12, 0x0b, 0x0a, 0x97, 0xfe, + 0x0c, 0x34, 0xe3, 0x71, 0xb6, 0x1b, 0x2a, 0x58, 0x38, 0x70, 0xf2, 0xcc, 0xbc, 0xef, 0xbd, 0xf9, + 0xde, 0xf7, 0x3e, 0xdb, 0x50, 0x5b, 0xf1, 0x05, 0x0b, 0x06, 0x51, 0xcc, 0x53, 0x8e, 0x1b, 0x8f, + 0x29, 0xf3, 0x58, 0x3c, 0xa0, 0x91, 0xef, 0x66, 0xa3, 0xd6, 0x0b, 0x1e, 0xf7, 0xb8, 0x8c, 0x0c, + 0xc5, 0x2a, 0x07, 0xb5, 0x5e, 0xf1, 0x38, 0xf7, 0x02, 0x36, 0xa4, 0x91, 0x3f, 0xa4, 0x61, 0xc8, + 0x53, 0x9a, 0xfa, 0x3c, 0x4c, 0x54, 0xb4, 0xa3, 0xa2, 0x72, 0x77, 0x76, 0xbe, 0x1c, 0xa6, 0xfe, + 0x8a, 0x25, 0x29, 0x5d, 0x45, 0x0a, 0xd0, 0xde, 0x05, 0x2c, 0xce, 0x63, 0x59, 0x21, 0x8f, 0xf7, + 0x7e, 0x46, 0x60, 0x7e, 0xc8, 0xd6, 0x1f, 0xd3, 0xe0, 0x9c, 0xe1, 0x26, 0x94, 0xbf, 0x60, 0x6b, + 0x0b, 0x75, 0x51, 0xbf, 0x4a, 0xc4, 0x12, 0x0f, 0xa1, 0x92, 0xb9, 0xe9, 0x3a, 0x62, 0x56, 0xa9, + 0x8b, 0xfa, 0xfb, 0x23, 0x6b, 0x70, 0x85, 0xf3, 0x40, 0xe6, 0xcd, 0xd6, 0x11, 0x23, 0x7a, 0x26, + 0x1e, 0xf8, 0x06, 0xe8, 0x99, 0x9b, 0xa4, 0xb1, 0x55, 0x96, 0x45, 0xb4, 0xec, 0x34, 0x8d, 0xf1, + 0x8b, 0xa2, 0xca, 0x19, 0xe7, 0x81, 0xa5, 0x75, 0x51, 0xdf, 0x24, 0x7a, 0x66, 0x73, 0x1e, 0xe0, + 0x03, 0x30, 0x32, 0xd7, 0x0f, 0xd3, 0xc3, 0xfb, 0x96, 0xde, 0x45, 0xfd, 0x32, 0xa9, 0x64, 0x8e, + 0xd8, 0xe1, 0x97, 0xa1, 0x9a, 0xb9, 0xcb, 0x80, 0x53, 0x11, 0xaa, 0x74, 0x51, 0x1f, 0x11, 0x33, + 0x1b, 0xe7, 0x7b, 0x7c, 0x13, 0xcc, 0xcc, 0x3d, 0xf3, 0x43, 0x1a, 0xaf, 0x2d, 0xa3, 0x8b, 0xfa, + 0x75, 0x62, 0x64, 0xb6, 0xdc, 0xbe, 0x65, 0x3e, 0xfd, 0xae, 0x83, 0x9e, 0x7e, 0xdf, 0x41, 0xbd, + 0xaf, 0x10, 0x94, 0x27, 0xdc, 0xc3, 0x36, 0x54, 0xb7, 0x8a, 0xc8, 0xbe, 0x6a, 0xa3, 0xd6, 0x20, + 0x97, 0x64, 0x50, 0x48, 0x32, 0x98, 0x15, 0x08, 0xdb, 0x7c, 0x72, 0xd1, 0xd9, 0xfb, 0xfa, 0xb7, + 0x0e, 0x22, 0x97, 0x69, 0xf8, 0x01, 0x54, 0x96, 0x3e, 0x0b, 0x16, 0x89, 0x55, 0xea, 0x96, 0xfb, + 0xb5, 0xd1, 0xc1, 0x8e, 0x06, 0x85, 0x7c, 0xb6, 0x26, 0xb2, 0x89, 0x02, 0xf7, 0x7e, 0x40, 0x60, + 0x9c, 0x46, 0x34, 0x24, 0x6c, 0x89, 0x1f, 0x80, 0x99, 0xc6, 0x74, 0xce, 0x5c, 0x7f, 0x21, 0x59, + 0xd4, 0xed, 0x96, 0xc0, 0xfe, 0x72, 0xd1, 0x31, 0x66, 0xe2, 0xdc, 0x39, 0xda, 0x5c, 0x2e, 0x89, + 0x21, 0xb1, 0xce, 0x02, 0xdf, 0x03, 0x23, 0x89, 0x68, 0x28, 0xb2, 0x4a, 0x32, 0xcb, 0x52, 0x59, + 0x15, 0x51, 0x58, 0x26, 0xa9, 0x15, 0xa9, 0x08, 0xa0, 0xb3, 0x10, 0x37, 0xc5, 0x6c, 0x99, 0x8f, + 0xac, 0x2c, 0x47, 0xd6, 0xda, 0xa1, 0xab, 0x38, 0xc9, 0xa1, 0x19, 0x71, 0xbe, 0xe8, 0xb9, 0x60, + 0x7c, 0x14, 0xf3, 0x39, 0x4b, 0x12, 0xfc, 0x2a, 0xd4, 0x13, 0x16, 0x67, 0xfe, 0x9c, 0xb9, 0x21, + 0x5d, 0x31, 0xe5, 0x86, 0x9a, 0x3a, 0x3b, 0xa1, 0x2b, 0x86, 0xef, 0x81, 0x96, 0x52, 0xef, 0x9a, + 0x7a, 0x48, 0x68, 0xef, 0x57, 0x0d, 0x34, 0x71, 0xf3, 0xff, 0x28, 0xc5, 0x6b, 0xb0, 0xcf, 0x23, + 0x96, 0xbb, 0x3d, 0x6f, 0x25, 0xf7, 0x64, 0x63, 0x7b, 0x2a, 0x9b, 0x79, 0x1b, 0x20, 0x66, 0x4b, + 0x16, 0xb3, 0x70, 0xce, 0x12, 0x4b, 0x93, 0x2d, 0xbd, 0xf4, 0x7c, 0xcd, 0x54, 0x47, 0xcf, 0xe0, + 0xf1, 0x2d, 0xd0, 0x97, 0x81, 0xd0, 0x42, 0x38, 0xb8, 0x61, 0x37, 0x14, 0x2b, 0x7d, 0x2c, 0x0e, + 0x49, 0x1e, 0xc3, 0x8f, 0x00, 0x92, 0x94, 0xc6, 0xa9, 0x2b, 0x4c, 0x25, 0x0d, 0x7d, 0x6d, 0x1b, + 0xca, 0x3c, 0x11, 0xc1, 0xef, 0x80, 0x59, 0xbc, 0xbb, 0xd2, 0xf7, 0xb5, 0xd1, 0xcd, 0xbf, 0x94, + 0x38, 0x52, 0x80, 0xbc, 0xc2, 0xb7, 0xa2, 0xc2, 0x36, 0x69, 0x3b, 0x35, 0xf3, 0xda, 0x53, 0xc3, + 0x77, 0x40, 0x0b, 0xb8, 0x97, 0x58, 0x55, 0x99, 0x82, 0x77, 0x52, 0x26, 0xdc, 0x2b, 0xd0, 0x02, + 0x85, 0xef, 0x82, 0x11, 0xe5, 0x26, 0xb2, 0x40, 0x12, 0xdc, 0x95, 0x51, 0x59, 0x8c, 0x14, 0x30, + 0x7c, 0x07, 0x40, 0x2d, 0xc5, 0x60, 0x6b, 0x62, 0x3c, 0x76, 0x63, 0x73, 0xd1, 0xa9, 0x2a, 0xa4, + 0x73, 0x44, 0xaa, 0x0a, 0xe0, 0x2c, 0x70, 0x0b, 0xcc, 0x2f, 0x69, 0x1c, 0xfa, 0xa1, 0x97, 0x58, + 0xf5, 0x6e, 0xb9, 0x5f, 0x25, 0xdb, 0x7d, 0xef, 0x9b, 0x12, 0xe8, 0xd2, 0x34, 0xf8, 0x75, 0xd0, + 0x85, 0x01, 0x12, 0x0b, 0x49, 0xd2, 0x37, 0x9e, 0x37, 0xca, 0x1c, 0x81, 0x3f, 0x80, 0x5a, 0x71, + 0xfd, 0x8a, 0x46, 0xca, 0xce, 0xb7, 0x76, 0x12, 0x64, 0xd5, 0x82, 0xfa, 0x31, 0x8d, 0x22, 0x3f, + 0x2c, 0xda, 0x2e, 0xc8, 0x1f, 0xd3, 0xe8, 0x0a, 0xb9, 0xf2, 0x55, 0x72, 0xad, 0x0c, 0xf6, 0xaf, + 0xe6, 0xef, 0x34, 0x8e, 0xfe, 0xa1, 0xf1, 0xc3, 0x4b, 0x61, 0x4b, 0x7f, 0x27, 0xac, 0xa2, 0x55, + 0x80, 0x7b, 0x8f, 0x41, 0xb7, 0x69, 0x3a, 0xff, 0xfc, 0xdf, 0x68, 0xf2, 0x1f, 0xef, 0xba, 0xfd, + 0x2e, 0x54, 0xb7, 0x3f, 0x03, 0x0c, 0x50, 0x39, 0x9d, 0x11, 0xe7, 0xe4, 0xbd, 0xe6, 0x1e, 0x36, + 0x41, 0xb3, 0xa7, 0xd3, 0x49, 0x13, 0xe1, 0x2a, 0xe8, 0xce, 0xc9, 0xec, 0xf0, 0x7e, 0xb3, 0x84, + 0x6b, 0x60, 0x8c, 0x27, 0xd3, 0x87, 0x62, 0x53, 0x16, 0x68, 0xdb, 0x39, 0x79, 0x48, 0x3e, 0x6d, + 0x6a, 0xb7, 0xdf, 0x80, 0xda, 0x33, 0x1f, 0x28, 0x5c, 0x07, 0xf3, 0xd1, 0xfb, 0xce, 0xe4, 0xc8, + 0x9d, 0x8e, 0x9b, 0x7b, 0xb8, 0x09, 0xf5, 0xf1, 0x74, 0x32, 0x99, 0x7e, 0x72, 0xea, 0x8e, 0xc9, + 0xf4, 0xb8, 0x89, 0xec, 0xbb, 0x4f, 0x36, 0x6d, 0xf4, 0xd3, 0xa6, 0x8d, 0x7e, 0xdf, 0xb4, 0xd1, + 0x8f, 0x7f, 0xb4, 0x11, 0x1c, 0xf8, 0x5c, 0x11, 0x16, 0x9f, 0x0e, 0x3f, 0xf4, 0x14, 0xef, 0xcf, + 0x74, 0xf9, 0xeb, 0x3d, 0xab, 0xc8, 0x97, 0xe5, 0xcd, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x28, + 0x10, 0xf8, 0xb3, 0x8a, 0x07, 0x00, 0x00, } diff --git a/model/model.pb.gw.go b/model/model.pb.gw.go deleted file mode 100644 index 56d52e6616a..00000000000 --- a/model/model.pb.gw.go +++ /dev/null @@ -1,227 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: model.proto - -/* -Package model is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package model - -import ( - "io" - "net/http" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray - -func request_CollectorServiceV2_PostSpans_0(ctx context.Context, marshaler runtime.Marshaler, client CollectorServiceV2Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq PostSpansRequest - var metadata runtime.ServerMetadata - - if req.ContentLength > 0 { - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - } - - msg, err := client.PostSpans(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_QueryServiceV2_GetTrace_0(ctx context.Context, marshaler runtime.Marshaler, client QueryServiceV2Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetTraceRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["id"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") - } - - protoReq.Id, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) - } - - msg, err := client.GetTrace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -// RegisterCollectorServiceV2HandlerFromEndpoint is same as RegisterCollectorServiceV2Handler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterCollectorServiceV2HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterCollectorServiceV2Handler(ctx, mux, conn) -} - -// RegisterCollectorServiceV2Handler registers the http handlers for service CollectorServiceV2 to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterCollectorServiceV2Handler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterCollectorServiceV2HandlerClient(ctx, mux, NewCollectorServiceV2Client(conn)) -} - -// RegisterCollectorServiceV2Handler registers the http handlers for service CollectorServiceV2 to "mux". -// The handlers forward requests to the grpc endpoint over the given implementation of "CollectorServiceV2Client". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "CollectorServiceV2Client" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "CollectorServiceV2Client" to call the correct interceptors. -func RegisterCollectorServiceV2HandlerClient(ctx context.Context, mux *runtime.ServeMux, client CollectorServiceV2Client) error { - - mux.Handle("POST", pattern_CollectorServiceV2_PostSpans_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_CollectorServiceV2_PostSpans_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_CollectorServiceV2_PostSpans_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_CollectorServiceV2_PostSpans_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "spans"}, "")) -) - -var ( - forward_CollectorServiceV2_PostSpans_0 = runtime.ForwardResponseMessage -) - -// RegisterQueryServiceV2HandlerFromEndpoint is same as RegisterQueryServiceV2Handler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterQueryServiceV2HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterQueryServiceV2Handler(ctx, mux, conn) -} - -// RegisterQueryServiceV2Handler registers the http handlers for service QueryServiceV2 to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterQueryServiceV2Handler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterQueryServiceV2HandlerClient(ctx, mux, NewQueryServiceV2Client(conn)) -} - -// RegisterQueryServiceV2Handler registers the http handlers for service QueryServiceV2 to "mux". -// The handlers forward requests to the grpc endpoint over the given implementation of "QueryServiceV2Client". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryServiceV2Client" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "QueryServiceV2Client" to call the correct interceptors. -func RegisterQueryServiceV2HandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryServiceV2Client) error { - - mux.Handle("GET", pattern_QueryServiceV2_GetTrace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_QueryServiceV2_GetTrace_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_QueryServiceV2_GetTrace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_QueryServiceV2_GetTrace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "traces", "id"}, "")) -) - -var ( - forward_QueryServiceV2_GetTrace_0 = runtime.ForwardResponseMessage -) diff --git a/model/proto/api_v2.proto b/model/proto/api_v2.proto new file mode 100644 index 00000000000..1fbc358aacd --- /dev/null +++ b/model/proto/api_v2.proto @@ -0,0 +1,111 @@ +// Copyright (c) 2018 Uber Technologies, Inc. +// +// 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. + +syntax="proto3"; + +package jaeger.api_v2; + +import "model.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "protoc-gen-swagger/options/annotations.proto"; + +option go_package = "api_v2"; +option java_package = "io.jaegertracing.api_v2"; + +// Enable gogoprotobuf extensions (https://github.com/gogo/protobuf/blob/master/extensions.md). +// Enable custom Marshal method. +option (gogoproto.marshaler_all) = true; +// Enable custom Unmarshal method. +option (gogoproto.unmarshaler_all) = true; +// Enable custom Size method (Required by Marshal and Unmarshal). +option (gogoproto.sizer_all) = true; +// Enable registration with golang/protobuf for the grpc-gateway. +option (gogoproto.goproto_registration) = true; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + version: "1.0"; + }; + external_docs: { + url: "https://github.com/jaegertracing/jaeger"; + description: "Jaeger API"; + } + schemes: HTTP; + schemes: HTTPS; +}; + +message PostSpansRequest { + Batch batch = 1 [ + (gogoproto.nullable) = false + ]; +} + +message PostSpansResponse { +} + +service CollectorService { + rpc PostSpans(PostSpansRequest) returns (PostSpansResponse) { + option (google.api.http) = { + post: "/api/v2/spans" + body: "*" + }; + } +} + +enum SamplingStrategyType { + PROBABILISTIC = 0; + RATE_LIMITING = 1; +}; + +message ProbabilisticSamplingStrategy { + double samplingRate = 1; +} + +message RateLimitingSamplingStrategy { + int32 maxTracesPerSecond = 1; +} + +message OperationSamplingStrategy { + string operation = 1; + ProbabilisticSamplingStrategy probabilisticSampling = 2; +} + +message PerOperationSamplingStrategies { + double defaultSamplingProbability = 1; + double defaultLowerBoundTracesPerSecond = 2; + repeated OperationSamplingStrategy perOperationStrategies = 3; + double defaultUpperBoundTracesPerSecond = 4; +} + +message SamplingStrategyResponse { + SamplingStrategyType strategyType = 1; + ProbabilisticSamplingStrategy probabilisticSampling = 2; + RateLimitingSamplingStrategy rateLimitingSampling = 3; + PerOperationSamplingStrategies operationSampling =4; +} + +message SamplingStrategyParameters { + string serviceName = 1; +} + +service SamplingManager { + rpc GetSamplingStrategy(SamplingStrategyParameters) returns (SamplingStrategyResponse) { + option (google.api.http) = { + post: "/api/v2/samplingStrategy" + body: "*" + }; + } +} + diff --git a/model/proto/model.proto b/model/proto/model.proto index ff6ce3c51b1..625e30b3df9 100644 --- a/model/proto/model.proto +++ b/model/proto/model.proto @@ -14,31 +14,20 @@ syntax="proto3"; -package jaeger.model; +package jaeger.api_v2; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; -import "google/api/annotations.proto"; -import "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.proto"; -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -// import "github.com/mwitkow/go-proto-validators/validator.proto"; // TODO: document all types and fields +// TODO: once this moves to jaeger-idl repo, we may want to change Go pkg to api_v2 +// and rewrite it to model only in this repo. That should make it easier to generate +// classes in other languages. option go_package = "model"; -option java_package = "io.jaegertracing.model"; - -option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { - info: { - version: "1.0"; - }; - external_docs: { - url: "https://github.com/jaegertracing/jaeger"; - description: "Jaeger API"; - } - schemes: HTTP; - schemes: HTTPS; -}; +option java_package = "io.jaegertracing.api_v2"; // Enable gogoprotobuf extensions (https://github.com/gogo/protobuf/blob/master/extensions.md). // Enable custom Marshal method. @@ -169,37 +158,3 @@ message Batch { (gogoproto.nullable) = false ]; } - -message PostSpansRequest { - Batch batch = 1; -} - -message PostSpansResponse { - bool ok = 1; -} - -// TODO: move services to another proto file. -service CollectorServiceV2 { - rpc PostSpans(PostSpansRequest) returns (PostSpansResponse) { - option (google.api.http) = { - post: "/api/v2/spans" - body: "*" - }; - } -} - -message GetTraceRequest { - string id = 1; -} - -message GetTraceResponse { - Trace trace = 1; -} - -service QueryServiceV2 { - rpc GetTrace(GetTraceRequest) returns (GetTraceResponse) { - option (google.api.http) = { - get: "/api/v2/traces/{id}" - }; - } -} \ No newline at end of file diff --git a/model/proto/prototool.yaml b/model/proto/prototool.yaml index bdfbae6b652..8fa270b980d 100644 --- a/model/proto/prototool.yaml +++ b/model/proto/prototool.yaml @@ -1,11 +1,12 @@ protoc_includes: # note vendor is .gitignored - - ../../vendor/ + - ../../vendor/github.com/gogo/protobuf + - ../../vendor/github.com/gogo/googleapis - ../../vendor/github.com/grpc-ecosystem/grpc-gateway - - ../../vendor/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis lint: exclude_ids: - FILE_OPTIONS_EQUAL_GO_PACKAGE_PB_SUFFIX + - FILE_OPTIONS_EQUAL_JAVA_PACKAGE_COM_PB - ENUM_FIELD_PREFIXES - ENUM_ZERO_VALUES_INVALID diff --git a/proto-gen/api_v2/api_v2.pb.go b/proto-gen/api_v2/api_v2.pb.go new file mode 100644 index 00000000000..64affc52580 --- /dev/null +++ b/proto-gen/api_v2/api_v2.pb.go @@ -0,0 +1,1669 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: api_v2.proto + +/* + Package api_v2 is a generated protocol buffer package. + + It is generated from these files: + api_v2.proto + + It has these top-level messages: + PostSpansRequest + PostSpansResponse + ProbabilisticSamplingStrategy + RateLimitingSamplingStrategy + OperationSamplingStrategy + PerOperationSamplingStrategies + SamplingStrategyResponse + SamplingStrategyParameters +*/ +package api_v2 + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import jaeger_api_v2 "github.com/jaegertracing/jaeger/model" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "github.com/gogo/googleapis/google/api" +import _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" + +import binary "encoding/binary" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type SamplingStrategyType int32 + +const ( + SamplingStrategyType_PROBABILISTIC SamplingStrategyType = 0 + SamplingStrategyType_RATE_LIMITING SamplingStrategyType = 1 +) + +var SamplingStrategyType_name = map[int32]string{ + 0: "PROBABILISTIC", + 1: "RATE_LIMITING", +} +var SamplingStrategyType_value = map[string]int32{ + "PROBABILISTIC": 0, + "RATE_LIMITING": 1, +} + +func (x SamplingStrategyType) String() string { + return proto.EnumName(SamplingStrategyType_name, int32(x)) +} +func (SamplingStrategyType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{0} } + +type PostSpansRequest struct { + Batch jaeger_api_v2.Batch `protobuf:"bytes,1,opt,name=batch" json:"batch"` +} + +func (m *PostSpansRequest) Reset() { *m = PostSpansRequest{} } +func (m *PostSpansRequest) String() string { return proto.CompactTextString(m) } +func (*PostSpansRequest) ProtoMessage() {} +func (*PostSpansRequest) Descriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{0} } + +func (m *PostSpansRequest) GetBatch() jaeger_api_v2.Batch { + if m != nil { + return m.Batch + } + return jaeger_api_v2.Batch{} +} + +type PostSpansResponse struct { +} + +func (m *PostSpansResponse) Reset() { *m = PostSpansResponse{} } +func (m *PostSpansResponse) String() string { return proto.CompactTextString(m) } +func (*PostSpansResponse) ProtoMessage() {} +func (*PostSpansResponse) Descriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{1} } + +type ProbabilisticSamplingStrategy struct { + SamplingRate float64 `protobuf:"fixed64,1,opt,name=samplingRate,proto3" json:"samplingRate,omitempty"` +} + +func (m *ProbabilisticSamplingStrategy) Reset() { *m = ProbabilisticSamplingStrategy{} } +func (m *ProbabilisticSamplingStrategy) String() string { return proto.CompactTextString(m) } +func (*ProbabilisticSamplingStrategy) ProtoMessage() {} +func (*ProbabilisticSamplingStrategy) Descriptor() ([]byte, []int) { + return fileDescriptorApiV2, []int{2} +} + +func (m *ProbabilisticSamplingStrategy) GetSamplingRate() float64 { + if m != nil { + return m.SamplingRate + } + return 0 +} + +type RateLimitingSamplingStrategy struct { + MaxTracesPerSecond int32 `protobuf:"varint,1,opt,name=maxTracesPerSecond,proto3" json:"maxTracesPerSecond,omitempty"` +} + +func (m *RateLimitingSamplingStrategy) Reset() { *m = RateLimitingSamplingStrategy{} } +func (m *RateLimitingSamplingStrategy) String() string { return proto.CompactTextString(m) } +func (*RateLimitingSamplingStrategy) ProtoMessage() {} +func (*RateLimitingSamplingStrategy) Descriptor() ([]byte, []int) { + return fileDescriptorApiV2, []int{3} +} + +func (m *RateLimitingSamplingStrategy) GetMaxTracesPerSecond() int32 { + if m != nil { + return m.MaxTracesPerSecond + } + return 0 +} + +type OperationSamplingStrategy struct { + Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `protobuf:"bytes,2,opt,name=probabilisticSampling" json:"probabilisticSampling,omitempty"` +} + +func (m *OperationSamplingStrategy) Reset() { *m = OperationSamplingStrategy{} } +func (m *OperationSamplingStrategy) String() string { return proto.CompactTextString(m) } +func (*OperationSamplingStrategy) ProtoMessage() {} +func (*OperationSamplingStrategy) Descriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{4} } + +func (m *OperationSamplingStrategy) GetOperation() string { + if m != nil { + return m.Operation + } + return "" +} + +func (m *OperationSamplingStrategy) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if m != nil { + return m.ProbabilisticSampling + } + return nil +} + +type PerOperationSamplingStrategies struct { + DefaultSamplingProbability float64 `protobuf:"fixed64,1,opt,name=defaultSamplingProbability,proto3" json:"defaultSamplingProbability,omitempty"` + DefaultLowerBoundTracesPerSecond float64 `protobuf:"fixed64,2,opt,name=defaultLowerBoundTracesPerSecond,proto3" json:"defaultLowerBoundTracesPerSecond,omitempty"` + PerOperationStrategies []*OperationSamplingStrategy `protobuf:"bytes,3,rep,name=perOperationStrategies" json:"perOperationStrategies,omitempty"` + DefaultUpperBoundTracesPerSecond float64 `protobuf:"fixed64,4,opt,name=defaultUpperBoundTracesPerSecond,proto3" json:"defaultUpperBoundTracesPerSecond,omitempty"` +} + +func (m *PerOperationSamplingStrategies) Reset() { *m = PerOperationSamplingStrategies{} } +func (m *PerOperationSamplingStrategies) String() string { return proto.CompactTextString(m) } +func (*PerOperationSamplingStrategies) ProtoMessage() {} +func (*PerOperationSamplingStrategies) Descriptor() ([]byte, []int) { + return fileDescriptorApiV2, []int{5} +} + +func (m *PerOperationSamplingStrategies) GetDefaultSamplingProbability() float64 { + if m != nil { + return m.DefaultSamplingProbability + } + return 0 +} + +func (m *PerOperationSamplingStrategies) GetDefaultLowerBoundTracesPerSecond() float64 { + if m != nil { + return m.DefaultLowerBoundTracesPerSecond + } + return 0 +} + +func (m *PerOperationSamplingStrategies) GetPerOperationStrategies() []*OperationSamplingStrategy { + if m != nil { + return m.PerOperationStrategies + } + return nil +} + +func (m *PerOperationSamplingStrategies) GetDefaultUpperBoundTracesPerSecond() float64 { + if m != nil { + return m.DefaultUpperBoundTracesPerSecond + } + return 0 +} + +type SamplingStrategyResponse struct { + StrategyType SamplingStrategyType `protobuf:"varint,1,opt,name=strategyType,proto3,enum=jaeger.api_v2.SamplingStrategyType" json:"strategyType,omitempty"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `protobuf:"bytes,2,opt,name=probabilisticSampling" json:"probabilisticSampling,omitempty"` + RateLimitingSampling *RateLimitingSamplingStrategy `protobuf:"bytes,3,opt,name=rateLimitingSampling" json:"rateLimitingSampling,omitempty"` + OperationSampling *PerOperationSamplingStrategies `protobuf:"bytes,4,opt,name=operationSampling" json:"operationSampling,omitempty"` +} + +func (m *SamplingStrategyResponse) Reset() { *m = SamplingStrategyResponse{} } +func (m *SamplingStrategyResponse) String() string { return proto.CompactTextString(m) } +func (*SamplingStrategyResponse) ProtoMessage() {} +func (*SamplingStrategyResponse) Descriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{6} } + +func (m *SamplingStrategyResponse) GetStrategyType() SamplingStrategyType { + if m != nil { + return m.StrategyType + } + return SamplingStrategyType_PROBABILISTIC +} + +func (m *SamplingStrategyResponse) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if m != nil { + return m.ProbabilisticSampling + } + return nil +} + +func (m *SamplingStrategyResponse) GetRateLimitingSampling() *RateLimitingSamplingStrategy { + if m != nil { + return m.RateLimitingSampling + } + return nil +} + +func (m *SamplingStrategyResponse) GetOperationSampling() *PerOperationSamplingStrategies { + if m != nil { + return m.OperationSampling + } + return nil +} + +type SamplingStrategyParameters struct { + ServiceName string `protobuf:"bytes,1,opt,name=serviceName,proto3" json:"serviceName,omitempty"` +} + +func (m *SamplingStrategyParameters) Reset() { *m = SamplingStrategyParameters{} } +func (m *SamplingStrategyParameters) String() string { return proto.CompactTextString(m) } +func (*SamplingStrategyParameters) ProtoMessage() {} +func (*SamplingStrategyParameters) Descriptor() ([]byte, []int) { return fileDescriptorApiV2, []int{7} } + +func (m *SamplingStrategyParameters) GetServiceName() string { + if m != nil { + return m.ServiceName + } + return "" +} + +func init() { + proto.RegisterType((*PostSpansRequest)(nil), "jaeger.api_v2.PostSpansRequest") + golang_proto.RegisterType((*PostSpansRequest)(nil), "jaeger.api_v2.PostSpansRequest") + proto.RegisterType((*PostSpansResponse)(nil), "jaeger.api_v2.PostSpansResponse") + golang_proto.RegisterType((*PostSpansResponse)(nil), "jaeger.api_v2.PostSpansResponse") + proto.RegisterType((*ProbabilisticSamplingStrategy)(nil), "jaeger.api_v2.ProbabilisticSamplingStrategy") + golang_proto.RegisterType((*ProbabilisticSamplingStrategy)(nil), "jaeger.api_v2.ProbabilisticSamplingStrategy") + proto.RegisterType((*RateLimitingSamplingStrategy)(nil), "jaeger.api_v2.RateLimitingSamplingStrategy") + golang_proto.RegisterType((*RateLimitingSamplingStrategy)(nil), "jaeger.api_v2.RateLimitingSamplingStrategy") + proto.RegisterType((*OperationSamplingStrategy)(nil), "jaeger.api_v2.OperationSamplingStrategy") + golang_proto.RegisterType((*OperationSamplingStrategy)(nil), "jaeger.api_v2.OperationSamplingStrategy") + proto.RegisterType((*PerOperationSamplingStrategies)(nil), "jaeger.api_v2.PerOperationSamplingStrategies") + golang_proto.RegisterType((*PerOperationSamplingStrategies)(nil), "jaeger.api_v2.PerOperationSamplingStrategies") + proto.RegisterType((*SamplingStrategyResponse)(nil), "jaeger.api_v2.SamplingStrategyResponse") + golang_proto.RegisterType((*SamplingStrategyResponse)(nil), "jaeger.api_v2.SamplingStrategyResponse") + proto.RegisterType((*SamplingStrategyParameters)(nil), "jaeger.api_v2.SamplingStrategyParameters") + golang_proto.RegisterType((*SamplingStrategyParameters)(nil), "jaeger.api_v2.SamplingStrategyParameters") + proto.RegisterEnum("jaeger.api_v2.SamplingStrategyType", SamplingStrategyType_name, SamplingStrategyType_value) + golang_proto.RegisterEnum("jaeger.api_v2.SamplingStrategyType", SamplingStrategyType_name, SamplingStrategyType_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for CollectorService service + +type CollectorServiceClient interface { + PostSpans(ctx context.Context, in *PostSpansRequest, opts ...grpc.CallOption) (*PostSpansResponse, error) +} + +type collectorServiceClient struct { + cc *grpc.ClientConn +} + +func NewCollectorServiceClient(cc *grpc.ClientConn) CollectorServiceClient { + return &collectorServiceClient{cc} +} + +func (c *collectorServiceClient) PostSpans(ctx context.Context, in *PostSpansRequest, opts ...grpc.CallOption) (*PostSpansResponse, error) { + out := new(PostSpansResponse) + err := grpc.Invoke(ctx, "/jaeger.api_v2.CollectorService/PostSpans", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for CollectorService service + +type CollectorServiceServer interface { + PostSpans(context.Context, *PostSpansRequest) (*PostSpansResponse, error) +} + +func RegisterCollectorServiceServer(s *grpc.Server, srv CollectorServiceServer) { + s.RegisterService(&_CollectorService_serviceDesc, srv) +} + +func _CollectorService_PostSpans_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PostSpansRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CollectorServiceServer).PostSpans(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/jaeger.api_v2.CollectorService/PostSpans", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CollectorServiceServer).PostSpans(ctx, req.(*PostSpansRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _CollectorService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "jaeger.api_v2.CollectorService", + HandlerType: (*CollectorServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PostSpans", + Handler: _CollectorService_PostSpans_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api_v2.proto", +} + +// Client API for SamplingManager service + +type SamplingManagerClient interface { + GetSamplingStrategy(ctx context.Context, in *SamplingStrategyParameters, opts ...grpc.CallOption) (*SamplingStrategyResponse, error) +} + +type samplingManagerClient struct { + cc *grpc.ClientConn +} + +func NewSamplingManagerClient(cc *grpc.ClientConn) SamplingManagerClient { + return &samplingManagerClient{cc} +} + +func (c *samplingManagerClient) GetSamplingStrategy(ctx context.Context, in *SamplingStrategyParameters, opts ...grpc.CallOption) (*SamplingStrategyResponse, error) { + out := new(SamplingStrategyResponse) + err := grpc.Invoke(ctx, "/jaeger.api_v2.SamplingManager/GetSamplingStrategy", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for SamplingManager service + +type SamplingManagerServer interface { + GetSamplingStrategy(context.Context, *SamplingStrategyParameters) (*SamplingStrategyResponse, error) +} + +func RegisterSamplingManagerServer(s *grpc.Server, srv SamplingManagerServer) { + s.RegisterService(&_SamplingManager_serviceDesc, srv) +} + +func _SamplingManager_GetSamplingStrategy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SamplingStrategyParameters) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SamplingManagerServer).GetSamplingStrategy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/jaeger.api_v2.SamplingManager/GetSamplingStrategy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SamplingManagerServer).GetSamplingStrategy(ctx, req.(*SamplingStrategyParameters)) + } + return interceptor(ctx, in, info, handler) +} + +var _SamplingManager_serviceDesc = grpc.ServiceDesc{ + ServiceName: "jaeger.api_v2.SamplingManager", + HandlerType: (*SamplingManagerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetSamplingStrategy", + Handler: _SamplingManager_GetSamplingStrategy_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api_v2.proto", +} + +func (m *PostSpansRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PostSpansRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.Batch.Size())) + n1, err := m.Batch.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + return i, nil +} + +func (m *PostSpansResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PostSpansResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *ProbabilisticSamplingStrategy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ProbabilisticSamplingStrategy) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.SamplingRate != 0 { + dAtA[i] = 0x9 + i++ + binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.SamplingRate)))) + i += 8 + } + return i, nil +} + +func (m *RateLimitingSamplingStrategy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RateLimitingSamplingStrategy) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.MaxTracesPerSecond != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.MaxTracesPerSecond)) + } + return i, nil +} + +func (m *OperationSamplingStrategy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OperationSamplingStrategy) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Operation) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintApiV2(dAtA, i, uint64(len(m.Operation))) + i += copy(dAtA[i:], m.Operation) + } + if m.ProbabilisticSampling != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.ProbabilisticSampling.Size())) + n2, err := m.ProbabilisticSampling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} + +func (m *PerOperationSamplingStrategies) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PerOperationSamplingStrategies) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.DefaultSamplingProbability != 0 { + dAtA[i] = 0x9 + i++ + binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.DefaultSamplingProbability)))) + i += 8 + } + if m.DefaultLowerBoundTracesPerSecond != 0 { + dAtA[i] = 0x11 + i++ + binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.DefaultLowerBoundTracesPerSecond)))) + i += 8 + } + if len(m.PerOperationStrategies) > 0 { + for _, msg := range m.PerOperationStrategies { + dAtA[i] = 0x1a + i++ + i = encodeVarintApiV2(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.DefaultUpperBoundTracesPerSecond != 0 { + dAtA[i] = 0x21 + i++ + binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.DefaultUpperBoundTracesPerSecond)))) + i += 8 + } + return i, nil +} + +func (m *SamplingStrategyResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SamplingStrategyResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.StrategyType != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.StrategyType)) + } + if m.ProbabilisticSampling != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.ProbabilisticSampling.Size())) + n3, err := m.ProbabilisticSampling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.RateLimitingSampling != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.RateLimitingSampling.Size())) + n4, err := m.RateLimitingSampling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + if m.OperationSampling != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintApiV2(dAtA, i, uint64(m.OperationSampling.Size())) + n5, err := m.OperationSampling.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + return i, nil +} + +func (m *SamplingStrategyParameters) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SamplingStrategyParameters) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ServiceName) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintApiV2(dAtA, i, uint64(len(m.ServiceName))) + i += copy(dAtA[i:], m.ServiceName) + } + return i, nil +} + +func encodeVarintApiV2(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *PostSpansRequest) Size() (n int) { + var l int + _ = l + l = m.Batch.Size() + n += 1 + l + sovApiV2(uint64(l)) + return n +} + +func (m *PostSpansResponse) Size() (n int) { + var l int + _ = l + return n +} + +func (m *ProbabilisticSamplingStrategy) Size() (n int) { + var l int + _ = l + if m.SamplingRate != 0 { + n += 9 + } + return n +} + +func (m *RateLimitingSamplingStrategy) Size() (n int) { + var l int + _ = l + if m.MaxTracesPerSecond != 0 { + n += 1 + sovApiV2(uint64(m.MaxTracesPerSecond)) + } + return n +} + +func (m *OperationSamplingStrategy) Size() (n int) { + var l int + _ = l + l = len(m.Operation) + if l > 0 { + n += 1 + l + sovApiV2(uint64(l)) + } + if m.ProbabilisticSampling != nil { + l = m.ProbabilisticSampling.Size() + n += 1 + l + sovApiV2(uint64(l)) + } + return n +} + +func (m *PerOperationSamplingStrategies) Size() (n int) { + var l int + _ = l + if m.DefaultSamplingProbability != 0 { + n += 9 + } + if m.DefaultLowerBoundTracesPerSecond != 0 { + n += 9 + } + if len(m.PerOperationStrategies) > 0 { + for _, e := range m.PerOperationStrategies { + l = e.Size() + n += 1 + l + sovApiV2(uint64(l)) + } + } + if m.DefaultUpperBoundTracesPerSecond != 0 { + n += 9 + } + return n +} + +func (m *SamplingStrategyResponse) Size() (n int) { + var l int + _ = l + if m.StrategyType != 0 { + n += 1 + sovApiV2(uint64(m.StrategyType)) + } + if m.ProbabilisticSampling != nil { + l = m.ProbabilisticSampling.Size() + n += 1 + l + sovApiV2(uint64(l)) + } + if m.RateLimitingSampling != nil { + l = m.RateLimitingSampling.Size() + n += 1 + l + sovApiV2(uint64(l)) + } + if m.OperationSampling != nil { + l = m.OperationSampling.Size() + n += 1 + l + sovApiV2(uint64(l)) + } + return n +} + +func (m *SamplingStrategyParameters) Size() (n int) { + var l int + _ = l + l = len(m.ServiceName) + if l > 0 { + n += 1 + l + sovApiV2(uint64(l)) + } + return n +} + +func sovApiV2(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozApiV2(x uint64) (n int) { + return sovApiV2(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PostSpansRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PostSpansRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PostSpansRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Batch", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Batch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PostSpansResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PostSpansResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PostSpansResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ProbabilisticSamplingStrategy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ProbabilisticSamplingStrategy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProbabilisticSamplingStrategy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field SamplingRate", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.SamplingRate = float64(math.Float64frombits(v)) + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RateLimitingSamplingStrategy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RateLimitingSamplingStrategy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RateLimitingSamplingStrategy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTracesPerSecond", wireType) + } + m.MaxTracesPerSecond = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxTracesPerSecond |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OperationSamplingStrategy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OperationSamplingStrategy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OperationSamplingStrategy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operation = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProbabilisticSampling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProbabilisticSampling == nil { + m.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + } + if err := m.ProbabilisticSampling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PerOperationSamplingStrategies) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PerOperationSamplingStrategies: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PerOperationSamplingStrategies: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultSamplingProbability", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.DefaultSamplingProbability = float64(math.Float64frombits(v)) + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultLowerBoundTracesPerSecond", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.DefaultLowerBoundTracesPerSecond = float64(math.Float64frombits(v)) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PerOperationStrategies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PerOperationStrategies = append(m.PerOperationStrategies, &OperationSamplingStrategy{}) + if err := m.PerOperationStrategies[len(m.PerOperationStrategies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultUpperBoundTracesPerSecond", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.DefaultUpperBoundTracesPerSecond = float64(math.Float64frombits(v)) + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SamplingStrategyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SamplingStrategyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SamplingStrategyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StrategyType", wireType) + } + m.StrategyType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StrategyType |= (SamplingStrategyType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProbabilisticSampling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProbabilisticSampling == nil { + m.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + } + if err := m.ProbabilisticSampling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RateLimitingSampling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RateLimitingSampling == nil { + m.RateLimitingSampling = &RateLimitingSamplingStrategy{} + } + if err := m.RateLimitingSampling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperationSampling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OperationSampling == nil { + m.OperationSampling = &PerOperationSamplingStrategies{} + } + if err := m.OperationSampling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SamplingStrategyParameters) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SamplingStrategyParameters: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SamplingStrategyParameters: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServiceName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApiV2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApiV2 + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ServiceName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApiV2(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthApiV2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipApiV2(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApiV2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApiV2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApiV2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthApiV2 + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowApiV2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipApiV2(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthApiV2 = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowApiV2 = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("api_v2.proto", fileDescriptorApiV2) } +func init() { golang_proto.RegisterFile("api_v2.proto", fileDescriptorApiV2) } + +var fileDescriptorApiV2 = []byte{ + // 733 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x4f, 0x13, 0x41, + 0x14, 0x66, 0x5b, 0x20, 0xe1, 0x15, 0xb4, 0x0c, 0x55, 0x6b, 0x03, 0xa5, 0x59, 0x0e, 0x60, 0x85, + 0x5d, 0x5c, 0xe3, 0x85, 0x18, 0x92, 0x16, 0x0d, 0x29, 0x29, 0xd0, 0x6c, 0xeb, 0x45, 0x0f, 0x38, + 0xdd, 0x8e, 0xdb, 0x35, 0xed, 0xce, 0x38, 0x33, 0x2d, 0x92, 0x78, 0x32, 0xf1, 0xea, 0x41, 0xcf, + 0x5e, 0xfc, 0x4b, 0x3c, 0x72, 0x34, 0xf1, 0xe6, 0xc1, 0x18, 0xf4, 0x0f, 0x31, 0x9d, 0x2e, 0xa5, + 0xdd, 0xfe, 0xe0, 0xe6, 0x69, 0xb7, 0xef, 0x7d, 0xf3, 0xbd, 0xef, 0x7d, 0xfb, 0xe6, 0x15, 0xe6, + 0x31, 0xf3, 0x4e, 0xda, 0x96, 0xc1, 0x38, 0x95, 0x14, 0x2d, 0xbc, 0xc6, 0xc4, 0x25, 0xdc, 0xe8, + 0x06, 0x53, 0xb1, 0x26, 0xad, 0x91, 0x46, 0x37, 0x97, 0x4a, 0xb8, 0xd4, 0xa5, 0xea, 0xd5, 0xec, + 0xbc, 0x05, 0xd1, 0x65, 0x97, 0x52, 0xb7, 0x41, 0x4c, 0xcc, 0x3c, 0x13, 0xfb, 0x3e, 0x95, 0x58, + 0x7a, 0xd4, 0x17, 0x41, 0x76, 0x53, 0x3d, 0x9c, 0x2d, 0x97, 0xf8, 0x5b, 0xe2, 0x14, 0xbb, 0x2e, + 0xe1, 0x26, 0x65, 0x0a, 0x31, 0x8c, 0xd6, 0x9f, 0x40, 0xbc, 0x44, 0x85, 0x2c, 0x33, 0xec, 0x0b, + 0x9b, 0xbc, 0x69, 0x11, 0x21, 0xd1, 0x36, 0xcc, 0x54, 0xb1, 0x74, 0xea, 0x49, 0x2d, 0xa3, 0x6d, + 0xc4, 0xac, 0x84, 0x31, 0xa0, 0xd0, 0xc8, 0x77, 0x72, 0xf9, 0xe9, 0xf3, 0x5f, 0xab, 0x53, 0x76, + 0x17, 0xa8, 0x2f, 0xc1, 0x62, 0x1f, 0x8b, 0x60, 0xd4, 0x17, 0x44, 0xdf, 0x83, 0x95, 0x12, 0xa7, + 0x55, 0x5c, 0xf5, 0x1a, 0x9e, 0x90, 0x9e, 0x53, 0xc6, 0x4d, 0xd6, 0xf0, 0x7c, 0xb7, 0x2c, 0x39, + 0x96, 0xc4, 0x3d, 0x43, 0x3a, 0xcc, 0x8b, 0x20, 0x66, 0x63, 0x49, 0x54, 0x39, 0xcd, 0x1e, 0x88, + 0xe9, 0x47, 0xb0, 0xdc, 0x79, 0x16, 0xbd, 0xa6, 0x27, 0x3b, 0x67, 0xc3, 0x1c, 0x06, 0xa0, 0x26, + 0x7e, 0x5b, 0xe1, 0xd8, 0x21, 0xa2, 0x44, 0x78, 0x99, 0x38, 0xd4, 0xaf, 0x29, 0xa6, 0x19, 0x7b, + 0x44, 0x46, 0xff, 0xa2, 0xc1, 0xdd, 0x63, 0x46, 0xb8, 0x32, 0x61, 0x88, 0x6d, 0x19, 0xe6, 0xe8, + 0x65, 0x52, 0x91, 0xcc, 0xd9, 0x57, 0x01, 0x54, 0x85, 0x5b, 0x6c, 0x54, 0x43, 0xc9, 0x88, 0xf2, + 0x69, 0x33, 0xe4, 0xd3, 0xc4, 0xe6, 0xed, 0xd1, 0x54, 0xfa, 0xcf, 0x08, 0xa4, 0x4b, 0x84, 0x8f, + 0x93, 0xe8, 0x11, 0x81, 0x76, 0x21, 0x55, 0x23, 0xaf, 0x70, 0xab, 0x21, 0x2f, 0x93, 0xbd, 0x4a, + 0xf2, 0x2c, 0x30, 0x71, 0x02, 0x02, 0x1d, 0x40, 0x26, 0xc8, 0x16, 0xe9, 0x29, 0xe1, 0x79, 0xda, + 0xf2, 0x6b, 0x61, 0x03, 0x23, 0x8a, 0xe5, 0x5a, 0x1c, 0x7a, 0x09, 0xb7, 0x59, 0xbf, 0xda, 0x9e, + 0xca, 0x64, 0x34, 0x13, 0xdd, 0x88, 0x59, 0x1b, 0x21, 0x4f, 0xc6, 0x5a, 0x6f, 0x8f, 0xe1, 0xe9, + 0x53, 0xfb, 0x8c, 0xb1, 0x31, 0x6a, 0xa7, 0x07, 0xd4, 0x8e, 0xc5, 0xe9, 0x1f, 0xa2, 0x90, 0x1c, + 0x2a, 0x1c, 0x8c, 0x2b, 0xda, 0x87, 0x79, 0x11, 0xc4, 0x2a, 0x67, 0xac, 0x3b, 0x8d, 0x37, 0xac, + 0xb5, 0x50, 0x03, 0xe1, 0xe3, 0x1d, 0xa8, 0x3d, 0x70, 0xf0, 0x7f, 0x8c, 0x09, 0x3a, 0x81, 0x04, + 0x1f, 0x71, 0x2d, 0x92, 0x51, 0x55, 0xe2, 0x7e, 0xa8, 0xc4, 0xa4, 0x1b, 0x64, 0x8f, 0x24, 0x42, + 0x2f, 0x60, 0x91, 0x86, 0xbf, 0x95, 0xf2, 0x39, 0x66, 0x6d, 0x85, 0x1b, 0x98, 0x38, 0xae, 0xf6, + 0x30, 0x8f, 0xbe, 0x0b, 0xa9, 0xb0, 0x8c, 0x12, 0xe6, 0xb8, 0x49, 0x24, 0xe1, 0x02, 0x65, 0x20, + 0x26, 0x08, 0x6f, 0x7b, 0x0e, 0x39, 0xc2, 0x4d, 0x12, 0x5c, 0xc3, 0xfe, 0x50, 0xf6, 0x31, 0x24, + 0x46, 0x7d, 0x07, 0xb4, 0x08, 0x0b, 0x25, 0xfb, 0x38, 0x9f, 0xcb, 0x17, 0x8a, 0x85, 0x72, 0xa5, + 0xb0, 0x17, 0x9f, 0xea, 0x84, 0xec, 0x5c, 0xe5, 0xe9, 0x49, 0xb1, 0x70, 0x58, 0xa8, 0x14, 0x8e, + 0xf6, 0xe3, 0x9a, 0xf5, 0x0e, 0xe2, 0x7b, 0xb4, 0xd1, 0x20, 0x8e, 0xa4, 0xbc, 0xdc, 0x65, 0x45, + 0x75, 0x98, 0xeb, 0x2d, 0x30, 0xb4, 0x1a, 0x6e, 0x30, 0xb4, 0x20, 0x53, 0x99, 0xf1, 0x80, 0x60, + 0xf7, 0x25, 0xdf, 0xff, 0xf8, 0xfb, 0x39, 0x82, 0xf4, 0x05, 0xb5, 0xa4, 0xdb, 0x96, 0x29, 0x3a, + 0xe9, 0x1d, 0x2d, 0x6b, 0x7d, 0xd5, 0xe0, 0xe6, 0xa5, 0xf8, 0x43, 0xec, 0x63, 0x97, 0x70, 0xf4, + 0x51, 0x83, 0xa5, 0x7d, 0x22, 0x87, 0xd6, 0xd1, 0xbd, 0x6b, 0x86, 0xef, 0xca, 0xb4, 0xd4, 0xfa, + 0x35, 0xd0, 0x9e, 0xb2, 0x35, 0xa5, 0x6c, 0x45, 0x4f, 0xf6, 0x94, 0x85, 0x90, 0x3b, 0x5a, 0x36, + 0xdf, 0xfe, 0x94, 0xcb, 0xa3, 0x19, 0x2b, 0xfa, 0xc0, 0xd8, 0xce, 0x46, 0xb4, 0x08, 0x7f, 0x04, + 0x70, 0xa0, 0xe8, 0x33, 0xb9, 0x52, 0x01, 0xad, 0xd7, 0xa5, 0x64, 0x62, 0xc7, 0x34, 0x5d, 0x4f, + 0xd6, 0x5b, 0x55, 0xc3, 0xa1, 0x4d, 0xb3, 0x5b, 0x5d, 0x72, 0xec, 0x78, 0xbe, 0x1b, 0xfc, 0x3a, + 0xbf, 0x48, 0x6b, 0xdf, 0x2f, 0xd2, 0xda, 0xef, 0x8b, 0xb4, 0xf6, 0xed, 0x4f, 0x5a, 0x83, 0x3b, + 0x1e, 0x35, 0x06, 0x80, 0x81, 0xda, 0xe7, 0xb3, 0xdd, 0x67, 0x75, 0x56, 0xfd, 0x29, 0x3d, 0xfc, + 0x17, 0x00, 0x00, 0xff, 0xff, 0x6c, 0xba, 0x05, 0x5d, 0x22, 0x07, 0x00, 0x00, +} diff --git a/proto-gen/api_v2/api_v2.pb.gw.go b/proto-gen/api_v2/api_v2.pb.gw.go new file mode 100644 index 00000000000..9aa65373603 --- /dev/null +++ b/proto-gen/api_v2/api_v2.pb.gw.go @@ -0,0 +1,215 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api_v2.proto + +/* +Package api_v2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package api_v2 + +import ( + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +func request_CollectorService_PostSpans_0(ctx context.Context, marshaler runtime.Marshaler, client CollectorServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PostSpansRequest + var metadata runtime.ServerMetadata + + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + } + + msg, err := client.PostSpans(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_SamplingManager_GetSamplingStrategy_0(ctx context.Context, marshaler runtime.Marshaler, client SamplingManagerClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SamplingStrategyParameters + var metadata runtime.ServerMetadata + + if req.ContentLength > 0 { + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + } + + msg, err := client.GetSamplingStrategy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +// RegisterCollectorServiceHandlerFromEndpoint is same as RegisterCollectorServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterCollectorServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterCollectorServiceHandler(ctx, mux, conn) +} + +// RegisterCollectorServiceHandler registers the http handlers for service CollectorService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterCollectorServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterCollectorServiceHandlerClient(ctx, mux, NewCollectorServiceClient(conn)) +} + +// RegisterCollectorServiceHandler registers the http handlers for service CollectorService to "mux". +// The handlers forward requests to the grpc endpoint over the given implementation of "CollectorServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "CollectorServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "CollectorServiceClient" to call the correct interceptors. +func RegisterCollectorServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client CollectorServiceClient) error { + + mux.Handle("POST", pattern_CollectorService_PostSpans_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_CollectorService_PostSpans_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_CollectorService_PostSpans_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_CollectorService_PostSpans_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "spans"}, "")) +) + +var ( + forward_CollectorService_PostSpans_0 = runtime.ForwardResponseMessage +) + +// RegisterSamplingManagerHandlerFromEndpoint is same as RegisterSamplingManagerHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterSamplingManagerHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterSamplingManagerHandler(ctx, mux, conn) +} + +// RegisterSamplingManagerHandler registers the http handlers for service SamplingManager to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterSamplingManagerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterSamplingManagerHandlerClient(ctx, mux, NewSamplingManagerClient(conn)) +} + +// RegisterSamplingManagerHandler registers the http handlers for service SamplingManager to "mux". +// The handlers forward requests to the grpc endpoint over the given implementation of "SamplingManagerClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SamplingManagerClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "SamplingManagerClient" to call the correct interceptors. +func RegisterSamplingManagerHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SamplingManagerClient) error { + + mux.Handle("POST", pattern_SamplingManager_GetSamplingStrategy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_SamplingManager_GetSamplingStrategy_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_SamplingManager_GetSamplingStrategy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_SamplingManager_GetSamplingStrategy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "samplingStrategy"}, "")) +) + +var ( + forward_SamplingManager_GetSamplingStrategy_0 = runtime.ForwardResponseMessage +) diff --git a/model/proto/openapi/model.swagger.json b/proto-gen/openapi/api_v2.swagger.json similarity index 58% rename from model/proto/openapi/model.swagger.json rename to proto-gen/openapi/api_v2.swagger.json index 36ae4f561b3..a476c054cd6 100644 --- a/model/proto/openapi/model.swagger.json +++ b/proto-gen/openapi/api_v2.swagger.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "title": "model.proto", + "title": "api_v2.proto", "version": "1.0" }, "schemes": [ @@ -15,14 +15,14 @@ "application/json" ], "paths": { - "/api/v2/spans": { + "/api/v2/samplingStrategy": { "post": { - "operationId": "PostSpans", + "operationId": "GetSamplingStrategy", "responses": { "200": { "description": "", "schema": { - "$ref": "#/definitions/modelPostSpansResponse" + "$ref": "#/definitions/api_v2SamplingStrategyResponse" } } }, @@ -32,82 +32,65 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/modelPostSpansRequest" + "$ref": "#/definitions/api_v2SamplingStrategyParameters" } } ], "tags": [ - "CollectorServiceV2" + "SamplingManager" ] } }, - "/api/v2/traces/{id}": { - "get": { - "operationId": "GetTrace", + "/api/v2/spans": { + "post": { + "operationId": "PostSpans", "responses": { "200": { "description": "", "schema": { - "$ref": "#/definitions/modelGetTraceResponse" + "$ref": "#/definitions/api_v2PostSpansResponse" } } }, "parameters": [ { - "name": "id", - "in": "path", + "name": "body", + "in": "body", "required": true, - "type": "string" + "schema": { + "$ref": "#/definitions/api_v2PostSpansRequest" + } } ], "tags": [ - "QueryServiceV2" + "CollectorService" ] } } }, "definitions": { - "TraceProcessMapping": { - "type": "object", - "properties": { - "process_id": { - "type": "string" - }, - "process": { - "$ref": "#/definitions/modelProcess" - } - } - }, - "modelBatch": { + "api_v2Batch": { "type": "object", "properties": { "spans": { "type": "array", "items": { - "$ref": "#/definitions/modelSpan" + "$ref": "#/definitions/api_v2Span" } }, "process": { - "$ref": "#/definitions/modelProcess" - } - } - }, - "modelGetTraceResponse": { - "type": "object", - "properties": { - "trace": { - "$ref": "#/definitions/modelTrace" + "$ref": "#/definitions/api_v2Process" } } }, - "modelKeyValue": { + "api_v2KeyValue": { "type": "object", "properties": { "key": { "type": "string" }, "v_type": { - "$ref": "#/definitions/modelValueType" + "$ref": "#/definitions/api_v2ValueType" }, "v_str": { "type": "string" @@ -130,7 +113,7 @@ } } }, - "modelLog": { + "api_v2Log": { "type": "object", "properties": { "timestamp": { @@ -140,29 +123,66 @@ "fields": { "type": "array", "items": { - "$ref": "#/definitions/modelKeyValue" + "$ref": "#/definitions/api_v2KeyValue" } } } }, - "modelPostSpansRequest": { + "api_v2OperationSamplingStrategy": { + "type": "object", + "properties": { + "operation": { + "type": "string" + }, + "probabilisticSampling": { + "$ref": "#/definitions/api_v2ProbabilisticSamplingStrategy" + } + } + }, + "api_v2PerOperationSamplingStrategies": { + "type": "object", + "properties": { + "defaultSamplingProbability": { + "type": "number", + "format": "double" + }, + "defaultLowerBoundTracesPerSecond": { + "type": "number", + "format": "double" + }, + "perOperationStrategies": { + "type": "array", + "items": { + "$ref": "#/definitions/api_v2OperationSamplingStrategy" + } + }, + "defaultUpperBoundTracesPerSecond": { + "type": "number", + "format": "double" + } + } + }, + "api_v2PostSpansRequest": { "type": "object", "properties": { "batch": { - "$ref": "#/definitions/modelBatch" + "$ref": "#/definitions/api_v2Batch" } } }, - "modelPostSpansResponse": { + "api_v2PostSpansResponse": { + "type": "object" + }, + "api_v2ProbabilisticSamplingStrategy": { "type": "object", "properties": { - "ok": { - "type": "boolean", - "format": "boolean" + "samplingRate": { + "type": "number", + "format": "double" } } }, - "modelProcess": { + "api_v2Process": { "type": "object", "properties": { "service_name": { @@ -171,12 +191,54 @@ "tags": { "type": "array", "items": { - "$ref": "#/definitions/modelKeyValue" + "$ref": "#/definitions/api_v2KeyValue" } } } }, - "modelSpan": { + "api_v2RateLimitingSamplingStrategy": { + "type": "object", + "properties": { + "maxTracesPerSecond": { + "type": "integer", + "format": "int32" + } + } + }, + "api_v2SamplingStrategyParameters": { + "type": "object", + "properties": { + "serviceName": { + "type": "string" + } + } + }, + "api_v2SamplingStrategyResponse": { + "type": "object", + "properties": { + "strategyType": { + "$ref": "#/definitions/api_v2SamplingStrategyType" + }, + "probabilisticSampling": { + "$ref": "#/definitions/api_v2ProbabilisticSamplingStrategy" + }, + "rateLimitingSampling": { + "$ref": "#/definitions/api_v2RateLimitingSamplingStrategy" + }, + "operationSampling": { + "$ref": "#/definitions/api_v2PerOperationSamplingStrategies" + } + } + }, + "api_v2SamplingStrategyType": { + "type": "string", + "enum": [ + "PROBABILISTIC", + "RATE_LIMITING" + ], + "default": "PROBABILISTIC" + }, + "api_v2Span": { "type": "object", "properties": { "trace_id": { @@ -193,7 +255,7 @@ "references": { "type": "array", "items": { - "$ref": "#/definitions/modelSpanRef" + "$ref": "#/definitions/api_v2SpanRef" } }, "flags": { @@ -210,17 +272,17 @@ "tags": { "type": "array", "items": { - "$ref": "#/definitions/modelKeyValue" + "$ref": "#/definitions/api_v2KeyValue" } }, "logs": { "type": "array", "items": { - "$ref": "#/definitions/modelLog" + "$ref": "#/definitions/api_v2Log" } }, "process": { - "$ref": "#/definitions/modelProcess" + "$ref": "#/definitions/api_v2Process" }, "process_id": { "type": "string" @@ -233,7 +295,7 @@ } } }, - "modelSpanRef": { + "api_v2SpanRef": { "type": "object", "properties": { "trace_id": { @@ -245,11 +307,11 @@ "format": "byte" }, "ref_type": { - "$ref": "#/definitions/modelSpanRefType" + "$ref": "#/definitions/api_v2SpanRefType" } } }, - "modelSpanRefType": { + "api_v2SpanRefType": { "type": "string", "enum": [ "CHILD_OF", @@ -257,30 +319,7 @@ ], "default": "CHILD_OF" }, - "modelTrace": { - "type": "object", - "properties": { - "spans": { - "type": "array", - "items": { - "$ref": "#/definitions/modelSpan" - } - }, - "process_map": { - "type": "array", - "items": { - "$ref": "#/definitions/TraceProcessMapping" - } - }, - "warnings": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "modelValueType": { + "api_v2ValueType": { "type": "string", "enum": [ "STRING", diff --git a/scripts/updateLicenses.sh b/scripts/updateLicenses.sh index 8cfb37eccc7..ef6449d7219 100755 --- a/scripts/updateLicenses.sh +++ b/scripts/updateLicenses.sh @@ -6,6 +6,7 @@ python scripts/updateLicense.py $(git ls-files "*\.go" | \ grep -v \ -e thrift-gen \ -e swagger-gen \ + -e proto-gen \ -e statik.go \ -e model.pb.go \ -e model.pb.gw.go \