diff --git a/NOTICE.txt b/NOTICE.txt index 1b2ec163497..3c6cd6fbce6 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2028,7 +2028,8 @@ Apache License 2.0 -------------------------------------------------------------------- Dependency: github.com/jaegertracing/jaeger -Revision: e4b97b38c4785d9a593483241f0a1d3abe007e1c +Version: v1.16.0 +Revision: 1c315785dddc80a39637c2b08b0a9bbe9ab1536c License type (autodetected): Apache-2.0 ./vendor/github.com/jaegertracing/jaeger/LICENSE: -------------------------------------------------------------------- @@ -2611,7 +2612,7 @@ Apache License 2.0 -------------------------------------------------------------------- Dependency: github.com/open-telemetry/opentelemetry-collector Version: master -Revision: e94dd19191e0ba67d5d17c4504de5e97f512eb75 +Revision: c300f13417023e53ddb643b312e6559899b54ac7 License type (autodetected): Apache-2.0 ./vendor/github.com/open-telemetry/opentelemetry-collector/LICENSE: -------------------------------------------------------------------- diff --git a/_meta/beat.yml b/_meta/beat.yml index 927fd3b830d..3b425499e61 100644 --- a/_meta/beat.yml +++ b/_meta/beat.yml @@ -400,11 +400,18 @@ apm-server: #---------------------------- APM Server - Open Telemetry Collector integration ---------------------------- #jaeger: - # Enable jaeger collector listening for traces sent from jaeger agent via gRPC. Disabled by default. - #enabled: false #grpc: - # Defines the gRPC host and port the server is listening on. Defaults to Jaeger collector default port 14250. + # Set to true to enable the Jaeger gRPC collector service. + #enabled: false + # Defines the gRPC host and port the server is listening on. + # Defaults to the standard Jaeger gRPC collector port 14250. #host: "{{ .jaeger_grpc_hostport }}" + #http: + # Set to true to enable the Jaeger HTTP collector endpoint. + #enabled: false + # Defines the HTTP host and port the server is listening on. + # Defaults to the standard Jaeger HTTP collector port 14268. + #host: "{{ .jaeger_http_hostport }}" #================================= General ================================= diff --git a/apm-server.docker.yml b/apm-server.docker.yml index 34e13453411..ef8c394518b 100644 --- a/apm-server.docker.yml +++ b/apm-server.docker.yml @@ -400,11 +400,18 @@ apm-server: #---------------------------- APM Server - Open Telemetry Collector integration ---------------------------- #jaeger: - # Enable jaeger collector listening for traces sent from jaeger agent via gRPC. Disabled by default. - #enabled: false #grpc: - # Defines the gRPC host and port the server is listening on. Defaults to Jaeger collector default port 14250. + # Set to true to enable the Jaeger gRPC collector service. + #enabled: false + # Defines the gRPC host and port the server is listening on. + # Defaults to the standard Jaeger gRPC collector port 14250. #host: "0.0.0.0:14250" + #http: + # Set to true to enable the Jaeger HTTP collector endpoint. + #enabled: false + # Defines the HTTP host and port the server is listening on. + # Defaults to the standard Jaeger HTTP collector port 14268. + #host: "0.0.0.0:14268" #================================= General ================================= diff --git a/apm-server.yml b/apm-server.yml index f1f3b0f157f..a5ad696e90e 100644 --- a/apm-server.yml +++ b/apm-server.yml @@ -400,11 +400,18 @@ apm-server: #---------------------------- APM Server - Open Telemetry Collector integration ---------------------------- #jaeger: - # Enable jaeger collector listening for traces sent from jaeger agent via gRPC. Disabled by default. - #enabled: false #grpc: - # Defines the gRPC host and port the server is listening on. Defaults to Jaeger collector default port 14250. + # Set to true to enable the Jaeger gRPC collector service. + #enabled: false + # Defines the gRPC host and port the server is listening on. + # Defaults to the standard Jaeger gRPC collector port 14250. #host: "localhost:14250" + #http: + # Set to true to enable the Jaeger HTTP collector endpoint. + #enabled: false + # Defines the HTTP host and port the server is listening on. + # Defaults to the standard Jaeger HTTP collector port 14268. + #host: "localhost:14268" #================================= General ================================= diff --git a/beater/api/jaeger/grpc.go b/beater/api/jaeger/grpc.go deleted file mode 100644 index fb511cdf338..00000000000 --- a/beater/api/jaeger/grpc.go +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you 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 ( - "context" - - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - trjaeger "github.com/open-telemetry/opentelemetry-collector/translator/trace/jaeger" - - "github.com/elastic/beats/libbeat/monitoring" - - "github.com/elastic/apm-server/beater/request" - "github.com/elastic/apm-server/processor/otel" -) - -const ( - collectorType = "jaeger" -) - -var ( - gRPCRegistry = monitoring.Default.NewRegistry("apm-server.jaeger.grpc", monitoring.PublishExpvar) - monitoringKeys = []request.ResultID{request.IDRequestCount, request.IDResponseCount, request.IDResponseErrorsCount, - request.IDResponseValidCount, request.IDEventReceivedCount, request.IDEventDroppedCount} - monitoringMap = request.MonitoringMapForRegistry(gRPCRegistry, monitoringKeys) -) - -// GRPCCollector implements Jaeger api_v2 protocol for receiving tracing data -type GRPCCollector struct { - consumer *otel.Consumer -} - -// NewGRPCCollector returns new instance of GRPCCollector -func NewGRPCCollector(consumer *otel.Consumer) GRPCCollector { - return GRPCCollector{consumer} -} - -// PostSpans implements the api_v2/collector.proto. It converts spans received via Jaeger Proto batch to open-telemetry -// TraceData and passes them on to the internal Consumer taking care of converting into Elastic APM format. -// The implementation of the protobuf contract is based on the open-telemetry implementation at -// https://github.com/open-telemetry/opentelemetry-collector/tree/master/receiver/jaegerreceiver -func (c GRPCCollector) PostSpans(ctx context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { - inc(request.IDRequestCount) - - resp, err := c.postSpans(ctx, r) - - inc(request.IDResponseCount) - if err != nil { - inc(request.IDResponseErrorsCount) - } else { - inc(request.IDResponseValidCount) - } - return resp, err -} - -func (c GRPCCollector) postSpans(ctx context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { - spansCount := len(r.Batch.Spans) - add(request.IDEventReceivedCount, int64(spansCount)) - traceData, err := trjaeger.ProtoBatchToOCProto(r.Batch) - if err != nil { - add(request.IDEventDroppedCount, int64(spansCount)) - return nil, err - } - traceData.SourceFormat = collectorType - if err = c.consumer.ConsumeTraceData(ctx, traceData); err != nil { - return nil, err - } - return &api_v2.PostSpansResponse{}, nil -} - -func inc(id request.ResultID) { - if counter, ok := monitoringMap[id]; ok { - counter.Inc() - } -} - -func add(id request.ResultID, n int64) { - if counter, ok := monitoringMap[id]; ok { - counter.Add(n) - } -} diff --git a/beater/api/jaeger/grpc_approval_test.go b/beater/api/jaeger/grpc_approval_test.go deleted file mode 100644 index a28b29b6319..00000000000 --- a/beater/api/jaeger/grpc_approval_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you 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 ( - "context" - "encoding/json" - "io/ioutil" - "path/filepath" - "testing" - - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - "github.com/stretchr/testify/require" - - "github.com/elastic/beats/libbeat/beat" - - "github.com/elastic/apm-server/publish" - "github.com/elastic/apm-server/tests/approvals" -) - -// testdata are created via a modified version of the hotrod example -// https://github.com/jaegertracing/jaeger/tree/master/examples/hotrod -func TestGRPCSpansToEvents(t *testing.T) { - for _, name := range []string{ - "batch_1", "batch_2", - } { - t.Run(name, func(t *testing.T) { - tc := testCollector{} - f := filepath.Join("testdata", name) - data, err := ioutil.ReadFile(f + ".json") - require.NoError(t, err) - var request api_v2.PostSpansRequest - require.NoError(t, json.Unmarshal(data, &request)) - tc.request = &request - var events []beat.Event - tc.reporter = func(ctx context.Context, req publish.PendingReq) error { - for _, transformable := range req.Transformables { - events = append(events, transformable.Transform(req.Tcontext)...) - } - require.NoError(t, approvals.ApproveEvents(events, f, "")) - return nil - } - tc.setup(t) - - _, err = tc.collector.PostSpans(context.Background(), tc.request) - require.NoError(t, err) - }) - } -} diff --git a/beater/api/jaeger/grpc_test.go b/beater/api/jaeger/grpc_test.go deleted file mode 100644 index ea8b7825ab0..00000000000 --- a/beater/api/jaeger/grpc_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you 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 ( - "context" - "errors" - "testing" - - v1 "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - "github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata" - "github.com/open-telemetry/opentelemetry-collector/translator/trace/jaeger" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/elastic/apm-server/beater/beatertest" - "github.com/elastic/apm-server/beater/request" - "github.com/elastic/apm-server/processor/otel" - "github.com/elastic/apm-server/publish" -) - -func TestGRPCCollector_PostSpans(t *testing.T) { - for name, tc := range map[string]testCollector{ - "empty request": { - request: &api_v2.PostSpansRequest{}, - monitoringInt: map[request.ResultID]int64{request.IDRequestCount: 1, request.IDResponseCount: 1, - request.IDResponseValidCount: 1}}, - "successful request": { - monitoringInt: map[request.ResultID]int64{request.IDRequestCount: 1, request.IDResponseCount: 1, - request.IDResponseValidCount: 1, request.IDEventReceivedCount: 2}}, - "failing request": { - reporter: func(ctx context.Context, pub publish.PendingReq) error { - return errors.New("consumer failed") - }, - expectedErr: errors.New("consumer failed"), - monitoringInt: map[request.ResultID]int64{request.IDRequestCount: 1, request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, request.IDEventReceivedCount: 2}}, - } { - t.Run(name, func(t *testing.T) { - tc.setup(t) - - resp, err := tc.collector.PostSpans(context.Background(), tc.request) - if tc.expectedErr != nil { - require.Nil(t, resp) - require.Error(t, err) - assert.Equal(t, tc.expectedErr, err) - } else { - require.NotNil(t, resp) - require.NoError(t, err) - } - assertMonitoring(t, tc.monitoringInt) - }) - } -} - -type testCollector struct { - request *api_v2.PostSpansRequest - reporter func(ctx context.Context, pub publish.PendingReq) error - collector GRPCCollector - - monitoringInt map[request.ResultID]int64 - expectedErr error -} - -func (tc *testCollector) setup(t *testing.T) { - beatertest.ClearRegistry(monitoringMap) - if tc.request == nil { - td := consumerdata.TraceData{Spans: []*v1.Span{ - {TraceId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - SpanId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, - {TraceId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - SpanId: []byte{0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}}} - batch, err := jaeger.OCProtoToJaegerProto(td) - require.NoError(t, err) - require.NotNil(t, batch) - tc.request = &api_v2.PostSpansRequest{Batch: *batch} - } - - if tc.reporter == nil { - tc.reporter = func(ctx context.Context, pub publish.PendingReq) error { return nil } - } - tc.collector = GRPCCollector{&otel.Consumer{Reporter: tc.reporter}} -} - -func assertMonitoring(t *testing.T, m map[request.ResultID]int64) { - for _, k := range monitoringKeys { - if val, ok := m[k]; ok { - assert.Equal(t, val, monitoringMap[k].Get()) - } else { - assert.Zero(t, monitoringMap[k].Get()) - } - } -} diff --git a/beater/api/mux.go b/beater/api/mux.go index 1c42ed933e3..21e32b65d0a 100644 --- a/beater/api/mux.go +++ b/beater/api/mux.go @@ -79,7 +79,7 @@ type route struct { // NewMux registers apm handlers to paths building up the APM Server API. func NewMux(beaterConfig *config.Config, report publish.Reporter) (*http.ServeMux, error) { - pool := newContextPool() + pool := request.NewContextPool() mux := http.NewServeMux() logger := logp.NewLogger(logs.Handler) @@ -112,7 +112,7 @@ func NewMux(beaterConfig *config.Config, report publish.Reporter) (*http.ServeMu return nil, err } logger.Infof("Path %s added to request handler", route.path) - mux.Handle(route.path, pool.handler(h)) + mux.Handle(route.path, pool.HTTPHandler(h)) } if beaterConfig.Expvar.IsEnabled() { diff --git a/beater/config/config_test.go b/beater/config/config_test.go index d1acf88f628..2d0fa9dc387 100644 --- a/beater/config/config_test.go +++ b/beater/config/config_test.go @@ -96,13 +96,15 @@ func Test_UnpackConfig(t *testing.T) { }, "kibana": map[string]interface{}{"enabled": "true"}, "agent.config.cache.expiration": "2m", + "jaeger.grpc.enabled": true, + "jaeger.grpc.host": "localhost:12345", + "jaeger.http.enabled": true, + "jaeger.http.host": "localhost:6789", "api_key": map[string]interface{}{ "enabled": true, "limit": 200, "elasticsearch.hosts": []string{"localhost:9201", "localhost:9202"}, }, - "jaeger.enabled": true, - "jaeger.grpc.host": "localhost:12345", }, outCfg: &Config{ Host: "localhost:3000", @@ -158,9 +160,9 @@ func Test_UnpackConfig(t *testing.T) { LimitMin: 200, ESConfig: &elasticsearch.Config{Hosts: elasticsearch.Hosts{"localhost:9201", "localhost:9202"}}}, JaegerConfig: JaegerConfig{ - Enabled: true, - GRPC: GRPCConfig{ - Host: "localhost:12345", + GRPC: JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:12345", TLS: func() *tls.Config { tlsServerConfig, err := tlscommon.LoadTLSServerConfig(&tlscommon.ServerConfig{ Enabled: &truthy, @@ -173,6 +175,10 @@ func Test_UnpackConfig(t *testing.T) { return tlsServerConfig.BuildModuleConfig("localhost:12345") }(), }, + HTTP: JaegerHTTPConfig{ + Enabled: true, + Host: "localhost:6789", + }, }, }, }, @@ -203,8 +209,9 @@ func Test_UnpackConfig(t *testing.T) { }, }, }, - "api_key.enabled": true, - "jaeger.enabled": true, + "jaeger.enabled": true, + "jaeger.grpc.enabled": true, + "api_key.enabled": true, }, outCfg: &Config{ Host: "localhost:3000", @@ -254,9 +261,9 @@ func Test_UnpackConfig(t *testing.T) { Pipeline: defaultAPMPipeline, APIKeyConfig: &APIKeyConfig{Enabled: true, LimitMin: 100, ESConfig: elasticsearch.DefaultConfig()}, JaegerConfig: JaegerConfig{ - Enabled: true, - GRPC: GRPCConfig{ - Host: "localhost:14250", + GRPC: JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:14250", TLS: func() *tls.Config { tlsServerConfig, err := tlscommon.LoadTLSServerConfig(&tlscommon.ServerConfig{ Enabled: &truthy, @@ -266,6 +273,10 @@ func Test_UnpackConfig(t *testing.T) { return tlsServerConfig.BuildModuleConfig("localhost:14250") }(), }, + HTTP: JaegerHTTPConfig{ + Enabled: false, + Host: "localhost:14268", + }, }, }, }, diff --git a/beater/config/jaeger.go b/beater/config/jaeger.go index f0799fa71d9..4a2a3d8e7f9 100644 --- a/beater/config/jaeger.go +++ b/beater/config/jaeger.go @@ -25,38 +25,51 @@ import ( const ( defaultJaegerGRPCHost = "localhost:14250" + defaultJaegerHTTPHost = "localhost:14268" ) -// JaegerConfig holds configuration for jaeger collector +// JaegerConfig holds configuration for Jaeger span collection. type JaegerConfig struct { - Enabled bool `config:"enabled"` - GRPC GRPCConfig `config:"grpc"` + GRPC JaegerGRPCConfig `config:"grpc"` + HTTP JaegerHTTPConfig `config:"http"` } -// GRPCConfig bundles information around a grpc server -type GRPCConfig struct { - Host string `config:"host"` - TLS *tls.Config `config:"-"` +// JaegerGRPCConfig holds configuration for the Jaeger gRPC server. +type JaegerGRPCConfig struct { + Enabled bool `config:"enabled"` + Host string `config:"host"` + TLS *tls.Config `config:"-"` +} + +// JaegerHTTPConfig holds configuration for the Jaeger HTTP server. +type JaegerHTTPConfig struct { + Enabled bool `config:"enabled"` + Host string `config:"host"` } func (c *JaegerConfig) setup(cfg *Config) error { - if !c.Enabled || cfg.TLS == nil || !cfg.TLS.IsEnabled() { + if cfg.TLS == nil || !cfg.TLS.IsEnabled() { return nil } - - tlsServerConfig, err := tlscommon.LoadTLSServerConfig(cfg.TLS) - if err != nil { - return err + if c.GRPC.Enabled { + tlsServerConfig, err := tlscommon.LoadTLSServerConfig(cfg.TLS) + if err != nil { + return err + } + c.GRPC.TLS = tlsServerConfig.BuildModuleConfig(c.GRPC.Host) } - c.GRPC.TLS = tlsServerConfig.BuildModuleConfig(c.GRPC.Host) return nil } func defaultJaeger() JaegerConfig { return JaegerConfig{ - Enabled: false, - GRPC: GRPCConfig{ - Host: defaultJaegerGRPCHost, + GRPC: JaegerGRPCConfig{ + Enabled: false, + Host: defaultJaegerGRPCHost, + }, + HTTP: JaegerHTTPConfig{ + Enabled: false, + Host: defaultJaegerHTTPHost, }, } } diff --git a/beater/config/jaeger_test.go b/beater/config/jaeger_test.go index 48587684951..5c26060ece0 100644 --- a/beater/config/jaeger_test.go +++ b/beater/config/jaeger_test.go @@ -25,9 +25,13 @@ import ( func TestJaeger_default(t *testing.T) { expected := JaegerConfig{ - Enabled: false, - GRPC: GRPCConfig{ - Host: "localhost:14250", + GRPC: JaegerGRPCConfig{ + Enabled: false, + Host: "localhost:14250", + }, + HTTP: JaegerHTTPConfig{ + Enabled: false, + Host: "localhost:14268", }, } assert.Equal(t, expected, defaultJaeger()) diff --git a/beater/jaeger/common.go b/beater/jaeger/common.go new file mode 100644 index 00000000000..f527708822e --- /dev/null +++ b/beater/jaeger/common.go @@ -0,0 +1,71 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 ( + "context" + + "github.com/elastic/apm-server/beater/request" + "github.com/elastic/beats/libbeat/monitoring" + + "github.com/jaegertracing/jaeger/model" + "github.com/open-telemetry/opentelemetry-collector/consumer" + trjaeger "github.com/open-telemetry/opentelemetry-collector/translator/trace/jaeger" +) + +const ( + collectorType = "jaeger" +) + +var ( + monitoringKeys = []request.ResultID{ + request.IDRequestCount, request.IDResponseCount, request.IDResponseErrorsCount, request.IDResponseValidCount, + request.IDEventReceivedCount, request.IDEventDroppedCount, + } +) + +type monitoringMap map[request.ResultID]*monitoring.Int + +func (m monitoringMap) inc(id request.ResultID) { + if counter, ok := m[id]; ok { + counter.Inc() + } +} + +func (m monitoringMap) add(id request.ResultID, n int64) { + if counter, ok := m[id]; ok { + counter.Add(n) + } +} + +func consumeBatch( + ctx context.Context, + batch model.Batch, + consumer consumer.TraceConsumer, + requestMetrics monitoringMap, +) error { + spanCount := int64(len(batch.Spans)) + requestMetrics.add(request.IDEventReceivedCount, spanCount) + traceData, err := trjaeger.ProtoBatchToOCProto(batch) + if err != nil { + requestMetrics.add(request.IDEventDroppedCount, spanCount) + return err + } + traceData.SourceFormat = collectorType + return consumer.ConsumeTraceData(ctx, traceData) +} diff --git a/beater/jaeger/grpc.go b/beater/jaeger/grpc.go index fed372a58fd..ebf472a0704 100644 --- a/beater/jaeger/grpc.go +++ b/beater/jaeger/grpc.go @@ -18,79 +18,38 @@ package jaeger import ( - "net" + "context" "github.com/jaegertracing/jaeger/proto-gen/api_v2" - "github.com/pkg/errors" - "go.elastic.co/apm" - "go.elastic.co/apm/module/apmgrpc" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" + "github.com/open-telemetry/opentelemetry-collector/consumer" - "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/monitoring" - "github.com/elastic/apm-server/beater/api/jaeger" - "github.com/elastic/apm-server/beater/config" - processor "github.com/elastic/apm-server/processor/otel" - "github.com/elastic/apm-server/publish" - "github.com/elastic/apm-server/transform" + "github.com/elastic/apm-server/beater/request" ) -const ( - networkTCP = "tcp" +var ( + gRPCRegistry = monitoring.Default.NewRegistry("apm-server.jaeger.grpc", monitoring.PublishExpvar) + gRPCMonitoringMap monitoringMap = request.MonitoringMapForRegistry(gRPCRegistry, monitoringKeys) ) -// GRPCServer allows to start and stop a Jaeger gRPC Server with a Jaeger Collector -type GRPCServer struct { - logger *logp.Logger - grpcServer *grpc.Server - host string - collector jaeger.GRPCCollector +// grpcCollector implements Jaeger api_v2 protocol for receiving tracing data +type grpcCollector struct { + consumer consumer.TraceConsumer } -// NewGRPCServer creates instance of Jaeger GRPCServer -func NewGRPCServer(logger *logp.Logger, cfg *config.Config, tracer *apm.Tracer, reporter publish.Reporter) (*GRPCServer, error) { - if !cfg.JaegerConfig.Enabled { - return nil, nil - } - - grpcOptions := []grpc.ServerOption{grpc.UnaryInterceptor(apmgrpc.NewUnaryServerInterceptor( - apmgrpc.WithRecovery(), - apmgrpc.WithTracer(tracer)))} - if cfg.JaegerConfig.GRPC.TLS != nil { - creds := credentials.NewTLS(cfg.JaegerConfig.GRPC.TLS) - grpcOptions = append(grpcOptions, grpc.Creds(creds)) - } - grpcServer := grpc.NewServer(grpcOptions...) - consumer := &processor.Consumer{ - Reporter: reporter, - TransformConfig: transform.Config{}, - } - - return &GRPCServer{ - logger: logger, - collector: jaeger.NewGRPCCollector(consumer), - grpcServer: grpcServer, - host: cfg.JaegerConfig.GRPC.Host, - }, nil -} - -// Start gRPC server to listen for incoming Jaeger trace requests. -//TODO(simi) to add support for sampling: api_v2.RegisterSamplingManagerServer -func (jc *GRPCServer) Start() error { - jc.logger.Infof("Starting Jaeger collector listening on: %s", jc.host) - - api_v2.RegisterCollectorServiceServer(jc.grpcServer, jc.collector) - - listener, err := net.Listen(networkTCP, jc.host) +// PostSpans implements the api_v2/collector.proto. It converts spans received via Jaeger Proto batch to open-telemetry +// TraceData and passes them on to the internal Consumer taking care of converting into Elastic APM format. +// The implementation of the protobuf contract is based on the open-telemetry implementation at +// https://github.com/open-telemetry/opentelemetry-collector/tree/master/receiver/jaegerreceiver +func (c grpcCollector) PostSpans(ctx context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { + gRPCMonitoringMap.inc(request.IDRequestCount) + err := consumeBatch(ctx, r.Batch, c.consumer, gRPCMonitoringMap) + gRPCMonitoringMap.inc(request.IDResponseCount) if err != nil { - return errors.Wrapf(err, "error starting Jaeger collector listening on: %s", jc.host) + gRPCMonitoringMap.inc(request.IDResponseErrorsCount) + return nil, err } - return jc.grpcServer.Serve(listener) -} - -// Stop gRPC server gracefully. -func (jc *GRPCServer) Stop() { - jc.logger.Infof("Stopping Jaeger collector listening on: %s", jc.host) - jc.grpcServer.GracefulStop() + gRPCMonitoringMap.inc(request.IDResponseValidCount) + return &api_v2.PostSpansResponse{}, nil } diff --git a/beater/jaeger/grpc_test.go b/beater/jaeger/grpc_test.go index 451dfd96bf9..817b685ca83 100644 --- a/beater/jaeger/grpc_test.go +++ b/beater/jaeger/grpc_test.go @@ -19,160 +19,108 @@ package jaeger import ( "context" - "path" + "errors" "testing" - "time" v1 "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" - jaegermodel "github.com/jaegertracing/jaeger/model" "github.com/jaegertracing/jaeger/proto-gen/api_v2" "github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata" - oteljaeger "github.com/open-telemetry/opentelemetry-collector/translator/trace/jaeger" - "github.com/pkg/errors" + "github.com/open-telemetry/opentelemetry-collector/translator/trace/jaeger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.elastic.co/apm" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "github.com/elastic/beats/libbeat/common/transport/tlscommon" - "github.com/elastic/beats/libbeat/logp" - - "github.com/elastic/apm-server/beater/config" - "github.com/elastic/apm-server/publish" - "github.com/elastic/apm-server/transform" + "github.com/elastic/apm-server/beater/beatertest" + "github.com/elastic/apm-server/beater/request" ) -func TestGRPCServerIntegration(t *testing.T) { - enabledTrue, enabledFalse := true, false - for name, tc := range map[string]testcaseJaeger{ - "default config": {cfg: config.DefaultConfig("9.9.9")}, - "with jaeger": { - cfg: func() *config.Config { - cfg := config.DefaultConfig("8.0.0") - cfg.JaegerConfig.Enabled = true - return cfg - }()}, - "with jaeger TLS disabled": { - cfg: &config.Config{ - TLS: &tlscommon.ServerConfig{ - Enabled: &enabledFalse, - Certificate: tlscommon.CertificateConfig{ - Certificate: path.Join("..", "testdata", "tls", "certificate.pem"), - Key: path.Join("..", "testdata", "tls", "key.pem")}, - }, - JaegerConfig: config.JaegerConfig{ - Enabled: true, - GRPC: config.GRPCConfig{ - Host: "localhost:4444", - }}, - }}, - "with jaeger with TLS": { - cfg: &config.Config{ - TLS: &tlscommon.ServerConfig{ - Enabled: &enabledTrue, - Certificate: tlscommon.CertificateConfig{ - Certificate: path.Join("..", "testdata", "tls", "certificate.pem"), - Key: path.Join("..", "testdata", "tls", "key.pem")}, - }, - JaegerConfig: config.JaegerConfig{ - Enabled: true, - GRPC: config.GRPCConfig{ - Host: "localhost:4444", - }}, - }}, +func TestGRPCCollector_PostSpans(t *testing.T) { + for name, tc := range map[string]testGRPCCollector{ + "empty request": { + request: &api_v2.PostSpansRequest{}, + monitoringInt: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseValidCount: 1, + }, + }, + "successful request": { + monitoringInt: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseValidCount: 1, + request.IDEventReceivedCount: 2, + }, + }, + "failing request": { + consumerErr: errors.New("consumer failed"), + monitoringInt: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseErrorsCount: 1, + request.IDEventReceivedCount: 2, + }, + }, } { t.Run(name, func(t *testing.T) { tc.setup(t) - if !tc.cfg.JaegerConfig.Enabled { - assert.Nil(t, tc.server) + resp, err := tc.collector.PostSpans(context.Background(), tc.request) + if tc.consumerErr != nil { + require.Nil(t, resp) + require.Error(t, err) + assert.Equal(t, tc.consumerErr, err) } else { - require.NotNil(t, tc.server) - require.NotNil(t, tc.client) - - // start - go func() { - err := tc.server.Start() - require.NoError(t, err) - }() - - err := tc.sendSpans(time.Second) + require.NotNil(t, resp) require.NoError(t, err) - assert.Equal(t, 1, len(tc.transformed)) - - // stop grpc server - tc.server.Stop() - _, err = tc.client.PostSpans(context.Background(), &api_v2.PostSpansRequest{Batch: *tc.batch}) - require.Error(t, err) } + assertMonitoring(t, tc.monitoringInt, gRPCMonitoringMap) }) } - } -type testcaseJaeger struct { - cfg *config.Config - reporter func(ctx context.Context, pub publish.PendingReq) error - transformed []transform.Transformable - server *GRPCServer - client api_v2.CollectorServiceClient - batch *jaegermodel.Batch +type testGRPCCollector struct { + request *api_v2.PostSpansRequest + consumerErr error + collector grpcCollector + + monitoringInt map[request.ResultID]int64 } -func (tc *testcaseJaeger) setup(t *testing.T) { - if tc.cfg == nil { - tc.cfg = config.DefaultConfig("9.9.9") +func (tc *testGRPCCollector) setup(t *testing.T) { + beatertest.ClearRegistry(gRPCMonitoringMap) + if tc.request == nil { + td := consumerdata.TraceData{Spans: []*v1.Span{ + {TraceId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + SpanId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, + {TraceId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + SpanId: []byte{0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}}} + batch, err := jaeger.OCProtoToJaegerProto(td) + require.NoError(t, err) + require.NotNil(t, batch) + tc.request = &api_v2.PostSpansRequest{Batch: *batch} } - // build grpc receiver - tc.reporter = func(ctx context.Context, pub publish.PendingReq) error { - tc.transformed = append(tc.transformed, pub.Transformables...) - return nil - } - var err error - tc.server, err = NewGRPCServer(logp.NewLogger("jaeger"), tc.cfg, apm.DefaultTracer, tc.reporter) - require.NoError(t, err) + tc.collector = grpcCollector{traceConsumerFunc(func(ctx context.Context, td consumerdata.TraceData) error { + return tc.consumerErr + })} +} - if !tc.cfg.JaegerConfig.Enabled { - return +func assertMonitoring(t *testing.T, expected map[request.ResultID]int64, actual monitoringMap) { + for _, k := range monitoringKeys { + if val, ok := expected[k]; ok { + assert.Equalf(t, val, actual[k].Get(), "%s mismatch", k) + } else { + assert.Zerof(t, actual[k].Get(), "%s mismatch", k) + } } +} - // build grpc client and batch for request - var client *grpc.ClientConn - if tc.cfg.JaegerConfig.GRPC.TLS != nil { - client, err = grpc.Dial(tc.cfg.JaegerConfig.GRPC.Host, - grpc.WithTransportCredentials(credentials.NewTLS(tc.cfg.JaegerConfig.GRPC.TLS))) - require.NoError(t, err) - - } else { - client, err = grpc.Dial(tc.cfg.JaegerConfig.GRPC.Host, grpc.WithInsecure()) - require.NoError(t, err) - } - tc.client = api_v2.NewCollectorServiceClient(client) +type traceConsumerFunc func(ctx context.Context, td consumerdata.TraceData) error - // send data via grpc client - td := consumerdata.TraceData{Spans: []*v1.Span{{ - TraceId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - SpanId: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}}} - tc.batch, err = oteljaeger.OCProtoToJaegerProto(td) - require.NoError(t, err) - require.NotNil(t, tc.batch) +func (f traceConsumerFunc) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error { + return f(ctx, td) } -func (tc *testcaseJaeger) sendSpans(timeout time.Duration) error { - start := time.Now() - var err error - for { - _, err = tc.client.PostSpans(context.Background(), &api_v2.PostSpansRequest{Batch: *tc.batch}) - if err == nil { - break - } - if time.Since(start) > timeout { - err = errors.New("timeout") - break - } - time.Sleep(time.Second / 50) - } - return err +func nopConsumer() traceConsumerFunc { + return func(context.Context, consumerdata.TraceData) error { return nil } } diff --git a/beater/jaeger/http.go b/beater/jaeger/http.go new file mode 100644 index 00000000000..bf14a664374 --- /dev/null +++ b/beater/jaeger/http.go @@ -0,0 +1,128 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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" + "io/ioutil" + "mime" + "net/http" + + "github.com/apache/thrift/lib/go/thrift" + "github.com/jaegertracing/jaeger/model" + converter "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" + "github.com/jaegertracing/jaeger/thrift-gen/jaeger" + "github.com/open-telemetry/opentelemetry-collector/consumer" + + "github.com/elastic/beats/libbeat/monitoring" + + "github.com/elastic/apm-server/beater/middleware" + "github.com/elastic/apm-server/beater/request" +) + +const ( + apiTracesRoute = "/api/traces" +) + +var ( + httpRegistry = monitoring.Default.NewRegistry("apm-server.jaeger.http", monitoring.PublishExpvar) + httpMonitoringMap = request.MonitoringMapForRegistry(httpRegistry, monitoringKeys) +) + +// newHTTPMux returns a new http.ServeMux which accepts Thrift-encoded spans. +func newHTTPMux(consumer consumer.TraceConsumer) (*http.ServeMux, error) { + handler, err := middleware.Wrap( + newHTTPHandler(consumer), + middleware.LogMiddleware(), + middleware.RecoverPanicMiddleware(), + middleware.MonitoringMiddleware(httpMonitoringMap), + middleware.RequestTimeMiddleware(), + ) + if err != nil { + return nil, err + } + + pool := request.NewContextPool() + mux := http.NewServeMux() + mux.Handle(apiTracesRoute, pool.HTTPHandler(handler)) + return mux, nil +} + +type httpHandler struct { + consumer consumer.TraceConsumer +} + +func newHTTPHandler(consumer consumer.TraceConsumer) request.Handler { + h := &httpHandler{consumer} + return h.handle +} + +func (h *httpHandler) handle(c *request.Context) { + switch c.Request.URL.Path { + case apiTracesRoute: + h.handleTraces(c) + default: + c.Result.SetWithError(request.IDResponseErrorsNotFound, errors.New("unknown route")) + } + c.Write() +} + +func (h *httpHandler) handleTraces(c *request.Context) { + if c.Request.Method != http.MethodPost { + c.Result.SetWithError( + request.IDResponseErrorsMethodNotAllowed, + errors.New("only POST requests are allowed"), + ) + return + } + + contentType, _, err := mime.ParseMediaType(c.Request.Header.Get("Content-Type")) + if err != nil { + c.Result.SetWithError(request.IDResponseErrorsValidate, err) + return + } + switch contentType { + case "application/x-thrift", "application/vnd.apache.thrift.binary": + default: + c.Result.SetWithError( + request.IDResponseErrorsValidate, + fmt.Errorf("unsupported content-type %q", contentType), + ) + return + } + + var batch jaeger.Batch + transport := thrift.NewStreamTransport(c.Request.Body, ioutil.Discard) + protocol := thrift.NewTBinaryProtocolFactoryDefault().GetProtocol(transport) + if err := batch.Read(protocol); err != nil { + c.Result.SetWithError(request.IDResponseErrorsDecode, err) + return + } + + modelBatch := model.Batch{ + Process: converter.ToDomainProcess(batch.Process), + Spans: converter.ToDomain(batch.Spans, batch.Process), + } + if err := consumeBatch(c.Request.Context(), modelBatch, h.consumer, httpMonitoringMap); err != nil { + // TODO(axw) map errors from the consumer back to appropriate error codes? + c.Result.SetWithError(request.IDResponseErrorsInternal, err) + return + } + c.Result.SetDefault(request.IDResponseValidAccepted) +} diff --git a/beater/jaeger/http_test.go b/beater/jaeger/http_test.go new file mode 100644 index 00000000000..eec1b7ed6a0 --- /dev/null +++ b/beater/jaeger/http_test.go @@ -0,0 +1,179 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 ( + "bytes" + "context" + "errors" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/apache/thrift/lib/go/thrift" + jaegerthrift "github.com/jaegertracing/jaeger/thrift-gen/jaeger" + "github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/elastic/apm-server/beater/beatertest" + "github.com/elastic/apm-server/beater/request" +) + +type httpMuxTest struct { + spans []*jaegerthrift.Span + consumerError error + + expectedStatusCode int + expectedMonitoringMap map[request.ResultID]int64 +} + +func TestHTTPMux(t *testing.T) { + for name, test := range map[string]httpMuxTest{ + "empty batch": { + expectedStatusCode: http.StatusAccepted, + expectedMonitoringMap: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseValidCount: 1, + request.IDEventReceivedCount: 0, + }, + }, + "non-empty batch": { + spans: []*jaegerthrift.Span{{}, {}}, + expectedStatusCode: http.StatusAccepted, + expectedMonitoringMap: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseValidCount: 1, + request.IDEventReceivedCount: 2, + }, + }, + "consumer fails": { + spans: []*jaegerthrift.Span{{}, {}}, + consumerError: errors.New("oh noes"), + expectedStatusCode: http.StatusInternalServerError, + expectedMonitoringMap: map[request.ResultID]int64{ + request.IDRequestCount: 1, + request.IDResponseCount: 1, + request.IDResponseErrorsCount: 1, + request.IDEventReceivedCount: 2, + }, + }, + } { + t.Run(name, func(t *testing.T) { + testHTTPMux(t, test) + }) + } +} + +func testHTTPMux(t *testing.T, test httpMuxTest) { + t.Helper() + beatertest.ClearRegistry(httpMonitoringMap) + + var consumed bool + mux, err := newHTTPMux(traceConsumerFunc(func(ctx context.Context, td consumerdata.TraceData) error { + consumed = true + return test.consumerError + })) + require.NoError(t, err) + + body := encodeThriftSpans(test.spans...) + req := httptest.NewRequest("POST", "/api/traces", body) + req.Header.Set("Content-Type", "application/x-thrift") + + recorder := httptest.NewRecorder() + mux.ServeHTTP(recorder, req) + assert.Equal(t, test.expectedStatusCode, recorder.Code) + assert.True(t, consumed) + assertMonitoring(t, test.expectedMonitoringMap, httpMonitoringMap) +} + +func TestHTTPHandler_UnknownRoute(t *testing.T) { + c, recorder := newRequestContext("POST", "/foo", nil) + newHTTPHandler(nopConsumer())(c) + assert.Equal(t, http.StatusNotFound, recorder.Code) + assert.Equal(t, `{"error":"404 page not found: unknown route"}`+"\n", recorder.Body.String()) +} + +func TestHTTPMux_MethodNotAllowed(t *testing.T) { + c, recorder := newRequestContext("GET", "/api/traces", nil) + newHTTPHandler(nopConsumer())(c) + assert.Equal(t, http.StatusMethodNotAllowed, recorder.Code) + assert.Equal(t, `{"error":"method not supported: only POST requests are allowed"}`+"\n", recorder.Body.String()) +} + +func TestHTTPMux_InvalidContentType(t *testing.T) { + c, recorder := newRequestContext("POST", "/api/traces", nil) + c.Request.Header.Set("Content-Type", "application/json") + newHTTPHandler(nopConsumer())(c) + assert.Equal(t, http.StatusBadRequest, recorder.Code) + assert.Equal(t, `{"error":"data validation error: unsupported content-type \"application/json\""}`+"\n", recorder.Body.String()) +} + +func TestHTTPMux_ValidContentTypes(t *testing.T) { + for _, contentType := range []string{"application/x-thrift", "application/vnd.apache.thrift.binary"} { + body := encodeThriftSpans(&jaegerthrift.Span{}) + c, recorder := newRequestContext("POST", "/api/traces", body) + c.Request.Header.Set("Content-Type", contentType) + newHTTPHandler(nopConsumer())(c) + assert.Equal(t, http.StatusAccepted, recorder.Code) + assert.Equal(t, ``, recorder.Body.String()) + } +} + +func TestHTTPMux_InvalidBody(t *testing.T) { + c, recorder := newRequestContext("POST", "/api/traces", strings.NewReader(`¯\_(ツ)_/¯`)) + newHTTPHandler(nopConsumer())(c) + assert.Equal(t, http.StatusBadRequest, recorder.Code) + assert.Regexp(t, `{"error":"data decoding error: .*"}`+"\n", recorder.Body.String()) +} + +func TestHTTPMux_ConsumerError(t *testing.T) { + var consumer traceConsumerFunc = func(ctx context.Context, td consumerdata.TraceData) error { + return errors.New("bauch tut weh") + } + c, recorder := newRequestContext("POST", "/api/traces", encodeThriftSpans(&jaegerthrift.Span{})) + newHTTPHandler(consumer)(c) + assert.Equal(t, http.StatusInternalServerError, recorder.Code) + assert.Regexp(t, `{"error":"internal error: bauch tut weh"}`+"\n", recorder.Body.String()) +} + +func newRequestContext(method, path string, body io.Reader) (*request.Context, *httptest.ResponseRecorder) { + rr := httptest.NewRecorder() + c := &request.Context{} + req := httptest.NewRequest(method, path, body) + req.Header.Set("Content-Type", "application/x-thrift") + c.Reset(rr, req) + return c, rr +} + +func encodeThriftSpans(spans ...*jaegerthrift.Span) io.Reader { + batch := &jaegerthrift.Batch{Process: &jaegerthrift.Process{ServiceName: "whatever"}, Spans: spans} + return encodeThriftBatch(batch) +} + +func encodeThriftBatch(batch *jaegerthrift.Batch) io.Reader { + transport := thrift.NewTMemoryBuffer() + if err := batch.Write(thrift.NewTBinaryProtocolTransport(transport)); err != nil { + panic(err) + } + return bytes.NewReader(transport.Buffer.Bytes()) +} diff --git a/beater/jaeger/server.go b/beater/jaeger/server.go new file mode 100644 index 00000000000..2b8e659e2be --- /dev/null +++ b/beater/jaeger/server.go @@ -0,0 +1,149 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 ( + "context" + "net" + "net/http" + + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + "go.elastic.co/apm" + "go.elastic.co/apm/module/apmgrpc" + "go.elastic.co/apm/module/apmhttp" + "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "github.com/elastic/beats/libbeat/logp" + + "github.com/elastic/apm-server/beater/config" + processor "github.com/elastic/apm-server/processor/otel" + "github.com/elastic/apm-server/publish" + "github.com/elastic/apm-server/transform" +) + +// Server manages Jaeger gRPC and HTTP servers, providing methods for starting and stopping them. +type Server struct { + logger *logp.Logger + grpc struct { + server *grpc.Server + listener net.Listener + } + http struct { + server *http.Server + listener net.Listener + } +} + +// NewServer creates a new Server. +func NewServer(logger *logp.Logger, cfg *config.Config, tracer *apm.Tracer, reporter publish.Reporter) (*Server, error) { + if !cfg.JaegerConfig.GRPC.Enabled && !cfg.JaegerConfig.HTTP.Enabled { + return nil, nil + } + traceConsumer := &processor.Consumer{ + Reporter: reporter, + TransformConfig: transform.Config{}, + } + + srv := &Server{logger: logger} + if cfg.JaegerConfig.GRPC.Enabled { + // TODO(axw) should the listener respect cfg.MaxConnections? + grpcListener, err := net.Listen("tcp", cfg.JaegerConfig.GRPC.Host) + if err != nil { + return nil, err + } + grpcOptions := []grpc.ServerOption{grpc.UnaryInterceptor(apmgrpc.NewUnaryServerInterceptor( + apmgrpc.WithRecovery(), + apmgrpc.WithTracer(tracer))), + } + if cfg.JaegerConfig.GRPC.TLS != nil { + creds := credentials.NewTLS(cfg.JaegerConfig.GRPC.TLS) + grpcOptions = append(grpcOptions, grpc.Creds(creds)) + } + srv.grpc.server = grpc.NewServer(grpcOptions...) + srv.grpc.listener = grpcListener + // TODO(simi) to add support for sampling: api_v2.RegisterSamplingManagerServer + api_v2.RegisterCollectorServiceServer(srv.grpc.server, grpcCollector{traceConsumer}) + } + if cfg.JaegerConfig.HTTP.Enabled { + // TODO(axw) should the listener respect cfg.MaxConnections? + httpListener, err := net.Listen("tcp", cfg.JaegerConfig.HTTP.Host) + if err != nil { + return nil, err + } + httpMux, err := newHTTPMux(traceConsumer) + if err != nil { + return nil, err + } + srv.http.listener = httpListener + srv.http.server = &http.Server{ + Handler: apmhttp.Wrap(httpMux, apmhttp.WithTracer(tracer)), + IdleTimeout: cfg.IdleTimeout, + ReadTimeout: cfg.ReadTimeout, + WriteTimeout: cfg.WriteTimeout, + MaxHeaderBytes: cfg.MaxHeaderSize, + } + } + return srv, nil +} + +// Serve accepts gRPC and HTTP connections, and handles Jaeger requests. +// +// Serve blocks until Stop is called, or if either of the gRPC or HTTP +// servers terminates unexpectedly. +func (s *Server) Serve() error { + var g errgroup.Group + if s.grpc.server != nil { + g.Go(s.serveGRPC) + } + if s.http.server != nil { + g.Go(s.serveHTTP) + } + return g.Wait() +} + +func (s *Server) serveGRPC() error { + s.logger.Infof("Listening for Jaeger gRPC requests on: %s", s.grpc.listener.Addr()) + return s.grpc.server.Serve(s.grpc.listener) +} + +func (s *Server) serveHTTP() error { + s.logger.Infof("Listening for Jaeger HTTP requests on: %s", s.http.listener.Addr()) + if err := s.http.server.Serve(s.http.listener); err != nil && err != http.ErrServerClosed { + return err + } + return nil +} + +// Stop stops the gRPC and HTTP servers gracefully, causing Serve to return. +func (s *Server) Stop() { + if s.grpc.server != nil { + s.logger.Infof("Stopping Jaeger gRPC server") + s.grpc.server.GracefulStop() + } + if s.http.server != nil { + s.logger.Infof("Stopping Jaeger HTTP server") + if err := s.http.server.Shutdown(context.Background()); err != nil { + s.logger.Errorf("Error stopping Jaeger HTTP server: %s", err) + if err := s.http.server.Close(); err != nil { + s.logger.Errorf("Error closing Jaeger HTTP server: %s", err) + } + } + } +} diff --git a/beater/jaeger/server_test.go b/beater/jaeger/server_test.go new file mode 100644 index 00000000000..26ea10f55ec --- /dev/null +++ b/beater/jaeger/server_test.go @@ -0,0 +1,395 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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 ( + "context" + "crypto/tls" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "path/filepath" + "testing" + + jaegermodel "github.com/jaegertracing/jaeger/model" + jaegerthriftconv "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger" + "github.com/jaegertracing/jaeger/proto-gen/api_v2" + jaegerthrift "github.com/jaegertracing/jaeger/thrift-gen/jaeger" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.elastic.co/apm/apmtest" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common/transport/tlscommon" + "github.com/elastic/beats/libbeat/logp" + + "github.com/elastic/apm-server/beater/config" + "github.com/elastic/apm-server/publish" + "github.com/elastic/apm-server/tests/approvals" +) + +func TestApprovals(t *testing.T) { + cfg := config.DefaultConfig("8.0.0") + cfg.JaegerConfig.GRPC.Enabled = true + cfg.JaegerConfig.GRPC.Host = "localhost:0" + cfg.JaegerConfig.HTTP.Enabled = true + cfg.JaegerConfig.HTTP.Host = "localhost:0" + + for _, name := range []string{ + "batch_1", "batch_2", + } { + t.Run(name, func(t *testing.T) { + tc := testcase{cfg: cfg, grpcDialOpts: []grpc.DialOption{grpc.WithInsecure()}} + tc.setup(t) + defer tc.teardown(t) + + f := filepath.Join("testdata", name) + data, err := ioutil.ReadFile(f + ".json") + require.NoError(t, err) + var request api_v2.PostSpansRequest + require.NoError(t, json.Unmarshal(data, &request)) + + require.NoError(t, tc.sendBatchGRPC(request.Batch)) + require.NoError(t, approvals.ApproveEvents(tc.events, f, "")) + + tc.events = nil + thriftBatch := &jaegerthrift.Batch{ + Process: thriftProcessFromModel(request.Batch.Process), + Spans: jaegerthriftconv.FromDomain(request.Batch.Spans), + } + require.NoError(t, tc.sendBatchHTTP(thriftBatch)) + require.NoError(t, approvals.ApproveEvents(tc.events, f, "")) + }) + } +} + +func TestServerIntegration(t *testing.T) { + for name, tc := range map[string]testcase{ + "default config": { + cfg: config.DefaultConfig("9.9.9"), + }, + "default config with Jaeger gRPC enabled": { + cfg: func() *config.Config { + cfg := config.DefaultConfig("8.0.0") + cfg.JaegerConfig.GRPC.Enabled = true + cfg.JaegerConfig.GRPC.Host = "localhost:0" + return cfg + }(), + grpcDialOpts: []grpc.DialOption{grpc.WithInsecure()}, + }, + "default config with Jaeger HTTP enabled": { + cfg: func() *config.Config { + cfg := config.DefaultConfig("8.0.0") + cfg.JaegerConfig.HTTP.Enabled = true + cfg.JaegerConfig.HTTP.Host = "localhost:0" + return cfg + }(), + }, + "default config with Jaeger gRPC and HTTP enabled": { + cfg: func() *config.Config { + cfg := config.DefaultConfig("8.0.0") + cfg.JaegerConfig.GRPC.Enabled = true + cfg.JaegerConfig.GRPC.Host = "localhost:0" + cfg.JaegerConfig.HTTP.Enabled = true + cfg.JaegerConfig.HTTP.Host = "localhost:0" + return cfg + }(), + grpcDialOpts: []grpc.DialOption{grpc.WithInsecure()}, + }, + "with Jaeger gRPC enabled and TLS disabled": { + cfg: &config.Config{ + JaegerConfig: config.JaegerConfig{ + GRPC: config.JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:0", + }, + }, + }, + grpcDialOpts: []grpc.DialOption{grpc.WithInsecure()}, + }, + "with Jaeger gRPC enabled and TLS enabled, client configured with CA cert": { + cfg: &config.Config{ + JaegerConfig: config.JaegerConfig{ + GRPC: config.JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:0", + TLS: func() *tls.Config { + enabledTrue := true + serverConfig, err := tlscommon.LoadTLSServerConfig(&tlscommon.ServerConfig{ + Enabled: &enabledTrue, + Certificate: tlscommon.CertificateConfig{ + Certificate: filepath.Join("..", "..", "testdata", "tls", "certificate.pem"), + Key: filepath.Join("..", "..", "testdata", "tls", "key.pem"), + }, + }) + if err != nil { + panic(err) + } + return serverConfig.BuildModuleConfig("") + }(), + }, + }, + }, + grpcDialOpts: func() []grpc.DialOption { + tls, err := credentials.NewClientTLSFromFile(filepath.Join("..", "..", "testdata", "tls", "ca.crt.pem"), "apm-server") + require.NoError(t, err) + return []grpc.DialOption{grpc.WithTransportCredentials(tls)} + }(), + }, + "with Jaeger gRPC enabled and TLS enabled, client fails without transport security": { + cfg: &config.Config{ + JaegerConfig: config.JaegerConfig{ + GRPC: config.JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:0", + TLS: func() *tls.Config { + enabledTrue := true + serverConfig, err := tlscommon.LoadTLSServerConfig(&tlscommon.ServerConfig{ + Enabled: &enabledTrue, + Certificate: tlscommon.CertificateConfig{ + Certificate: filepath.Join("..", "..", "testdata", "tls", "certificate.pem"), + Key: filepath.Join("..", "..", "testdata", "tls", "key.pem"), + }, + }) + if err != nil { + panic(err) + } + return serverConfig.BuildModuleConfig("") + }(), + }, + }, + }, + grpcDialShouldFail: true, + }, + "with Jaeger gRPC enabled and TLS enabled, client fails to verify server certificate": { + cfg: &config.Config{ + JaegerConfig: config.JaegerConfig{ + GRPC: config.JaegerGRPCConfig{ + Enabled: true, + Host: "localhost:0", + TLS: func() *tls.Config { + enabledTrue := true + serverConfig, err := tlscommon.LoadTLSServerConfig(&tlscommon.ServerConfig{ + Enabled: &enabledTrue, + Certificate: tlscommon.CertificateConfig{ + Certificate: filepath.Join("..", "..", "testdata", "tls", "certificate.pem"), + Key: filepath.Join("..", "..", "testdata", "tls", "key.pem"), + }, + }) + if err != nil { + panic(err) + } + return serverConfig.BuildModuleConfig("") + }(), + }, + }, + }, + // grpc.Dial returns immediately, and the connection happens in the background. + // Therefore the dial won't fail, the subsequent PostSpans call will fail due + // to the certificate verification failing. + grpcSendShouldFail: true, + grpcDialOpts: func() []grpc.DialOption { + return []grpc.DialOption{grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))} + }(), + }, + } { + t.Run(name, func(t *testing.T) { + tc.setup(t) + defer tc.teardown(t) + + if !tc.cfg.JaegerConfig.GRPC.Enabled && !tc.cfg.JaegerConfig.HTTP.Enabled { + assert.Nil(t, tc.server) + assert.Nil(t, tc.grpcClient) + assert.Nil(t, tc.httpURL) + return + } + + var nevents int + if tc.grpcClient != nil { + err := tc.sendSpanGRPC() + if tc.grpcSendShouldFail { + require.Error(t, err) + } else { + require.NoError(t, err) + assert.Equal(t, nevents+1, len(tc.events)) + nevents++ + tc.tracer.Flush(nil) + transactions := tc.tracer.Payloads().Transactions + require.Len(t, transactions, nevents) + assert.Equal(t, "/jaeger.api_v2.CollectorService/PostSpans", transactions[nevents-1].Name) + } + } + if tc.httpURL != nil { + err := tc.sendSpanHTTP() + require.NoError(t, err) + + assert.Equal(t, nevents+1, len(tc.events)) + nevents++ + tc.tracer.Flush(nil) + transactions := tc.tracer.Payloads().Transactions + require.Len(t, transactions, nevents) + assert.Equal(t, "POST /api/traces", transactions[nevents-1].Name) + } + }) + } +} + +type testcase struct { + cfg *config.Config + grpcDialOpts []grpc.DialOption + grpcDialShouldFail bool + grpcSendShouldFail bool + + events []beat.Event + server *Server + serverDone <-chan error + grpcClient *grpc.ClientConn + httpURL *url.URL + tracer *apmtest.RecordingTracer +} + +func (tc *testcase) setup(t *testing.T) { + reporter := func(ctx context.Context, req publish.PendingReq) error { + for _, transformable := range req.Transformables { + tc.events = append(tc.events, transformable.Transform(req.Tcontext)...) + } + return nil + } + + var err error + tc.tracer = apmtest.NewRecordingTracer() + tc.server, err = NewServer(logp.NewLogger("jaeger"), tc.cfg, tc.tracer.Tracer, reporter) + require.NoError(t, err) + if tc.server == nil { + return + } + + if tc.cfg.JaegerConfig.HTTP.Enabled { + tc.httpURL = &url.URL{ + Scheme: "http", + Host: tc.server.http.listener.Addr().String(), + Path: "/api/traces", + } + } else { + require.Nil(t, tc.server.http.server) + require.Nil(t, tc.server.http.listener) + } + + if tc.cfg.JaegerConfig.GRPC.Enabled { + client, err := grpc.Dial(tc.server.grpc.listener.Addr().String(), tc.grpcDialOpts...) + if tc.grpcDialShouldFail { + require.Error(t, err) + } else { + require.NoError(t, err) + tc.grpcClient = client + } + } else { + require.Nil(t, tc.server.grpc.server) + require.Nil(t, tc.server.grpc.listener) + } + + serverDone := make(chan error, 1) + tc.serverDone = serverDone + go func() { serverDone <- tc.server.Serve() }() +} + +func (tc *testcase) teardown(t *testing.T) { + if tc.serverDone != nil { + tc.server.Stop() + err := <-tc.serverDone + // grpc.ErrServerStopped may be returned by Serve + // in the tests when Stop is called before Serve. + if err != grpc.ErrServerStopped { + require.NoError(t, err) + } + } + if tc.grpcClient != nil { + err := tc.sendSpanGRPC() + require.Error(t, err) // server is closed + tc.grpcClient.Close() + } + if tc.httpURL != nil { + err := tc.sendSpanHTTP() + require.Error(t, err) // server is closed + } + if tc.tracer != nil { + tc.tracer.Close() + } +} + +func (tc *testcase) sendSpanGRPC() error { + return tc.sendBatchGRPC(jaegermodel.Batch{ + Spans: []*jaegermodel.Span{{ + TraceID: jaegermodel.NewTraceID(123, 456), + SpanID: jaegermodel.NewSpanID(789), + }}, + }) +} + +func (tc *testcase) sendBatchGRPC(batch jaegermodel.Batch) error { + client := api_v2.NewCollectorServiceClient(tc.grpcClient) + _, err := client.PostSpans(context.Background(), &api_v2.PostSpansRequest{Batch: batch}) + return err +} + +func (tc *testcase) sendSpanHTTP() error { + return tc.sendBatchHTTP(&jaegerthrift.Batch{ + Process: &jaegerthrift.Process{ServiceName: "whatever"}, + Spans: []*jaegerthrift.Span{{TraceIdHigh: 123, TraceIdLow: 456, SpanId: 789}}, + }) +} + +func (tc *testcase) sendBatchHTTP(batch *jaegerthrift.Batch) error { + body := encodeThriftBatch(batch) + resp, err := http.Post(tc.httpURL.String(), "application/x-thrift", body) + if err != nil { + return err + } + resp.Body.Close() + if resp.StatusCode != http.StatusAccepted { + return fmt.Errorf("expected status %d, got %d", http.StatusAccepted, resp.StatusCode) + } + return nil +} + +func thriftProcessFromModel(in *jaegermodel.Process) *jaegerthrift.Process { + out := &jaegerthrift.Process{ServiceName: in.ServiceName} + out.Tags = make([]*jaegerthrift.Tag, len(in.Tags)) + for i, kv := range in.Tags { + kv := kv // copy for pointer refs + tag := &jaegerthrift.Tag{Key: kv.Key, VType: jaegerthrift.TagType(kv.VType)} + switch kv.VType { + case jaegermodel.ValueType_STRING: + tag.VStr = &kv.VStr + case jaegermodel.ValueType_BOOL: + tag.VBool = &kv.VBool + case jaegermodel.ValueType_INT64: + tag.VLong = &kv.VInt64 + case jaegermodel.ValueType_FLOAT64: + tag.VDouble = &kv.VFloat64 + case jaegermodel.ValueType_BINARY: + tag.VBinary = kv.VBinary + } + out.Tags[i] = tag + } + return out +} diff --git a/beater/api/jaeger/testdata/batch_1.approved.json b/beater/jaeger/testdata/batch_1.approved.json similarity index 100% rename from beater/api/jaeger/testdata/batch_1.approved.json rename to beater/jaeger/testdata/batch_1.approved.json diff --git a/beater/api/jaeger/testdata/batch_1.json b/beater/jaeger/testdata/batch_1.json similarity index 100% rename from beater/api/jaeger/testdata/batch_1.json rename to beater/jaeger/testdata/batch_1.json diff --git a/beater/api/jaeger/testdata/batch_2.approved.json b/beater/jaeger/testdata/batch_2.approved.json similarity index 100% rename from beater/api/jaeger/testdata/batch_2.approved.json rename to beater/jaeger/testdata/batch_2.approved.json diff --git a/beater/api/jaeger/testdata/batch_2.json b/beater/jaeger/testdata/batch_2.json similarity index 100% rename from beater/api/jaeger/testdata/batch_2.json rename to beater/jaeger/testdata/batch_2.json diff --git a/beater/api/context_pool.go b/beater/request/context_pool.go similarity index 69% rename from beater/api/context_pool.go rename to beater/request/context_pool.go index 81ad531d3e1..63b2bf48a7e 100644 --- a/beater/api/context_pool.go +++ b/beater/request/context_pool.go @@ -15,33 +15,34 @@ // specific language governing permissions and limitations // under the License. -package api +package request import ( "net/http" "sync" - - "github.com/elastic/apm-server/beater/request" ) -type contextPool struct { +// ContextPool provides a pool of Context objects, and a +// means of acquiring http.Handlers from Handlers. +type ContextPool struct { p sync.Pool } -func newContextPool() *contextPool { - pool := contextPool{} +// NewContextPool returns a new ContextPool. +func NewContextPool() *ContextPool { + pool := ContextPool{} pool.p.New = func() interface{} { - return &request.Context{} + return &Context{} } return &pool } -func (pool *contextPool) handler(h request.Handler) http.Handler { +// HTTPHandler returns an http.Handler that calls h with a new context. +func (pool *ContextPool) HTTPHandler(h Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - c := pool.p.Get().(*request.Context) + c := pool.p.Get().(*Context) defer pool.p.Put(c) c.Reset(w, r) - h(c) }) } diff --git a/beater/api/context_pool_test.go b/beater/request/context_pool_test.go similarity index 87% rename from beater/api/context_pool_test.go rename to beater/request/context_pool_test.go index f56d5167d44..af6886717d9 100644 --- a/beater/api/context_pool_test.go +++ b/beater/request/context_pool_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package api +package request import ( "net/http" @@ -24,21 +24,19 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/elastic/apm-server/beater/request" ) func TestContextPool(t *testing.T) { - // This test ensures that request.Context instances are reused from a pool, while - // the Request stored inside a context is always set fresh + // This test ensures that Context instances are reused from a pool, while the + // Request stored inside a context is always set fresh. // The test is important to avoid mixing up separate requests in a reused context. - p := newContextPool() + p := NewContextPool() // mockhHandler adds the context and its request to dedicated slices var contexts, requests []interface{} var mu sync.Mutex - mockHandler := func(c *request.Context) { + mockHandler := func(c *Context) { mu.Lock() defer mu.Unlock() contexts = append(contexts, c) @@ -55,7 +53,7 @@ func TestContextPool(t *testing.T) { for j := 0; j < runs; j++ { w := httptest.NewRecorder() r := httptest.NewRequest(http.MethodGet, "/", nil) - p.handler(mockHandler).ServeHTTP(w, r) + p.HTTPHandler(mockHandler).ServeHTTP(w, r) } }() } diff --git a/beater/server.go b/beater/server.go index 3c138685d56..082a74c8180 100644 --- a/beater/server.go +++ b/beater/server.go @@ -38,8 +38,8 @@ type server struct { logger *logp.Logger cfg *config.Config - httpServer *httpServer - jaegerGRPCServer *jaeger.GRPCServer + httpServer *httpServer + jaegerServer *jaeger.Server } func newServer(logger *logp.Logger, cfg *config.Config, tracer *apm.Tracer, reporter publish.Reporter) (server, error) { @@ -47,21 +47,19 @@ func newServer(logger *logp.Logger, cfg *config.Config, tracer *apm.Tracer, repo if err != nil { return server{}, err } - jaegerGRPCServer, err := jaeger.NewGRPCServer(logger, cfg, tracer, reporter) + jaegerServer, err := jaeger.NewServer(logger, cfg, tracer, reporter) if err != nil { return server{}, err } - return server{logger, cfg, httpServer, jaegerGRPCServer}, nil + return server{logger, cfg, httpServer, jaegerServer}, nil } func (s server) run(listener net.Listener, tracerServer *tracerServer, pub *publish.Publisher) error { s.logger.Infof("Starting apm-server [%s built %s]. Hit CTRL-C to stop it.", version.Commit(), version.BuildTime()) var g errgroup.Group - if s.jaegerGRPCServer != nil { - g.Go(func() error { - return s.jaegerGRPCServer.Start() - }) + if s.jaegerServer != nil { + g.Go(s.jaegerServer.Serve) } if s.httpServer != nil { g.Go(func() error { @@ -89,8 +87,8 @@ func (s server) run(listener net.Listener, tracerServer *tracerServer, pub *publ } func (s server) stop(logger *logp.Logger) { - if s.jaegerGRPCServer != nil { - s.jaegerGRPCServer.Stop() + if s.jaegerServer != nil { + s.jaegerServer.Stop() } if s.httpServer != nil { s.httpServer.stop() diff --git a/magefile.go b/magefile.go index 32f35f00ff6..5317f629080 100644 --- a/magefile.go +++ b/magefile.go @@ -103,6 +103,7 @@ func shortConfigFileParams() mage.ConfigFileParams { "elasticsearch_hostport": "localhost:9200", "listen_hostport": "localhost:" + config.DefaultPort, "jaeger_grpc_hostport": "localhost:14250", + "jaeger_http_hostport": "localhost:14268", }, } } @@ -116,6 +117,7 @@ func dockerConfigFileParams() mage.ConfigFileParams { "elasticsearch_hostport": "elasticsearch:9200", "listen_hostport": "0.0.0.0:" + config.DefaultPort, "jaeger_grpc_hostport": "0.0.0.0:14250", + "jaeger_http_hostport": "0.0.0.0:14268", }, } } diff --git a/testdata/tls/ca.crt.pem b/testdata/tls/ca.crt.pem index 6aa866ef3c6..c85923ab153 100644 --- a/testdata/tls/ca.crt.pem +++ b/testdata/tls/ca.crt.pem @@ -1,24 +1,26 @@ -----BEGIN CERTIFICATE----- -MIIEDTCCAvWgAwIBAgIJAK0hBUGT1U4dMA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJTRjELMAkGA1UEBwwCU0YxDDAKBgNVBAoMA2FwbTER -MA8GA1UECwwIYXBtLnRlc3QxETAPBgNVBAMMCGFwbS50ZXN0MB4XDTE5MDUyMzEy -MDAwN1oXDTE5MDYyMjEyMDAwN1owWzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNG -MQswCQYDVQQHDAJTRjEMMAoGA1UECgwDYXBtMREwDwYDVQQLDAhhcG0udGVzdDER -MA8GA1UEAwwIYXBtLnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDc4hD53cwZWALgOkkGdFK2/EUyDEsLrTsIUm1r3PxJBr8dT+i6efmztG19Ktpo -iCXhgFj608sphnivcDAxD03c+hv5VMHV77eBO11BrJ0euNGZIaBkWbcUYIH8lMkj -L4iOqjvNHhcqft98CWH0UnMPQbOarZIPQi2Asoh1BjvmSTIHk1zOfC646qT4RS8r -YYTDMbf0Y8bUo59ONVlYN9lxu7qL+LR/lDHZSrGZlEJeDYERTkO0IqTwJPr5L7o0 -FjvLygYrQh9/JBL/D1+kcAkunffLKUxzWVayAB055ccK9tqqaBiJp4WAqO/jRXqL -eXm9pGXMmdg7Vi9NmTGiyMcZAgMBAAGjgdMwgdAwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQU3UvewGGYImmpQGVP3IrVnwZnGgowgY0GA1UdIwSBhTCBgoAU3Uve -wGGYImmpQGVP3IrVnwZnGgqhX6RdMFsxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJT -RjELMAkGA1UEBwwCU0YxDDAKBgNVBAoMA2FwbTERMA8GA1UECwwIYXBtLnRlc3Qx -ETAPBgNVBAMMCGFwbS50ZXN0ggkArSEFQZPVTh0wDgYDVR0PAQH/BAQDAgGGMA0G -CSqGSIb3DQEBCwUAA4IBAQAI1HzscEA6YMGgCXy5MdwrpJf2lN5EQ47RsOhIwnhO -g8FrQByrYzX59tN5xSO4I0AOvFXNurWudTRYQiTTiQmYcG+8Rcy9B3oHCGSmjxg0 -3J0Pv6nhBng2rAZZJFy2FdEG3T8i1KPnb7ihaf5xfpNrfG91bm64jLOQ7Ksl+Nrc -Q4gTC6viqPEgPzuuDMwKphz94hR3w2BigNXHFoeKBFh3krrSSfLBrYw/faF/suIg -CDJg6HeCZy4hKs7CQxhIWIKiAoHd1DkcjyxrkjDcvB50iReZV9RGF5Je9Vctgjad -Jbo6OrbsCDmfywMmN4jsVqNmJOGyQE6//h2nbPRUBCPn +MIIEeTCCAuGgAwIBAgIQSBFa2J1M1F1VmdGTRhpKMzANBgkqhkiG9w0BAQsFADBV +MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExFTATBgNVBAsMDGFuZHJl +d0BhbGxveTEcMBoGA1UEAwwTbWtjZXJ0IGFuZHJld0BhbGxveTAeFw0xOTEyMTgx +NTAxMjJaFw0yOTEyMTgxNTAxMjJaMFUxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9w +bWVudCBDQTEVMBMGA1UECwwMYW5kcmV3QGFsbG95MRwwGgYDVQQDDBNta2NlcnQg +YW5kcmV3QGFsbG95MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAuqff +L3O5BBd/YjTU8rTh7d1pfltzaMq+nW3lswQY90+SUk8Q1kryGhg2TmDfHzNfZmQi ++FdcTHc31fMujuVmymLSNG75IrNTbJLUcHTWdLBLi1cHzMehJAzxZ4ImazDAxlhI +bNyGJdQ4Wpy1U/hzZZuDWoeurcRhE4u9C4IY5zh4Da9cIThrtJsHCJQseovqCZUg +u0jBA14FV7+J1c+XgB1yN1kUj2epc42lS96GWJPUIMpyK3v1B7I95Vfa0Vm2fsuy +Vc2iNewFrcyrhDTtWgJK74USF1AitkWih+hvXc8D+3EuYT4pRN/ThL/wVLIasXsJ +prZqhj5/OJfwNfF6MB73DPME+v/vufS54eilO4hz42mvCu84EFeGLHqeISt3bJXr +aJ/LFtcaeQxEcZp08IVS4oDObZZkOV2pYrSq1+V4l46bJn6oZuXMH3ywqNTXkpzS +7Nmhup6Ed1E98XyplmJuxIpChmS6wYrMi4yo9qYZy6ENN336Hx9o3nte3l3lAgMB +AAGjRTBDMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1Ud +DgQWBBSnn449BTqjuzA5/jsJXD247pnjSjANBgkqhkiG9w0BAQsFAAOCAYEAYUpw +TmUlYH5JlY3b7hpi/93TrKueUfc8SoLzL8LWjiRuyB+884sDr9XAx95eZ/UwHher +7S8x3dzrQ7snkMhM/aISCReu2Uwo7ao75UYCqtT3Es9LTownvRM3ffq7QQexgpmK +CVX772qWBnwUGM+f8ngAA3zlWC2z/LvYLdRqNRa1r/Cpejzs3Dg3d7c5ktKlnOac +ssPt/exDdB1sULuWPNwRVQwDHrOH9mM71JiQpt2AG2RGLck1eNdpNAyFYIiAGI1n +EJ8B/xxidGY+7G/X1HmQahg4FAjRnSP4Sg0SHRem6TL6Ocmc4x9jRyS80K1uoDqo +hxnHQQ3Cz/DgSvUx9dOAaGeB7cr3WzE+1JT1WaFV0/XauYEmjFiSr3J7YPl2ZLiE +ug1tTlzvqX1YlxvweIclLdjWEwu6NL1yA39Kdpz6AYLjJeyHOUaJw8qkyEVfYR/5 +ike0BAhkY0lbr0wiVhjRrOvxcKIYLB71DTYVv/O4jiBLn349qvIWaWePZUDt -----END CERTIFICATE----- diff --git a/testdata/tls/certificate.pem b/testdata/tls/certificate.pem index debfcaeec91..ff546c80971 100644 --- a/testdata/tls/certificate.pem +++ b/testdata/tls/certificate.pem @@ -1,24 +1,24 @@ -----BEGIN CERTIFICATE----- -MIIEDDCCAnSgAwIBAgIQD7olAnRFP4oAsfPUqSfm6jANBgkqhkiG9w0BAQsFADBV +MIIEDDCCAnSgAwIBAgIQQdc3EublR2vZ0MDmd9l9wDANBgkqhkiG9w0BAQsFADBV MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExFTATBgNVBAsMDGFuZHJl -d0BhbGxveTEcMBoGA1UEAwwTbWtjZXJ0IGFuZHJld0BhbGxveTAeFw0xOTEwMTcw -NjUxMTVaFw0yOTEwMTcwNjUxMTVaMEAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9w +d0BhbGxveTEcMBoGA1UEAwwTbWtjZXJ0IGFuZHJld0BhbGxveTAeFw0xOTEyMTgx +NTAxMjJaFw0yOTEyMTgxNTAxMjJaMEAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9w bWVudCBjZXJ0aWZpY2F0ZTEVMBMGA1UECwwMYW5kcmV3QGFsbG95MIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx6k+9q7Us/wQqRNED+0cHosEb9zMj3dE -9nCxw6c8AQ6jF8YzUBA8CL9WqG+dB9FlqjY/jShLbKLTwYayZHcceoGKqUbpI5yZ -7aGsvrztD2UNa0DHwInCAJjLG1sFgPTqCvu3h9aXGRJCGpNzRKU3ueKnHB1tCkLh -CLVB0GyyhOWGcd0YuPFle2DlE7RNsnuQbwtrGzb+zWv0oqVMcyJzGgTBOpNmn31D -PuwoN3BKGk0uqWJIK5Pi9YOH2eeBvP/FqBkGWVov/JChDMIEJOg9M3yeP5rOlYZs -OViLjyWzw3tXMJ2grr9++O9P6fr4Ytz9By/K7XWh6mWN0s/xcChE3wIDAQABo20w +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzKWyVEaVDmHHHjR9GcIF7CqkZxaHt1qG +ND7LuZIgvcsPVkk8+6xyJ4HGLtUxXwSrhZpiBkTGe4xoxSggbW93xJPidbX5nsLj +mgQayFhJJEDk9jdjQ4yAtCNuPwGiXDIy9dRu+2vKL6J2Oavg32azuBCc+yp838pw +aPbsZy2yiciL6a4OGMeRlk+gxiYLvaTQjKSrKefC+B/GZJ2xkQYh/tEtjBk2o3R8 +z6yhVkXvhNQilng4HTRJsLu8cWpcO1zWrTCP33/+Oygpo4+kR4k8zIFzbmdvjqdp +b+5lbwy6nVnq6uvGS8OIi0Kf+U/bk/tU3izJRT9UkWMsRjyGiSevBwIDAQABo20w azAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/ -BAIwADAfBgNVHSMEGDAWgBSAoea0+Eh/hSBph1ZWfPmQ1Xp3XDAVBgNVHREEDjAM -ggphcG0tc2VydmVyMA0GCSqGSIb3DQEBCwUAA4IBgQB05KyybKeaKOb/y3UCY5fg -aInWVX5piojCtB2c1pGvTMc+apAb0M+WHZitd+Mlxa5vdeisnBKGxm31xut+IlrC -TBmvfI58Jiz/WkxeaD08yHcQhijQBj8M4BG05gp7WUInuYMQ7qIq2ytCPIbxyTmb -zNn1Nhfzz12c3mLlhdctrvM7peSZ75sff47TSRZ7SrW0admdQTRMdqJQjHCnUjpK -b6YDXG/0wq4u3j67O3YhaLSxzIxj0ZWqd3ahB3YOltl9CxH9hPP8D6zWRHibGp4Y -usAAVIspv+j2jRV2HhbTvG1Zc6eCSpnQOTLRB2jhPKBgpn8hLb1nnMsPIJiKjZpj -Gx6OrkNLXh53S7yQz8H0iFZLHGzydf2wgSWPx1HRTgbfDdnFGle8jVuS7Yz1FTTl -C6Z3cdMYVoaXXG8b2YMXLejeA5nGfU0YpZk1RQ0nYxM5SNxxY73p2YJ0yNeJEefn -ZXsNdR1tNKjw4prvaM2ZYzk1/iDUOWL/mOZPd42gMUI= +BAIwADAfBgNVHSMEGDAWgBSnn449BTqjuzA5/jsJXD247pnjSjAVBgNVHREEDjAM +ggphcG0tc2VydmVyMA0GCSqGSIb3DQEBCwUAA4IBgQAqnBtfKmvv63TbXncmMJeD +bS+NkZSR08T/UjPFOcv9RJWw4vb89bffb146kmF7qLJDBO0AVTsuZqMHn2LaHa0w +Ho1aMZWT67frhsvYgTI8p7JB+NTjBNkncgPPpc3+2XxpdKZNU/MO3j9NAE+wGWs9 +nm+GOqdiy2sHcqhkGRDOmvGaQzOOCSGlWy7QrGKHFvzUgOytMrrPj1sttbRo5P1y +sQeIlo+wNOruXu3ZD8V1kczISTBMk6irIIbIh/8oNbwCq6FxAZL1cvtqaYwb47Ot +wWCxRKGhR3LSfrBov4ZEF1JYlKqfbWZXZ7KSByyD+YuwddKJ+JnVc4T6C6c+VYO1 +t/ynsmrjcWMKMldzu5e7OUhv4df3L9NvsAXFb0Rk17h6qadnsPseFt4M9swTORWg +4aDbNPBZULTK7MJlNZuGPPoc3tU9QRnmh9rYrd9/rX4Ai3btpFh3uWkw/ml3l5LK +PykPwYQ6lMiE/wOEWIZGipkk9Ik9dTN70hTEbmuayUI= -----END CERTIFICATE----- diff --git a/testdata/tls/key.pem b/testdata/tls/key.pem index 32be45cde73..9d379f312a9 100644 --- a/testdata/tls/key.pem +++ b/testdata/tls/key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHqT72rtSz/BCp -E0QP7RweiwRv3MyPd0T2cLHDpzwBDqMXxjNQEDwIv1aob50H0WWqNj+NKEtsotPB -hrJkdxx6gYqpRukjnJntoay+vO0PZQ1rQMfAicIAmMsbWwWA9OoK+7eH1pcZEkIa -k3NEpTe54qccHW0KQuEItUHQbLKE5YZx3Ri48WV7YOUTtE2ye5BvC2sbNv7Na/Si -pUxzInMaBME6k2affUM+7Cg3cEoaTS6pYkgrk+L1g4fZ54G8/8WoGQZZWi/8kKEM -wgQk6D0zfJ4/ms6Vhmw5WIuPJbPDe1cwnaCuv37470/p+vhi3P0HL8rtdaHqZY3S -z/FwKETfAgMBAAECggEBAJU84j1M7NwjeuiF6AfneW8zBfv/FD/gLIHwNk9CP02i -/TEWCuC7YcRAEKwR0VQ4pj8WEWaXSdlH0/QBlHIXvgersFNbF4Rw13WRtSdU2/T3 -2ZHjd+tojMQZcSdfX7vGVPIkuEgmlAY/aX2n3S7gN8kPq00OiaRz3PS/VxRNSxqd -iQpld8tOiExMablEVscZDDQm/ahQG/jqeXDCoxYndGtLNMRuk1p3HPJvfAPABqxx -3RYI4DmdL61qzyfN3ObLB8yn/VjPC9KFAe7YAHV7klfnBVV4xeMotOIy7gxTajut -TrKj7a6ZqgymNYo8mGJhbJXdH5GtmTo7pdwRxBRTBxECgYEA/neLiP11RqFQaqiO -4IyocrE7BYz9U4VrtP0RRgZgkN1bM1RmMLSOy7emdl0Um6tkBKVUsJjDBtfmsdCj -2LJTHEMY498PMsMJsvjN9a0kbdV9jGelu4bVfO/xJNQYVmtTSosYV/U18yQVSWho -A1U20HWVDKcguOildMcdKnHPRBUCgYEAyN0tBTgHXRlw/dUxBx5c5cvYRJ1XDE0u -zMCYnUNyx79tx3hvNJhmfWpMEW4DSXGizc8ijq/QDFvZ/3xIaYrmR8D/9PyQbcC6 -t5UJFD1xWE0WoeaEL6TUnhSnYGE4adF8OkJcDKTjOywHuG15ZiDG96Ievn1zAdIY -ZUNOBQPZniMCgYBQDjf9zw94OwPbqk/Y4SeVfaB97I8+GXl7JSqsBxGWQa2Rhnnn -1MYf3RUno7z6BH+g3oq4TDb/Dilrw6HoaKGxAILyHZjgdW+1uITDR8dwLnwjEfCY -AKFlfu80kO1fMsCvcPclpOVmKvHveENQ2Rw3lOZhZqrqwXZcONA6LDfyyQKBgFXN -PPz8uRCI3J5hYkcTLkWvNNvihhuoILSwFMEg3bf7ys4pYP+LlkQ+ku3jG55U32Gg -+LcQ3QNafR3InjoPblz6UZv6A0wOxvPCwxUVRgSdMWzJRm//rh803WarQOja5oEQ -dbek+7f8D/Q1N2Vr3PJNG2rttaHyeB9Rh9NWmLAXAoGAKjq/669YRny5kR2Pks6W -Zg/5RskXBhCAIiS5KYN/4oAAoMcHm4TieFJ0GtXFtzxya1ZwMM8SE6l9x+vlvPW7 -xrqSOgJcPv65h3s4mtfzgf03UlZDuO/VAwTFoIGxUHcwOvP5hY2l3Zn3SM/vbPxx -8lxZAtOQb+/kUb86+lQ1qoM= +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMpbJURpUOYcce +NH0ZwgXsKqRnFoe3WoY0Psu5kiC9yw9WSTz7rHIngcYu1TFfBKuFmmIGRMZ7jGjF +KCBtb3fEk+J1tfmewuOaBBrIWEkkQOT2N2NDjIC0I24/AaJcMjL11G77a8ovonY5 +q+DfZrO4EJz7KnzfynBo9uxnLbKJyIvprg4Yx5GWT6DGJgu9pNCMpKsp58L4H8Zk +nbGRBiH+0S2MGTajdHzPrKFWRe+E1CKWeDgdNEmwu7xxalw7XNatMI/ff/47KCmj +j6RHiTzMgXNuZ2+Op2lv7mVvDLqdWerq68ZLw4iLQp/5T9uT+1TeLMlFP1SRYyxG +PIaJJ68HAgMBAAECggEBAKJCwumVaTwVBOcLISHaOA3wJZhjQcp8aSplm+yQU4uI +xKlaupKmQYDXocaiXVoEfucY6J4ly+ZMBwpD7ao3lpPz2bwRRFHAHuyQUpgFgEDR +f3lFo1v8vFOYQCKO7igB2WwXOsP4zEAGpYzGni8j5F2ONpnjL03V2lkvZ3PLxOL/ +BiWdUzh3IKWEjIbQyLzBeE7x8Apv9uE0RRqitcUrd4IcVhh40Z40Q0/vdfWGqbbI +9bwdx6IOh1RpBjAeVqs8I0U0uqdjAltu6huhobTvl23He+/0/uKqX2pZL+90G+on +XreyFn1BKIyWeaKeiSiqzCf9yePol2xzdwQY7wfALhkCgYEAzodGh7A16cUNyJo9 +DfMcXo104m3rLbBDRqx8zTD1V3LF8xLUmUrpHGqLRS5c/BcyBUExmDnUs8bFILDE +j7Bm2dZYlD2k6+vUokGH+SYCwWqdE1n6fgIL6CmnchunIbnlPdt8qVlGnpNRgLvX +W/raw/BQMzGcw6p8moX1uoTBzusCgYEA/asQcY4m8zw7Z7hxvF0MbFbMvr8NC9QG +2yv/aLa1Tl/nBuDosar8iF0JfH03MZWxYmnMJ+gw1xzUGsdhM8qS6V4grOPeYimk +OoA8cf6dNNyI7K/scbxUeR4SwcLdkUpYldTE7aU54P+bhsgZVS3lOzKjFC3ShlCE +bLILPSXZMVUCgYEAl1x/LWzQZm68Blw8COA213k2w8gpR0faVo6NvNh3xspgFyCi +3WIQbHoNbftnvH3HdCBul5EyuTshOC81L9Xp2xcDvklbeGhTY0NBwzC/bj+TtR4J +vpYDYfg9NxzbJZWXU/lraLX8UrXHUuDYGhpEgLu8G3jt2l01iw5IpJUtcVcCgYBu +tA4MEKaM9ldSj5sLQmxeh475G7Wc2N5ZHh1r3HjJiG7xgIvspZtqA3hVXOwOdq6g +LV3MeLd/2XPzb9nK2Xg94jdOXG+71UJ3yWkXsq9211vmN2xvwmn3JZm398vsUU7R +rLZ4o+fbepGsQ31SwCHPMO0crFa5CUCRky32dKMRtQKBgQCgmCmmw0E28f2wXr+n +w3ojlKjeyTz5JV0BbvaRXIKlYw5ZlBtFnXI8mWKGmQlILs9Ot0iYlaTak/iHHu9G +mmHudL7Q4rzLDR+xPp85yWa4/pk1V+ytNhgPaTqDGop4A7vHt6xBRLEHLcszcfqi +jdACJa/CqAMN6+C0wN4LKWpSTA== -----END PRIVATE KEY----- diff --git a/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/doc.go b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/doc.go new file mode 100644 index 00000000000..26050003d63 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/doc.go @@ -0,0 +1,17 @@ +// Copyright (c) 2019 The Jaeger Authors. +// 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 jaeger allows converting model.Trace to/from jaeger.thrift model. +package jaeger diff --git a/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/from_domain.go b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/from_domain.go new file mode 100644 index 00000000000..ecf8ae645e1 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/from_domain.go @@ -0,0 +1,154 @@ +// Copyright (c) 2019 The Jaeger Authors. +// 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 jaeger + +import ( + "fmt" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/thrift-gen/jaeger" +) + +// FromDomain takes an arrya of model.Span and returns +// an array of jaeger.Span. If errors are found during +// conversion of tags, then error tags are appended. +func FromDomain(spans []*model.Span) []*jaeger.Span { + jSpans := make([]*jaeger.Span, len(spans)) + dToJ := domainToJaegerTransformer{} + for idx, span := range spans { + jSpans[idx] = dToJ.transformSpan(span) + } + return jSpans +} + +// FromDomainSpan takes a single model.Span and +// converts it into a jaeger.Span. If errors are found +// during conversion of tags, then error tags are appended. +func FromDomainSpan(span *model.Span) *jaeger.Span { + dToJ := &domainToJaegerTransformer{} + return dToJ.transformSpan(span) +} + +type domainToJaegerTransformer struct{} + +func (d domainToJaegerTransformer) keyValueToTag(kv *model.KeyValue) *jaeger.Tag { + if kv.VType == model.StringType { + stringValue := string(kv.VStr) + return &jaeger.Tag{ + Key: kv.Key, + VType: jaeger.TagType_STRING, + VStr: &stringValue, + } + } + + if kv.VType == model.Int64Type { + intValue := kv.Int64() + return &jaeger.Tag{ + Key: kv.Key, + VType: jaeger.TagType_LONG, + VLong: &intValue, + } + } + + if kv.VType == model.BinaryType { + binaryValue := kv.Binary() + return &jaeger.Tag{ + Key: kv.Key, + VType: jaeger.TagType_BINARY, + VBinary: binaryValue, + } + } + + if kv.VType == model.BoolType { + boolValue := kv.Bool() + return &jaeger.Tag{ + Key: kv.Key, + VType: jaeger.TagType_BOOL, + VBool: &boolValue, + } + } + + if kv.VType == model.Float64Type { + floatValue := kv.Float64() + return &jaeger.Tag{ + Key: kv.Key, + VType: jaeger.TagType_DOUBLE, + VDouble: &floatValue, + } + } + + errString := fmt.Sprintf("No suitable tag type found for: %#v", kv.VType) + errTag := &jaeger.Tag{ + Key: "Error", + VType: jaeger.TagType_STRING, + VStr: &errString, + } + + return errTag +} + +func (d domainToJaegerTransformer) convertKeyValuesToTags(kvs model.KeyValues) []*jaeger.Tag { + jaegerTags := make([]*jaeger.Tag, len(kvs)) + for idx, kv := range kvs { + jaegerTags[idx] = d.keyValueToTag(&kv) + } + return jaegerTags +} + +func (d domainToJaegerTransformer) convertLogs(logs []model.Log) []*jaeger.Log { + jaegerLogs := make([]*jaeger.Log, len(logs)) + for idx, log := range logs { + jaegerLogs[idx] = &jaeger.Log{ + Timestamp: int64(model.TimeAsEpochMicroseconds(log.Timestamp)), + Fields: d.convertKeyValuesToTags(log.Fields), + } + } + return jaegerLogs +} + +func (d domainToJaegerTransformer) convertSpanRefs(refs []model.SpanRef) []*jaeger.SpanRef { + jaegerSpanRefs := make([]*jaeger.SpanRef, len(refs)) + for idx, ref := range refs { + jaegerSpanRefs[idx] = &jaeger.SpanRef{ + RefType: jaeger.SpanRefType(ref.RefType), + TraceIdLow: int64(ref.TraceID.Low), + TraceIdHigh: int64(ref.TraceID.High), + SpanId: int64(ref.SpanID), + } + } + return jaegerSpanRefs +} + +func (d domainToJaegerTransformer) transformSpan(span *model.Span) *jaeger.Span { + tags := d.convertKeyValuesToTags(span.Tags) + logs := d.convertLogs(span.Logs) + refs := d.convertSpanRefs(span.References) + + jaegerSpan := &jaeger.Span{ + TraceIdLow: int64(span.TraceID.Low), + TraceIdHigh: int64(span.TraceID.High), + SpanId: int64(span.SpanID), + ParentSpanId: int64(span.ParentSpanID()), + OperationName: span.OperationName, + References: refs, + Flags: int32(span.Flags), + StartTime: int64(model.TimeAsEpochMicroseconds(span.StartTime)), + Duration: int64(model.DurationAsMicroseconds(span.Duration)), + Tags: tags, + Logs: logs, + } + return jaegerSpan +} diff --git a/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/sampling_from_domain.go b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/sampling_from_domain.go new file mode 100644 index 00000000000..8f511da1e03 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/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/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/sampling_to_domain.go b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/sampling_to_domain.go new file mode 100644 index 00000000000..876e50a4a83 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/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/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/to_domain.go b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/to_domain.go new file mode 100644 index 00000000000..d3857094cfd --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/model/converter/thrift/jaeger/to_domain.go @@ -0,0 +1,159 @@ +// Copyright (c) 2019 The Jaeger Authors. +// 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 jaeger + +import ( + "fmt" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/thrift-gen/jaeger" +) + +// ToDomain transforms a set of spans and a process in jaeger.thrift format into a slice of model.Span. +// A valid []*model.Span is always returned, even when there are errors. +// Errors are presented as tags on spans +func ToDomain(jSpans []*jaeger.Span, jProcess *jaeger.Process) []*model.Span { + return toDomain{}.ToDomain(jSpans, jProcess) +} + +// ToDomainSpan transforms a span in jaeger.thrift format into model.Span. +// A valid model.Span is always returned, even when there are errors. +// Errors are presented as tags on spans +func ToDomainSpan(jSpan *jaeger.Span, jProcess *jaeger.Process) *model.Span { + return toDomain{}.ToDomainSpan(jSpan, jProcess) +} + +// ToDomainProcess transforms a process in jaeger.thrift format to model.Span. +func ToDomainProcess(jProcess *jaeger.Process) *model.Process { + return toDomain{}.getProcess(jProcess) +} + +type toDomain struct{} + +func (td toDomain) ToDomain(jSpans []*jaeger.Span, jProcess *jaeger.Process) []*model.Span { + spans := make([]*model.Span, len(jSpans)) + mProcess := td.getProcess(jProcess) + for i, jSpan := range jSpans { + spans[i] = td.transformSpan(jSpan, mProcess) + } + return spans +} + +func (td toDomain) ToDomainSpan(jSpan *jaeger.Span, jProcess *jaeger.Process) *model.Span { + mProcess := td.getProcess(jProcess) + return td.transformSpan(jSpan, mProcess) +} + +func (td toDomain) transformSpan(jSpan *jaeger.Span, mProcess *model.Process) *model.Span { + traceID := model.NewTraceID(uint64(jSpan.TraceIdHigh), uint64(jSpan.TraceIdLow)) + //allocate extra space for future append operation + tags := td.getTags(jSpan.Tags, 1) + refs := td.getReferences(jSpan.References) + // We no longer store ParentSpanID in the domain model, but the data in Thrift model + // might still have these IDs without representing them in the References, so we + // convert it back into child-of reference. + if jSpan.ParentSpanId != 0 { + parentSpanID := model.NewSpanID(uint64(jSpan.ParentSpanId)) + refs = model.MaybeAddParentSpanID(traceID, parentSpanID, refs) + } + return &model.Span{ + TraceID: traceID, + SpanID: model.NewSpanID(uint64(jSpan.SpanId)), + OperationName: jSpan.OperationName, + References: refs, + Flags: model.Flags(jSpan.Flags), + StartTime: model.EpochMicrosecondsAsTime(uint64(jSpan.StartTime)), + Duration: model.MicrosecondsAsDuration(uint64(jSpan.Duration)), + Tags: tags, + Logs: td.getLogs(jSpan.Logs), + Process: mProcess, + } +} + +func (td toDomain) getReferences(jRefs []*jaeger.SpanRef) []model.SpanRef { + if len(jRefs) == 0 { + return nil + } + + mRefs := make([]model.SpanRef, len(jRefs)) + for idx, jRef := range jRefs { + mRefs[idx] = model.SpanRef{ + RefType: model.SpanRefType(int(jRef.RefType)), + TraceID: model.NewTraceID(uint64(jRef.TraceIdHigh), uint64(jRef.TraceIdLow)), + SpanID: model.NewSpanID(uint64(jRef.SpanId)), + } + } + + return mRefs +} + +// getProcess takes a jaeger.thrift process and produces a model.Process. +// Any errors are presented as tags +func (td toDomain) getProcess(jProcess *jaeger.Process) *model.Process { + if jProcess == nil { + return nil + } + tags := td.getTags(jProcess.Tags, 0) + return &model.Process{ + Tags: tags, + ServiceName: jProcess.ServiceName, + } +} + +//convert the jaeger.Tag slice to domain KeyValue slice +//zipkin/to_domain.go does not give a default slice size since it has to filter annotations, jaeger conversion is more predictable +//thus to avoid future full array copy when using append, pre-allocate extra space as an optimization +func (td toDomain) getTags(tags []*jaeger.Tag, extraSpace int) model.KeyValues { + if len(tags) == 0 { + return nil + } + retMe := make(model.KeyValues, len(tags), len(tags)+extraSpace) + for i, tag := range tags { + retMe[i] = td.getTag(tag) + } + return retMe +} + +func (td toDomain) getTag(tag *jaeger.Tag) model.KeyValue { + switch tag.VType { + case jaeger.TagType_BOOL: + return model.Bool(tag.Key, tag.GetVBool()) + case jaeger.TagType_BINARY: + return model.Binary(tag.Key, tag.GetVBinary()) + case jaeger.TagType_DOUBLE: + return model.Float64(tag.Key, tag.GetVDouble()) + case jaeger.TagType_LONG: + return model.Int64(tag.Key, tag.GetVLong()) + case jaeger.TagType_STRING: + return model.String(tag.Key, tag.GetVStr()) + default: + return model.String(tag.Key, fmt.Sprintf("Unknown VType: %+v", tag)) + } +} + +func (td toDomain) getLogs(logs []*jaeger.Log) []model.Log { + if len(logs) == 0 { + return nil + } + retMe := make([]model.Log, len(logs)) + for i, log := range logs { + retMe[i] = model.Log{ + Timestamp: model.EpochMicrosecondsAsTime(uint64(log.Timestamp)), + Fields: td.getTags(log.Fields, 0), + } + } + return retMe +} diff --git a/vendor/github.com/jaegertracing/jaeger/model/ids.go b/vendor/github.com/jaegertracing/jaeger/model/ids.go index 8b34f7c9a33..be7da4d546c 100644 --- a/vendor/github.com/jaegertracing/jaeger/model/ids.go +++ b/vendor/github.com/jaegertracing/jaeger/model/ids.go @@ -49,9 +49,9 @@ func NewTraceID(high, low uint64) TraceID { func (t TraceID) String() string { if t.High == 0 { - return fmt.Sprintf("%x", t.Low) + return fmt.Sprintf("%016x", t.Low) } - return fmt.Sprintf("%x%016x", t.High, t.Low) + return fmt.Sprintf("%016x%016x", t.High, t.Low) } // TraceIDFromString creates a TraceID from a hexadecimal string @@ -163,7 +163,7 @@ func NewSpanID(v uint64) SpanID { } func (s SpanID) String() string { - return fmt.Sprintf("%x", uint64(s)) + return fmt.Sprintf("%016x", uint64(s)) } // SpanIDFromString creates a SpanID from a hexadecimal string diff --git a/vendor/github.com/jaegertracing/jaeger/model/keyvalue.go b/vendor/github.com/jaegertracing/jaeger/model/keyvalue.go index 09fae483553..44f3e1bdb03 100644 --- a/vendor/github.com/jaegertracing/jaeger/model/keyvalue.go +++ b/vendor/github.com/jaegertracing/jaeger/model/keyvalue.go @@ -120,8 +120,17 @@ func (kv *KeyValue) Value() interface{} { } } -// AsString returns a potentially lossy string representation of the value. +// AsStringLossy returns a potentially lossy string representation of the value. +func (kv *KeyValue) AsStringLossy() string { + return kv.asString(true) +} + +// AsString returns a string representation of the value. func (kv *KeyValue) AsString() string { + return kv.asString(false) +} + +func (kv *KeyValue) asString(truncate bool) string { switch kv.VType { case StringType: return kv.VStr @@ -135,7 +144,7 @@ func (kv *KeyValue) AsString() string { case Float64Type: return strconv.FormatFloat(kv.Float64(), 'g', 10, 64) case BinaryType: - if len(kv.VBinary) > 256 { + if truncate && len(kv.VBinary) > 256 { return hex.EncodeToString(kv.VBinary[0:256]) + "..." } return hex.EncodeToString(kv.VBinary) diff --git a/vendor/github.com/jaegertracing/jaeger/proto-gen/api_v2/query.pb.go b/vendor/github.com/jaegertracing/jaeger/proto-gen/api_v2/query.pb.go index 234257ef468..16e45ac881a 100644 --- a/vendor/github.com/jaegertracing/jaeger/proto-gen/api_v2/query.pb.go +++ b/vendor/github.com/jaegertracing/jaeger/proto-gen/api_v2/query.pb.go @@ -438,6 +438,7 @@ func (m *GetServicesResponse) GetServices() []string { type GetOperationsRequest struct { Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` + SpanKind string `protobuf:"bytes,2,opt,name=span_kind,json=spanKind,proto3" json:"span_kind,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -483,18 +484,81 @@ func (m *GetOperationsRequest) GetService() string { return "" } -type GetOperationsResponse struct { - Operations []string `protobuf:"bytes,1,rep,name=operations,proto3" json:"operations,omitempty"` +func (m *GetOperationsRequest) GetSpanKind() string { + if m != nil { + return m.SpanKind + } + return "" +} + +type Operation struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + SpanKind string `protobuf:"bytes,2,opt,name=span_kind,json=spanKind,proto3" json:"span_kind,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } +func (m *Operation) Reset() { *m = Operation{} } +func (m *Operation) String() string { return proto.CompactTextString(m) } +func (*Operation) ProtoMessage() {} +func (*Operation) Descriptor() ([]byte, []int) { + return fileDescriptor_26651706f9f8a4f0, []int{9} +} +func (m *Operation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Operation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Operation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Operation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Operation.Merge(m, src) +} +func (m *Operation) XXX_Size() int { + return m.Size() +} +func (m *Operation) XXX_DiscardUnknown() { + xxx_messageInfo_Operation.DiscardUnknown(m) +} + +var xxx_messageInfo_Operation proto.InternalMessageInfo + +func (m *Operation) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Operation) GetSpanKind() string { + if m != nil { + return m.SpanKind + } + return "" +} + +type GetOperationsResponse struct { + OperationNames []string `protobuf:"bytes,1,rep,name=operationNames,proto3" json:"operationNames,omitempty"` + Operations []*Operation `protobuf:"bytes,2,rep,name=operations,proto3" json:"operations,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + func (m *GetOperationsResponse) Reset() { *m = GetOperationsResponse{} } func (m *GetOperationsResponse) String() string { return proto.CompactTextString(m) } func (*GetOperationsResponse) ProtoMessage() {} func (*GetOperationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_26651706f9f8a4f0, []int{9} + return fileDescriptor_26651706f9f8a4f0, []int{10} } func (m *GetOperationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -523,7 +587,14 @@ func (m *GetOperationsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_GetOperationsResponse proto.InternalMessageInfo -func (m *GetOperationsResponse) GetOperations() []string { +func (m *GetOperationsResponse) GetOperationNames() []string { + if m != nil { + return m.OperationNames + } + return nil +} + +func (m *GetOperationsResponse) GetOperations() []*Operation { if m != nil { return m.Operations } @@ -542,7 +613,7 @@ func (m *GetDependenciesRequest) Reset() { *m = GetDependenciesRequest{} func (m *GetDependenciesRequest) String() string { return proto.CompactTextString(m) } func (*GetDependenciesRequest) ProtoMessage() {} func (*GetDependenciesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_26651706f9f8a4f0, []int{10} + return fileDescriptor_26651706f9f8a4f0, []int{11} } func (m *GetDependenciesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -596,7 +667,7 @@ func (m *GetDependenciesResponse) Reset() { *m = GetDependenciesResponse func (m *GetDependenciesResponse) String() string { return proto.CompactTextString(m) } func (*GetDependenciesResponse) ProtoMessage() {} func (*GetDependenciesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_26651706f9f8a4f0, []int{11} + return fileDescriptor_26651706f9f8a4f0, []int{12} } func (m *GetDependenciesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -653,6 +724,8 @@ func init() { golang_proto.RegisterType((*GetServicesResponse)(nil), "jaeger.api_v2.GetServicesResponse") proto.RegisterType((*GetOperationsRequest)(nil), "jaeger.api_v2.GetOperationsRequest") golang_proto.RegisterType((*GetOperationsRequest)(nil), "jaeger.api_v2.GetOperationsRequest") + proto.RegisterType((*Operation)(nil), "jaeger.api_v2.Operation") + golang_proto.RegisterType((*Operation)(nil), "jaeger.api_v2.Operation") proto.RegisterType((*GetOperationsResponse)(nil), "jaeger.api_v2.GetOperationsResponse") golang_proto.RegisterType((*GetOperationsResponse)(nil), "jaeger.api_v2.GetOperationsResponse") proto.RegisterType((*GetDependenciesRequest)(nil), "jaeger.api_v2.GetDependenciesRequest") @@ -665,68 +738,71 @@ func init() { proto.RegisterFile("api_v2/query.proto", fileDescriptor_26651706f9 func init() { golang_proto.RegisterFile("api_v2/query.proto", fileDescriptor_26651706f9f8a4f0) } var fileDescriptor_26651706f9f8a4f0 = []byte{ - // 965 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x73, 0xdb, 0x44, - 0x14, 0x47, 0x4e, 0x1c, 0xdb, 0x4f, 0x76, 0x4b, 0xd7, 0x4e, 0x6b, 0x04, 0xd8, 0x8e, 0x42, 0x21, - 0xd3, 0x21, 0xda, 0xd4, 0x0c, 0x53, 0xc8, 0x05, 0xe2, 0xa6, 0xf5, 0xa4, 0x03, 0xa5, 0xa8, 0x39, - 0xc1, 0xc1, 0xb3, 0xb1, 0x16, 0x59, 0x24, 0x5e, 0xa9, 0xd2, 0xda, 0x4d, 0x86, 0xe1, 0xc2, 0x27, - 0x60, 0xe0, 0xc2, 0x89, 0x2b, 0x27, 0xbe, 0x03, 0xc7, 0x1e, 0x99, 0xe1, 0xc6, 0x21, 0x30, 0x81, - 0x0f, 0xc2, 0xec, 0x1f, 0x39, 0xb6, 0xec, 0x49, 0x43, 0x0f, 0x3d, 0x69, 0xf7, 0xed, 0x7b, 0xbf, - 0xf7, 0xef, 0xf7, 0x9e, 0x00, 0x91, 0x28, 0xe8, 0x8d, 0xdb, 0xf8, 0xc9, 0x88, 0xc6, 0x27, 0x4e, - 0x14, 0x87, 0x3c, 0x44, 0x95, 0xaf, 0x09, 0xf5, 0x69, 0xec, 0xa8, 0x27, 0xcb, 0x1c, 0x86, 0x1e, - 0x3d, 0x52, 0x6f, 0x56, 0xcd, 0x0f, 0xfd, 0x50, 0x1e, 0xb1, 0x38, 0x69, 0xe9, 0x1b, 0x7e, 0x18, - 0xfa, 0x47, 0x14, 0x93, 0x28, 0xc0, 0x84, 0xb1, 0x90, 0x13, 0x1e, 0x84, 0x2c, 0xd1, 0xaf, 0x4d, - 0xfd, 0x2a, 0x6f, 0x07, 0xa3, 0xaf, 0x30, 0x0f, 0x86, 0x34, 0xe1, 0x64, 0x18, 0x69, 0x85, 0x46, - 0x56, 0xc1, 0x1b, 0xc5, 0x12, 0x41, 0xbf, 0xbf, 0x2b, 0x3f, 0xfd, 0x4d, 0x9f, 0xb2, 0xcd, 0xe4, - 0x29, 0xf1, 0x7d, 0x1a, 0xe3, 0x30, 0x92, 0x2e, 0xe6, 0xdd, 0xd9, 0x0c, 0xae, 0x76, 0x29, 0xdf, - 0x8f, 0x49, 0x9f, 0xba, 0xf4, 0xc9, 0x88, 0x26, 0x1c, 0x7d, 0x09, 0x45, 0x2e, 0xee, 0xbd, 0xc0, - 0xab, 0x1b, 0x2d, 0x63, 0xa3, 0xdc, 0xf9, 0xf8, 0xd9, 0x69, 0xf3, 0x95, 0x3f, 0x4f, 0x9b, 0x9b, - 0x7e, 0xc0, 0x07, 0xa3, 0x03, 0xa7, 0x1f, 0x0e, 0xb1, 0x4a, 0x5b, 0x28, 0x06, 0xcc, 0xd7, 0x37, - 0xac, 0x92, 0x97, 0x68, 0x7b, 0xbb, 0x67, 0xa7, 0xcd, 0x82, 0x3e, 0xba, 0x05, 0x89, 0xb8, 0xe7, - 0xd9, 0xf7, 0x00, 0x3d, 0x8e, 0x08, 0x4b, 0x5c, 0x9a, 0x44, 0x21, 0x4b, 0xe8, 0xdd, 0xc1, 0x88, - 0x1d, 0x22, 0x0c, 0xf9, 0x44, 0x48, 0xeb, 0x46, 0x6b, 0x69, 0xc3, 0x6c, 0x57, 0x9d, 0x99, 0xa2, - 0x3a, 0xc2, 0xa2, 0xb3, 0x2c, 0x82, 0x70, 0x95, 0x9e, 0x1d, 0x43, 0x75, 0x27, 0xee, 0x0f, 0x82, - 0x31, 0x7d, 0x79, 0xa1, 0x5f, 0x87, 0xda, 0xac, 0x4f, 0x95, 0x81, 0xfd, 0xcb, 0x32, 0xd4, 0xa4, - 0xe4, 0x73, 0x41, 0x8b, 0x47, 0x24, 0x26, 0x43, 0xca, 0x69, 0x9c, 0xa0, 0x35, 0x28, 0x27, 0x34, - 0x1e, 0x07, 0x7d, 0xda, 0x63, 0x64, 0x48, 0x65, 0x44, 0x25, 0xd7, 0xd4, 0xb2, 0x87, 0x64, 0x48, - 0xd1, 0x4d, 0xb8, 0x12, 0x46, 0x54, 0xf5, 0x4f, 0x29, 0xe5, 0xa4, 0x52, 0x65, 0x22, 0x95, 0x6a, - 0x3b, 0xb0, 0xcc, 0x89, 0x9f, 0xd4, 0x97, 0x64, 0x79, 0x36, 0x33, 0xe5, 0x59, 0xe4, 0xdc, 0xd9, - 0x27, 0x7e, 0x72, 0x8f, 0xf1, 0xf8, 0xc4, 0x95, 0xa6, 0xe8, 0x01, 0x5c, 0x49, 0x38, 0x89, 0x79, - 0x4f, 0xf0, 0xa9, 0x37, 0x0c, 0x58, 0x7d, 0xb9, 0x65, 0x6c, 0x98, 0x6d, 0xcb, 0x51, 0x7c, 0x72, - 0x52, 0x3e, 0x39, 0xfb, 0x29, 0xe1, 0x3a, 0x45, 0x51, 0xbc, 0xef, 0xff, 0x6a, 0x1a, 0x6e, 0x59, - 0xda, 0x8a, 0x97, 0x4f, 0x03, 0x96, 0xc5, 0x22, 0xc7, 0xf5, 0xfc, 0x8b, 0x61, 0x91, 0x63, 0x74, - 0x1f, 0xca, 0x29, 0x81, 0x65, 0x54, 0x2b, 0x12, 0xe9, 0xb5, 0x39, 0xa4, 0x5d, 0xad, 0xa4, 0x80, - 0x7e, 0x12, 0x40, 0x66, 0x6a, 0x28, 0x62, 0x9a, 0xc1, 0x21, 0xc7, 0xf5, 0xc2, 0x8b, 0xe0, 0x90, - 0x63, 0xd5, 0x34, 0x12, 0xf7, 0x07, 0x3d, 0x8f, 0x46, 0x7c, 0x50, 0x2f, 0xb6, 0x8c, 0x8d, 0xbc, - 0x68, 0x9a, 0x90, 0xed, 0x0a, 0x91, 0x75, 0x07, 0x4a, 0x93, 0xea, 0xa2, 0x57, 0x61, 0xe9, 0x90, - 0x9e, 0xe8, 0xde, 0x8a, 0x23, 0xaa, 0x41, 0x7e, 0x4c, 0x8e, 0x46, 0x69, 0x2b, 0xd5, 0x65, 0x3b, - 0xf7, 0x81, 0x61, 0x3f, 0x84, 0x6b, 0xf7, 0x03, 0xe6, 0xc9, 0x7e, 0x25, 0x29, 0x67, 0x3f, 0x84, - 0xbc, 0xdc, 0x27, 0x12, 0xc2, 0x6c, 0xaf, 0x5f, 0xa2, 0xb9, 0xae, 0xb2, 0xb0, 0x6b, 0x80, 0xba, - 0x94, 0x3f, 0x56, 0x7c, 0x4a, 0x01, 0xed, 0xdb, 0x50, 0x9d, 0x91, 0x2a, 0x9a, 0x22, 0x0b, 0x8a, - 0x9a, 0x79, 0x6a, 0xcc, 0x4a, 0xee, 0xe4, 0x6e, 0x6f, 0x41, 0xad, 0x4b, 0xf9, 0x67, 0x29, 0xe7, - 0x26, 0xb1, 0xd5, 0xa1, 0xa0, 0x75, 0x74, 0x82, 0xe9, 0xd5, 0xbe, 0x03, 0xab, 0x19, 0x0b, 0xed, - 0xa6, 0x01, 0x30, 0xe1, 0x6e, 0xea, 0x68, 0x4a, 0x62, 0xff, 0x6c, 0xc0, 0xf5, 0x2e, 0xe5, 0xbb, - 0x34, 0xa2, 0xcc, 0xa3, 0xac, 0x1f, 0x9c, 0x57, 0xe2, 0x2e, 0xc0, 0x39, 0xad, 0x74, 0x39, 0x2e, - 0x47, 0xa9, 0xd2, 0x84, 0x52, 0xe8, 0x23, 0x28, 0x52, 0xe6, 0x29, 0x88, 0xdc, 0xff, 0x80, 0x28, - 0x50, 0xe6, 0x09, 0xb9, 0x7d, 0x00, 0x37, 0xe6, 0xe2, 0xd3, 0xb9, 0x75, 0xa1, 0xec, 0x4d, 0xc9, - 0xf5, 0xb6, 0x7a, 0x33, 0xd3, 0xb1, 0x89, 0xe9, 0xc9, 0x27, 0x01, 0x3b, 0xd4, 0x7b, 0x6b, 0xc6, - 0xb0, 0xfd, 0x6b, 0x1e, 0xca, 0xb2, 0xa7, 0xba, 0x4b, 0xe8, 0x10, 0x8a, 0xe9, 0x1a, 0x46, 0x8d, - 0x0c, 0x5e, 0x66, 0x3f, 0x5b, 0x6b, 0x0b, 0xb6, 0xe3, 0xec, 0x3e, 0xb5, 0xad, 0xef, 0xfe, 0xf8, - 0xf7, 0xc7, 0x5c, 0x0d, 0x21, 0x2c, 0x97, 0x57, 0x82, 0xbf, 0x49, 0xd7, 0xe2, 0xb7, 0x5b, 0x06, - 0xe2, 0x50, 0x9e, 0x5e, 0x64, 0xc8, 0xce, 0x00, 0x2e, 0xd8, 0xac, 0xd6, 0xfa, 0x85, 0x3a, 0x7a, - 0x13, 0xbe, 0x2e, 0xdd, 0xae, 0xda, 0x55, 0x4c, 0xd4, 0xf3, 0x94, 0x5f, 0xe4, 0x03, 0x9c, 0x93, - 0x1f, 0xb5, 0x32, 0x78, 0x73, 0x73, 0x71, 0x99, 0x34, 0x91, 0xf4, 0x57, 0xb6, 0x0b, 0x58, 0x8d, - 0xe7, 0xb6, 0x71, 0x6b, 0xcb, 0x40, 0x3e, 0x98, 0x53, 0xfc, 0x47, 0x6b, 0xf3, 0xe5, 0xcc, 0x4c, - 0x8c, 0x65, 0x5f, 0xa4, 0xa2, 0x73, 0xbb, 0x26, 0x7d, 0x99, 0xa8, 0x84, 0xd3, 0xa9, 0x41, 0x21, - 0x54, 0x66, 0x66, 0x00, 0xad, 0xcf, 0xe3, 0xcc, 0xcd, 0x94, 0xf5, 0xd6, 0xc5, 0x4a, 0xda, 0x5d, - 0x55, 0xba, 0xab, 0x20, 0x13, 0x9f, 0xcf, 0x0e, 0x7a, 0x2a, 0x7f, 0xd6, 0xd3, 0xd4, 0x44, 0x37, - 0xe7, 0xd1, 0x16, 0x8c, 0x96, 0xf5, 0xf6, 0xf3, 0xd4, 0xb4, 0xdb, 0x55, 0xe9, 0xf6, 0x2a, 0xaa, - 0xe0, 0x69, 0xbe, 0x76, 0xc6, 0x3f, 0xec, 0x74, 0x50, 0xbe, 0xbd, 0x74, 0xdb, 0xd9, 0xba, 0x95, - 0x33, 0x72, 0xf1, 0xfb, 0x00, 0x0f, 0x24, 0x5e, 0x6b, 0xe7, 0xd1, 0x1e, 0x7a, 0x67, 0xc0, 0x79, - 0x94, 0x6c, 0x63, 0xfc, 0x9c, 0x7f, 0xec, 0xb3, 0xb3, 0x86, 0xf1, 0xfb, 0x59, 0xc3, 0xf8, 0xfb, - 0xac, 0x61, 0xfc, 0xf6, 0x4f, 0xc3, 0x80, 0x1b, 0x41, 0xe8, 0xcc, 0x28, 0xea, 0xf0, 0xbe, 0x58, - 0x51, 0xdf, 0x83, 0x15, 0x39, 0xb2, 0xef, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0xee, 0x7a, 0xc9, - 0xa7, 0x79, 0x09, 0x00, 0x00, + // 1017 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x73, 0xdb, 0x44, + 0x14, 0x47, 0x4e, 0x1c, 0xdb, 0xcf, 0x76, 0x4b, 0xd7, 0x4e, 0x2b, 0x54, 0xb0, 0x1d, 0x85, 0x96, + 0x4c, 0x87, 0x48, 0xa9, 0x19, 0x86, 0x92, 0x61, 0x06, 0xe2, 0xa6, 0xf5, 0xa4, 0xd0, 0x52, 0xd4, + 0x9c, 0xe0, 0xe0, 0xd9, 0x58, 0x8b, 0x2c, 0x1c, 0xaf, 0x54, 0x69, 0xed, 0xc6, 0xc3, 0x70, 0xe1, + 0x13, 0x30, 0x70, 0xe1, 0xc4, 0x95, 0x13, 0xdf, 0x81, 0x63, 0x8f, 0xcc, 0x70, 0xe3, 0x10, 0x98, + 0xc0, 0x07, 0x61, 0xf6, 0x8f, 0x1c, 0x59, 0xce, 0xa4, 0xa1, 0x07, 0x4e, 0xde, 0x7d, 0xfb, 0xde, + 0xef, 0xfd, 0xfb, 0xbd, 0x67, 0x01, 0xc2, 0xa1, 0xdf, 0x9b, 0xb4, 0xed, 0xa7, 0x63, 0x12, 0x4d, + 0xad, 0x30, 0x0a, 0x58, 0x80, 0xaa, 0x5f, 0x61, 0xe2, 0x91, 0xc8, 0x92, 0x4f, 0x46, 0x79, 0x14, + 0xb8, 0xe4, 0x50, 0xbe, 0x19, 0x75, 0x2f, 0xf0, 0x02, 0x71, 0xb4, 0xf9, 0x49, 0x49, 0x5f, 0xf7, + 0x82, 0xc0, 0x3b, 0x24, 0x36, 0x0e, 0x7d, 0x1b, 0x53, 0x1a, 0x30, 0xcc, 0xfc, 0x80, 0xc6, 0xea, + 0xb5, 0xa9, 0x5e, 0xc5, 0xed, 0x60, 0xfc, 0xa5, 0xcd, 0xfc, 0x11, 0x89, 0x19, 0x1e, 0x85, 0x4a, + 0xa1, 0x91, 0x55, 0x70, 0xc7, 0x91, 0x40, 0x50, 0xef, 0x6f, 0x8b, 0x9f, 0xfe, 0xa6, 0x47, 0xe8, + 0x66, 0xfc, 0x0c, 0x7b, 0x1e, 0x89, 0xec, 0x20, 0x14, 0x2e, 0x16, 0xdd, 0x99, 0x14, 0x2e, 0x77, + 0x09, 0xdb, 0x8f, 0x70, 0x9f, 0x38, 0xe4, 0xe9, 0x98, 0xc4, 0x0c, 0x7d, 0x01, 0x45, 0xc6, 0xef, + 0x3d, 0xdf, 0xd5, 0xb5, 0x96, 0xb6, 0x51, 0xe9, 0x7c, 0xf4, 0xfc, 0xb8, 0xf9, 0xca, 0x1f, 0xc7, + 0xcd, 0x4d, 0xcf, 0x67, 0x83, 0xf1, 0x81, 0xd5, 0x0f, 0x46, 0xb6, 0x4c, 0x9b, 0x2b, 0xfa, 0xd4, + 0x53, 0x37, 0x5b, 0x26, 0x2f, 0xd0, 0xf6, 0x76, 0x4f, 0x8e, 0x9b, 0x05, 0x75, 0x74, 0x0a, 0x02, + 0x71, 0xcf, 0x35, 0xef, 0x01, 0x7a, 0x12, 0x62, 0x1a, 0x3b, 0x24, 0x0e, 0x03, 0x1a, 0x93, 0xbb, + 0x83, 0x31, 0x1d, 0x22, 0x1b, 0xf2, 0x31, 0x97, 0xea, 0x5a, 0x6b, 0x69, 0xa3, 0xdc, 0xae, 0x59, + 0x73, 0x45, 0xb5, 0xb8, 0x45, 0x67, 0x99, 0x07, 0xe1, 0x48, 0x3d, 0x33, 0x82, 0xda, 0x4e, 0xd4, + 0x1f, 0xf8, 0x13, 0xf2, 0xff, 0x85, 0x7e, 0x15, 0xea, 0xf3, 0x3e, 0x65, 0x06, 0xe6, 0xcf, 0xcb, + 0x50, 0x17, 0x92, 0xcf, 0x38, 0x2d, 0x1e, 0xe3, 0x08, 0x8f, 0x08, 0x23, 0x51, 0x8c, 0xd6, 0xa0, + 0x12, 0x93, 0x68, 0xe2, 0xf7, 0x49, 0x8f, 0xe2, 0x11, 0x11, 0x11, 0x95, 0x9c, 0xb2, 0x92, 0x3d, + 0xc2, 0x23, 0x82, 0x6e, 0xc0, 0xa5, 0x20, 0x24, 0xb2, 0x7f, 0x52, 0x29, 0x27, 0x94, 0xaa, 0x33, + 0xa9, 0x50, 0xdb, 0x81, 0x65, 0x86, 0xbd, 0x58, 0x5f, 0x12, 0xe5, 0xd9, 0xcc, 0x94, 0xe7, 0x2c, + 0xe7, 0xd6, 0x3e, 0xf6, 0xe2, 0x7b, 0x94, 0x45, 0x53, 0x47, 0x98, 0xa2, 0x07, 0x70, 0x29, 0x66, + 0x38, 0x62, 0x3d, 0xce, 0xa7, 0xde, 0xc8, 0xa7, 0xfa, 0x72, 0x4b, 0xdb, 0x28, 0xb7, 0x0d, 0x4b, + 0xf2, 0xc9, 0x4a, 0xf8, 0x64, 0xed, 0x27, 0x84, 0xeb, 0x14, 0x79, 0xf1, 0xbe, 0xfb, 0xb3, 0xa9, + 0x39, 0x15, 0x61, 0xcb, 0x5f, 0x1e, 0xfa, 0x34, 0x8b, 0x85, 0x8f, 0xf4, 0xfc, 0xcb, 0x61, 0xe1, + 0x23, 0x74, 0x1f, 0x2a, 0x09, 0x81, 0x45, 0x54, 0x2b, 0x02, 0xe9, 0xb5, 0x05, 0xa4, 0x5d, 0xa5, + 0x24, 0x81, 0x7e, 0xe4, 0x40, 0xe5, 0xc4, 0x90, 0xc7, 0x34, 0x87, 0x83, 0x8f, 0xf4, 0xc2, 0xcb, + 0xe0, 0xe0, 0x23, 0xd9, 0x34, 0x1c, 0xf5, 0x07, 0x3d, 0x97, 0x84, 0x6c, 0xa0, 0x17, 0x5b, 0xda, + 0x46, 0x9e, 0x37, 0x8d, 0xcb, 0x76, 0xb9, 0xc8, 0x78, 0x0f, 0x4a, 0xb3, 0xea, 0xa2, 0x57, 0x61, + 0x69, 0x48, 0xa6, 0xaa, 0xb7, 0xfc, 0x88, 0xea, 0x90, 0x9f, 0xe0, 0xc3, 0x71, 0xd2, 0x4a, 0x79, + 0xd9, 0xce, 0xdd, 0xd1, 0xcc, 0x47, 0x70, 0xe5, 0xbe, 0x4f, 0x5d, 0xd1, 0xaf, 0x38, 0xe1, 0xec, + 0xfb, 0x90, 0x17, 0xfb, 0x44, 0x40, 0x94, 0xdb, 0xeb, 0x17, 0x68, 0xae, 0x23, 0x2d, 0xcc, 0x3a, + 0xa0, 0x2e, 0x61, 0x4f, 0x24, 0x9f, 0x12, 0x40, 0xf3, 0x36, 0xd4, 0xe6, 0xa4, 0x92, 0xa6, 0xc8, + 0x80, 0xa2, 0x62, 0x9e, 0x1c, 0xb3, 0x92, 0x33, 0xbb, 0x9b, 0x0f, 0xa1, 0xde, 0x25, 0xec, 0xd3, + 0x84, 0x73, 0xb3, 0xd8, 0x74, 0x28, 0x28, 0x1d, 0x95, 0x60, 0x72, 0x45, 0xd7, 0xa1, 0xc4, 0x27, + 0xb1, 0x37, 0xf4, 0xa9, 0xab, 0x12, 0x2d, 0x72, 0xc1, 0xc7, 0x3e, 0x75, 0xcd, 0x0f, 0xa0, 0x34, + 0xc3, 0x42, 0x08, 0x96, 0x53, 0xec, 0x17, 0xe7, 0xf3, 0xad, 0xa7, 0xb0, 0x9a, 0x09, 0x46, 0x65, + 0x70, 0x33, 0x35, 0x2c, 0x7c, 0x2c, 0x92, 0x3c, 0x32, 0x52, 0x74, 0x07, 0x60, 0x26, 0x89, 0xf5, + 0x9c, 0x98, 0x19, 0x3d, 0x53, 0xd6, 0x19, 0xbc, 0x93, 0xd2, 0x35, 0x7f, 0xd2, 0xe0, 0x6a, 0x97, + 0xb0, 0x5d, 0x12, 0x12, 0xea, 0x12, 0xda, 0xf7, 0x4f, 0xdb, 0x74, 0x17, 0xe0, 0x94, 0xf3, 0xaa, + 0x57, 0x17, 0xe3, 0x7b, 0x69, 0xc6, 0x77, 0xf4, 0x21, 0x14, 0x09, 0x75, 0x25, 0x44, 0xee, 0x3f, + 0x40, 0x14, 0x08, 0x75, 0xb9, 0xdc, 0x3c, 0x80, 0x6b, 0x0b, 0xf1, 0xa9, 0xea, 0x74, 0xa1, 0xe2, + 0xa6, 0xe4, 0x6a, 0x95, 0xbe, 0x91, 0xc9, 0x7b, 0x66, 0x3a, 0xfd, 0xc4, 0xa7, 0x43, 0xb5, 0x54, + 0xe7, 0x0c, 0xdb, 0xbf, 0xe4, 0xa1, 0x22, 0x08, 0xa7, 0x28, 0x84, 0x86, 0x50, 0x4c, 0xfe, 0x23, + 0x50, 0x23, 0x83, 0x97, 0xf9, 0xf3, 0x30, 0xd6, 0xce, 0x58, 0xdd, 0xf3, 0xcb, 0xde, 0x34, 0xbe, + 0xfd, 0xfd, 0x9f, 0x1f, 0x72, 0x75, 0x84, 0x6c, 0xb1, 0x59, 0x63, 0xfb, 0xeb, 0x64, 0x67, 0x7f, + 0xb3, 0xa5, 0x21, 0x06, 0x95, 0xf4, 0x96, 0x45, 0x66, 0x06, 0xf0, 0x8c, 0xb5, 0x6f, 0xac, 0x9f, + 0xab, 0xa3, 0xd6, 0xf4, 0x75, 0xe1, 0x76, 0xd5, 0xac, 0xd9, 0x58, 0x3e, 0xa7, 0xfc, 0x22, 0x0f, + 0xe0, 0x74, 0x32, 0x51, 0x2b, 0x83, 0xb7, 0x30, 0xb4, 0x17, 0x49, 0x13, 0x09, 0x7f, 0x15, 0xb3, + 0x60, 0xcb, 0xdd, 0xb1, 0xad, 0xdd, 0xda, 0xd2, 0x90, 0x07, 0xe5, 0xd4, 0x70, 0xa2, 0xb5, 0xc5, + 0x72, 0x66, 0xc6, 0xd9, 0x30, 0xcf, 0x53, 0x51, 0xb9, 0x5d, 0x11, 0xbe, 0xca, 0xa8, 0x64, 0x27, + 0x23, 0x8d, 0x02, 0xa8, 0xce, 0x4d, 0x11, 0x5a, 0x5f, 0xc4, 0x59, 0x18, 0x78, 0xe3, 0xcd, 0xf3, + 0x95, 0x94, 0xbb, 0x9a, 0x70, 0x57, 0x45, 0x65, 0xfb, 0x74, 0x76, 0xd0, 0x33, 0xf1, 0x25, 0x91, + 0xa6, 0x26, 0xba, 0xb1, 0x88, 0x76, 0xc6, 0x68, 0x19, 0x37, 0x5f, 0xa4, 0xa6, 0xdc, 0xae, 0x0a, + 0xb7, 0x97, 0x51, 0xd5, 0x4e, 0xf3, 0xb5, 0x33, 0xf9, 0x7e, 0xa7, 0x83, 0xf2, 0xed, 0xa5, 0xdb, + 0xd6, 0xd6, 0xad, 0x9c, 0x96, 0x8b, 0xde, 0x05, 0x78, 0x20, 0xf0, 0x5a, 0x3b, 0x8f, 0xf7, 0xd0, + 0x5b, 0x03, 0xc6, 0xc2, 0x78, 0xdb, 0xb6, 0x5f, 0xf0, 0x01, 0xf0, 0xfc, 0xa4, 0xa1, 0xfd, 0x76, + 0xd2, 0xd0, 0xfe, 0x3a, 0x69, 0x68, 0xbf, 0xfe, 0xdd, 0xd0, 0xe0, 0x9a, 0x1f, 0x58, 0x73, 0x8a, + 0x2a, 0xbc, 0xcf, 0x57, 0xe4, 0xef, 0xc1, 0x8a, 0x18, 0xd9, 0x77, 0xfe, 0x0d, 0x00, 0x00, 0xff, + 0xff, 0x26, 0xf0, 0x4d, 0x32, 0x16, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1329,6 +1405,45 @@ func (m *GetOperationsRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(len(m.Service))) i += copy(dAtA[i:], m.Service) } + if len(m.SpanKind) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintQuery(dAtA, i, uint64(len(m.SpanKind))) + i += copy(dAtA[i:], m.SpanKind) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Operation) 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 *Operation) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintQuery(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.SpanKind) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintQuery(dAtA, i, uint64(len(m.SpanKind))) + i += copy(dAtA[i:], m.SpanKind) + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1350,8 +1465,8 @@ func (m *GetOperationsResponse) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Operations) > 0 { - for _, s := range m.Operations { + if len(m.OperationNames) > 0 { + for _, s := range m.OperationNames { dAtA[i] = 0xa i++ l = len(s) @@ -1365,6 +1480,18 @@ func (m *GetOperationsResponse) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], s) } } + if len(m.Operations) > 0 { + for _, msg := range m.Operations { + dAtA[i] = 0x12 + i++ + i = encodeVarintQuery(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1603,6 +1730,30 @@ func (m *GetOperationsRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + l = len(m.SpanKind) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Operation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.SpanKind) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1615,12 +1766,18 @@ func (m *GetOperationsResponse) Size() (n int) { } var l int _ = l - if len(m.Operations) > 0 { - for _, s := range m.Operations { + if len(m.OperationNames) > 0 { + for _, s := range m.OperationNames { l = len(s) n += 1 + l + sovQuery(uint64(l)) } } + if len(m.Operations) > 0 { + for _, e := range m.Operations { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2677,6 +2834,156 @@ func (m *GetOperationsRequest) Unmarshal(dAtA []byte) error { } m.Service = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpanKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpanKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Operation) 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 ErrIntOverflowQuery + } + 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: Operation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Operation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpanKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpanKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2733,7 +3040,7 @@ func (m *GetOperationsResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Operations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OperationNames", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2761,7 +3068,41 @@ func (m *GetOperationsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Operations = append(m.Operations, string(dAtA[iNdEx:postIndex])) + m.OperationNames = append(m.OperationNames, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operations = append(m.Operations, &Operation{}) + if err := m.Operations[len(m.Operations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/constants.go b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/constants.go new file mode 100644 index 00000000000..1c6ade8e210 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/constants.go @@ -0,0 +1,19 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + + "github.com/apache/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +func init() { +} diff --git a/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/samplingmanager.go b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/samplingmanager.go new file mode 100644 index 00000000000..1c28aaf0e30 --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/samplingmanager.go @@ -0,0 +1,411 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + + "github.com/apache/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +type SamplingManager interface { + // Parameters: + // - ServiceName + GetSamplingStrategy(serviceName string) (r *SamplingStrategyResponse, err error) +} + +type SamplingManagerClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewSamplingManagerClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *SamplingManagerClient { + return &SamplingManagerClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewSamplingManagerClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *SamplingManagerClient { + return &SamplingManagerClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// Parameters: +// - ServiceName +func (p *SamplingManagerClient) GetSamplingStrategy(serviceName string) (r *SamplingStrategyResponse, err error) { + if err = p.sendGetSamplingStrategy(serviceName); err != nil { + return + } + return p.recvGetSamplingStrategy() +} + +func (p *SamplingManagerClient) sendGetSamplingStrategy(serviceName string) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("getSamplingStrategy", thrift.CALL, p.SeqId); err != nil { + return + } + args := SamplingManagerGetSamplingStrategyArgs{ + ServiceName: serviceName, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +func (p *SamplingManagerClient) recvGetSamplingStrategy() (value *SamplingStrategyResponse, err error) { + iprot := p.InputProtocol + if iprot == nil { + iprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.InputProtocol = iprot + } + method, mTypeId, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return + } + if method != "getSamplingStrategy" { + err = thrift.NewTApplicationException(thrift.WRONG_METHOD_NAME, "getSamplingStrategy failed: wrong method name") + return + } + if p.SeqId != seqId { + err = thrift.NewTApplicationException(thrift.BAD_SEQUENCE_ID, "getSamplingStrategy failed: out of sequence response") + return + } + if mTypeId == thrift.EXCEPTION { + error1 := thrift.NewTApplicationException(thrift.UNKNOWN_APPLICATION_EXCEPTION, "Unknown Exception") + var error2 error + error2, err = error1.Read(iprot) + if err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + err = error2 + return + } + if mTypeId != thrift.REPLY { + err = thrift.NewTApplicationException(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, "getSamplingStrategy failed: invalid message type") + return + } + result := SamplingManagerGetSamplingStrategyResult{} + if err = result.Read(iprot); err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + value = result.GetSuccess() + return +} + +type SamplingManagerProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler SamplingManager +} + +func (p *SamplingManagerProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *SamplingManagerProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *SamplingManagerProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewSamplingManagerProcessor(handler SamplingManager) *SamplingManagerProcessor { + + self3 := &SamplingManagerProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self3.processorMap["getSamplingStrategy"] = &samplingManagerProcessorGetSamplingStrategy{handler: handler} + return self3 +} + +func (p *SamplingManagerProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x4 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x4.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x4 + +} + +type samplingManagerProcessorGetSamplingStrategy struct { + handler SamplingManager +} + +func (p *samplingManagerProcessorGetSamplingStrategy) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := SamplingManagerGetSamplingStrategyArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("getSamplingStrategy", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, err + } + + iprot.ReadMessageEnd() + result := SamplingManagerGetSamplingStrategyResult{} + var retval *SamplingStrategyResponse + var err2 error + if retval, err2 = p.handler.GetSamplingStrategy(args.ServiceName); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing getSamplingStrategy: "+err2.Error()) + oprot.WriteMessageBegin("getSamplingStrategy", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("getSamplingStrategy", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - ServiceName +type SamplingManagerGetSamplingStrategyArgs struct { + ServiceName string `thrift:"serviceName,1" json:"serviceName"` +} + +func NewSamplingManagerGetSamplingStrategyArgs() *SamplingManagerGetSamplingStrategyArgs { + return &SamplingManagerGetSamplingStrategyArgs{} +} + +func (p *SamplingManagerGetSamplingStrategyArgs) GetServiceName() string { + return p.ServiceName +} +func (p *SamplingManagerGetSamplingStrategyArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.ServiceName = v + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getSamplingStrategy_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("serviceName", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:serviceName: ", p), err) + } + if err := oprot.WriteString(string(p.ServiceName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.serviceName (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:serviceName: ", p), err) + } + return err +} + +func (p *SamplingManagerGetSamplingStrategyArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingManagerGetSamplingStrategyArgs(%+v)", *p) +} + +// Attributes: +// - Success +type SamplingManagerGetSamplingStrategyResult struct { + Success *SamplingStrategyResponse `thrift:"success,0" json:"success,omitempty"` +} + +func NewSamplingManagerGetSamplingStrategyResult() *SamplingManagerGetSamplingStrategyResult { + return &SamplingManagerGetSamplingStrategyResult{} +} + +var SamplingManagerGetSamplingStrategyResult_Success_DEFAULT *SamplingStrategyResponse + +func (p *SamplingManagerGetSamplingStrategyResult) GetSuccess() *SamplingStrategyResponse { + if !p.IsSetSuccess() { + return SamplingManagerGetSamplingStrategyResult_Success_DEFAULT + } + return p.Success +} +func (p *SamplingManagerGetSamplingStrategyResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 0: + if err := p.readField0(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) readField0(iprot thrift.TProtocol) error { + p.Success = &SamplingStrategyResponse{} + if err := p.Success.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Success), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getSamplingStrategy_result"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField0(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err := oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err) + } + if err := p.Success.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Success), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err) + } + } + return err +} + +func (p *SamplingManagerGetSamplingStrategyResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingManagerGetSamplingStrategyResult(%+v)", *p) +} diff --git a/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/tchan-sampling.go b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/tchan-sampling.go new file mode 100644 index 00000000000..203b3049dee --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/tchan-sampling.go @@ -0,0 +1,105 @@ +// @generated Code generated by thrift-gen. Do not modify. + +// Package sampling is generated code used to make or handle TChannel calls using Thrift. +package sampling + +import ( + "fmt" + + athrift "github.com/apache/thrift/lib/go/thrift" + "github.com/uber/tchannel-go/thrift" +) + +// Interfaces for the service and client for the services defined in the IDL. + +// TChanSamplingManager is the interface that defines the server handler and client interface. +type TChanSamplingManager interface { + GetSamplingStrategy(ctx thrift.Context, serviceName string) (*SamplingStrategyResponse, error) +} + +// Implementation of a client and service handler. + +type tchanSamplingManagerClient struct { + thriftService string + client thrift.TChanClient +} + +func NewTChanSamplingManagerInheritedClient(thriftService string, client thrift.TChanClient) *tchanSamplingManagerClient { + return &tchanSamplingManagerClient{ + thriftService, + client, + } +} + +// NewTChanSamplingManagerClient creates a client that can be used to make remote calls. +func NewTChanSamplingManagerClient(client thrift.TChanClient) TChanSamplingManager { + return NewTChanSamplingManagerInheritedClient("SamplingManager", client) +} + +func (c *tchanSamplingManagerClient) GetSamplingStrategy(ctx thrift.Context, serviceName string) (*SamplingStrategyResponse, error) { + var resp SamplingManagerGetSamplingStrategyResult + args := SamplingManagerGetSamplingStrategyArgs{ + ServiceName: serviceName, + } + success, err := c.client.Call(ctx, c.thriftService, "getSamplingStrategy", &args, &resp) + if err == nil && !success { + switch { + default: + err = fmt.Errorf("received no result or unknown exception for getSamplingStrategy") + } + } + + return resp.GetSuccess(), err +} + +type tchanSamplingManagerServer struct { + handler TChanSamplingManager +} + +// NewTChanSamplingManagerServer wraps a handler for TChanSamplingManager so it can be +// registered with a thrift.Server. +func NewTChanSamplingManagerServer(handler TChanSamplingManager) thrift.TChanServer { + return &tchanSamplingManagerServer{ + handler, + } +} + +func (s *tchanSamplingManagerServer) Service() string { + return "SamplingManager" +} + +func (s *tchanSamplingManagerServer) Methods() []string { + return []string{ + "getSamplingStrategy", + } +} + +func (s *tchanSamplingManagerServer) Handle(ctx thrift.Context, methodName string, protocol athrift.TProtocol) (bool, athrift.TStruct, error) { + switch methodName { + case "getSamplingStrategy": + return s.handleGetSamplingStrategy(ctx, protocol) + + default: + return false, nil, fmt.Errorf("method %v not found in service %v", methodName, s.Service()) + } +} + +func (s *tchanSamplingManagerServer) handleGetSamplingStrategy(ctx thrift.Context, protocol athrift.TProtocol) (bool, athrift.TStruct, error) { + var req SamplingManagerGetSamplingStrategyArgs + var res SamplingManagerGetSamplingStrategyResult + + if err := req.Read(protocol); err != nil { + return false, nil, err + } + + r, err := + s.handler.GetSamplingStrategy(ctx, req.ServiceName) + + if err != nil { + return false, nil, err + } else { + res.Success = r + } + + return err == nil, &res, nil +} diff --git a/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/ttypes.go b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/ttypes.go new file mode 100644 index 00000000000..490c4b07dcd --- /dev/null +++ b/vendor/github.com/jaegertracing/jaeger/thrift-gen/sampling/ttypes.go @@ -0,0 +1,874 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + + "github.com/apache/thrift/lib/go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var GoUnusedProtection__ int + +type SamplingStrategyType int64 + +const ( + SamplingStrategyType_PROBABILISTIC SamplingStrategyType = 0 + SamplingStrategyType_RATE_LIMITING SamplingStrategyType = 1 +) + +func (p SamplingStrategyType) String() string { + switch p { + case SamplingStrategyType_PROBABILISTIC: + return "PROBABILISTIC" + case SamplingStrategyType_RATE_LIMITING: + return "RATE_LIMITING" + } + return "" +} + +func SamplingStrategyTypeFromString(s string) (SamplingStrategyType, error) { + switch s { + case "PROBABILISTIC": + return SamplingStrategyType_PROBABILISTIC, nil + case "RATE_LIMITING": + return SamplingStrategyType_RATE_LIMITING, nil + } + return SamplingStrategyType(0), fmt.Errorf("not a valid SamplingStrategyType string") +} + +func SamplingStrategyTypePtr(v SamplingStrategyType) *SamplingStrategyType { return &v } + +func (p SamplingStrategyType) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *SamplingStrategyType) UnmarshalText(text []byte) error { + q, err := SamplingStrategyTypeFromString(string(text)) + if err != nil { + return err + } + *p = q + return nil +} + +// Attributes: +// - SamplingRate +type ProbabilisticSamplingStrategy struct { + SamplingRate float64 `thrift:"samplingRate,1,required" json:"samplingRate"` +} + +func NewProbabilisticSamplingStrategy() *ProbabilisticSamplingStrategy { + return &ProbabilisticSamplingStrategy{} +} + +func (p *ProbabilisticSamplingStrategy) GetSamplingRate() float64 { + return p.SamplingRate +} +func (p *ProbabilisticSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetSamplingRate bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetSamplingRate = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetSamplingRate { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field SamplingRate is not set")) + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.SamplingRate = v + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("ProbabilisticSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("samplingRate", thrift.DOUBLE, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:samplingRate: ", p), err) + } + if err := oprot.WriteDouble(float64(p.SamplingRate)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.samplingRate (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:samplingRate: ", p), err) + } + return err +} + +func (p *ProbabilisticSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("ProbabilisticSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - MaxTracesPerSecond +type RateLimitingSamplingStrategy struct { + MaxTracesPerSecond int16 `thrift:"maxTracesPerSecond,1,required" json:"maxTracesPerSecond"` +} + +func NewRateLimitingSamplingStrategy() *RateLimitingSamplingStrategy { + return &RateLimitingSamplingStrategy{} +} + +func (p *RateLimitingSamplingStrategy) GetMaxTracesPerSecond() int16 { + return p.MaxTracesPerSecond +} +func (p *RateLimitingSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetMaxTracesPerSecond bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetMaxTracesPerSecond = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetMaxTracesPerSecond { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field MaxTracesPerSecond is not set")) + } + return nil +} + +func (p *RateLimitingSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.MaxTracesPerSecond = v + } + return nil +} + +func (p *RateLimitingSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("RateLimitingSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *RateLimitingSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("maxTracesPerSecond", thrift.I16, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:maxTracesPerSecond: ", p), err) + } + if err := oprot.WriteI16(int16(p.MaxTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.maxTracesPerSecond (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:maxTracesPerSecond: ", p), err) + } + return err +} + +func (p *RateLimitingSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("RateLimitingSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - Operation +// - ProbabilisticSampling +type OperationSamplingStrategy struct { + Operation string `thrift:"operation,1,required" json:"operation"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `thrift:"probabilisticSampling,2,required" json:"probabilisticSampling"` +} + +func NewOperationSamplingStrategy() *OperationSamplingStrategy { + return &OperationSamplingStrategy{} +} + +func (p *OperationSamplingStrategy) GetOperation() string { + return p.Operation +} + +var OperationSamplingStrategy_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy + +func (p *OperationSamplingStrategy) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if !p.IsSetProbabilisticSampling() { + return OperationSamplingStrategy_ProbabilisticSampling_DEFAULT + } + return p.ProbabilisticSampling +} +func (p *OperationSamplingStrategy) IsSetProbabilisticSampling() bool { + return p.ProbabilisticSampling != nil +} + +func (p *OperationSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetOperation bool = false + var issetProbabilisticSampling bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetOperation = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetProbabilisticSampling = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetOperation { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Operation is not set")) + } + if !issetProbabilisticSampling { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field ProbabilisticSampling is not set")) + } + return nil +} + +func (p *OperationSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Operation = v + } + return nil +} + +func (p *OperationSamplingStrategy) readField2(iprot thrift.TProtocol) error { + p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + if err := p.ProbabilisticSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err) + } + return nil +} + +func (p *OperationSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("OperationSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *OperationSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("operation", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:operation: ", p), err) + } + if err := oprot.WriteString(string(p.Operation)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.operation (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:operation: ", p), err) + } + return err +} + +func (p *OperationSamplingStrategy) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err) + } + if err := p.ProbabilisticSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err) + } + return err +} + +func (p *OperationSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("OperationSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - DefaultSamplingProbability +// - DefaultLowerBoundTracesPerSecond +// - PerOperationStrategies +// - DefaultUpperBoundTracesPerSecond +type PerOperationSamplingStrategies struct { + DefaultSamplingProbability float64 `thrift:"defaultSamplingProbability,1,required" json:"defaultSamplingProbability"` + DefaultLowerBoundTracesPerSecond float64 `thrift:"defaultLowerBoundTracesPerSecond,2,required" json:"defaultLowerBoundTracesPerSecond"` + PerOperationStrategies []*OperationSamplingStrategy `thrift:"perOperationStrategies,3,required" json:"perOperationStrategies"` + DefaultUpperBoundTracesPerSecond *float64 `thrift:"defaultUpperBoundTracesPerSecond,4" json:"defaultUpperBoundTracesPerSecond,omitempty"` +} + +func NewPerOperationSamplingStrategies() *PerOperationSamplingStrategies { + return &PerOperationSamplingStrategies{} +} + +func (p *PerOperationSamplingStrategies) GetDefaultSamplingProbability() float64 { + return p.DefaultSamplingProbability +} + +func (p *PerOperationSamplingStrategies) GetDefaultLowerBoundTracesPerSecond() float64 { + return p.DefaultLowerBoundTracesPerSecond +} + +func (p *PerOperationSamplingStrategies) GetPerOperationStrategies() []*OperationSamplingStrategy { + return p.PerOperationStrategies +} + +var PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT float64 + +func (p *PerOperationSamplingStrategies) GetDefaultUpperBoundTracesPerSecond() float64 { + if !p.IsSetDefaultUpperBoundTracesPerSecond() { + return PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT + } + return *p.DefaultUpperBoundTracesPerSecond +} +func (p *PerOperationSamplingStrategies) IsSetDefaultUpperBoundTracesPerSecond() bool { + return p.DefaultUpperBoundTracesPerSecond != nil +} + +func (p *PerOperationSamplingStrategies) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetDefaultSamplingProbability bool = false + var issetDefaultLowerBoundTracesPerSecond bool = false + var issetPerOperationStrategies bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetDefaultSamplingProbability = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetDefaultLowerBoundTracesPerSecond = true + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + issetPerOperationStrategies = true + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetDefaultSamplingProbability { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultSamplingProbability is not set")) + } + if !issetDefaultLowerBoundTracesPerSecond { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultLowerBoundTracesPerSecond is not set")) + } + if !issetPerOperationStrategies { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field PerOperationStrategies is not set")) + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.DefaultSamplingProbability = v + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.DefaultLowerBoundTracesPerSecond = v + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField3(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*OperationSamplingStrategy, 0, size) + p.PerOperationStrategies = tSlice + for i := 0; i < size; i++ { + _elem0 := &OperationSamplingStrategy{} + if err := _elem0.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem0), err) + } + p.PerOperationStrategies = append(p.PerOperationStrategies, _elem0) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.DefaultUpperBoundTracesPerSecond = &v + } + return nil +} + +func (p *PerOperationSamplingStrategies) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("PerOperationSamplingStrategies"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *PerOperationSamplingStrategies) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("defaultSamplingProbability", thrift.DOUBLE, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:defaultSamplingProbability: ", p), err) + } + if err := oprot.WriteDouble(float64(p.DefaultSamplingProbability)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultSamplingProbability (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:defaultSamplingProbability: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("defaultLowerBoundTracesPerSecond", thrift.DOUBLE, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:defaultLowerBoundTracesPerSecond: ", p), err) + } + if err := oprot.WriteDouble(float64(p.DefaultLowerBoundTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultLowerBoundTracesPerSecond (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:defaultLowerBoundTracesPerSecond: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("perOperationStrategies", thrift.LIST, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:perOperationStrategies: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.PerOperationStrategies)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.PerOperationStrategies { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:perOperationStrategies: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetDefaultUpperBoundTracesPerSecond() { + if err := oprot.WriteFieldBegin("defaultUpperBoundTracesPerSecond", thrift.DOUBLE, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:defaultUpperBoundTracesPerSecond: ", p), err) + } + if err := oprot.WriteDouble(float64(*p.DefaultUpperBoundTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultUpperBoundTracesPerSecond (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:defaultUpperBoundTracesPerSecond: ", p), err) + } + } + return err +} + +func (p *PerOperationSamplingStrategies) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PerOperationSamplingStrategies(%+v)", *p) +} + +// Attributes: +// - StrategyType +// - ProbabilisticSampling +// - RateLimitingSampling +// - OperationSampling +type SamplingStrategyResponse struct { + StrategyType SamplingStrategyType `thrift:"strategyType,1,required" json:"strategyType"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `thrift:"probabilisticSampling,2" json:"probabilisticSampling,omitempty"` + RateLimitingSampling *RateLimitingSamplingStrategy `thrift:"rateLimitingSampling,3" json:"rateLimitingSampling,omitempty"` + OperationSampling *PerOperationSamplingStrategies `thrift:"operationSampling,4" json:"operationSampling,omitempty"` +} + +func NewSamplingStrategyResponse() *SamplingStrategyResponse { + return &SamplingStrategyResponse{} +} + +func (p *SamplingStrategyResponse) GetStrategyType() SamplingStrategyType { + return p.StrategyType +} + +var SamplingStrategyResponse_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy + +func (p *SamplingStrategyResponse) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if !p.IsSetProbabilisticSampling() { + return SamplingStrategyResponse_ProbabilisticSampling_DEFAULT + } + return p.ProbabilisticSampling +} + +var SamplingStrategyResponse_RateLimitingSampling_DEFAULT *RateLimitingSamplingStrategy + +func (p *SamplingStrategyResponse) GetRateLimitingSampling() *RateLimitingSamplingStrategy { + if !p.IsSetRateLimitingSampling() { + return SamplingStrategyResponse_RateLimitingSampling_DEFAULT + } + return p.RateLimitingSampling +} + +var SamplingStrategyResponse_OperationSampling_DEFAULT *PerOperationSamplingStrategies + +func (p *SamplingStrategyResponse) GetOperationSampling() *PerOperationSamplingStrategies { + if !p.IsSetOperationSampling() { + return SamplingStrategyResponse_OperationSampling_DEFAULT + } + return p.OperationSampling +} +func (p *SamplingStrategyResponse) IsSetProbabilisticSampling() bool { + return p.ProbabilisticSampling != nil +} + +func (p *SamplingStrategyResponse) IsSetRateLimitingSampling() bool { + return p.RateLimitingSampling != nil +} + +func (p *SamplingStrategyResponse) IsSetOperationSampling() bool { + return p.OperationSampling != nil +} + +func (p *SamplingStrategyResponse) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetStrategyType bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetStrategyType = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetStrategyType { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field StrategyType is not set")) + } + return nil +} + +func (p *SamplingStrategyResponse) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + temp := SamplingStrategyType(v) + p.StrategyType = temp + } + return nil +} + +func (p *SamplingStrategyResponse) readField2(iprot thrift.TProtocol) error { + p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + if err := p.ProbabilisticSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) readField3(iprot thrift.TProtocol) error { + p.RateLimitingSampling = &RateLimitingSamplingStrategy{} + if err := p.RateLimitingSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.RateLimitingSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) readField4(iprot thrift.TProtocol) error { + p.OperationSampling = &PerOperationSamplingStrategies{} + if err := p.OperationSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.OperationSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("SamplingStrategyResponse"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingStrategyResponse) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("strategyType", thrift.I32, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:strategyType: ", p), err) + } + if err := oprot.WriteI32(int32(p.StrategyType)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.strategyType (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:strategyType: ", p), err) + } + return err +} + +func (p *SamplingStrategyResponse) writeField2(oprot thrift.TProtocol) (err error) { + if p.IsSetProbabilisticSampling() { + if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err) + } + if err := p.ProbabilisticSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) writeField3(oprot thrift.TProtocol) (err error) { + if p.IsSetRateLimitingSampling() { + if err := oprot.WriteFieldBegin("rateLimitingSampling", thrift.STRUCT, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:rateLimitingSampling: ", p), err) + } + if err := p.RateLimitingSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.RateLimitingSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:rateLimitingSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetOperationSampling() { + if err := oprot.WriteFieldBegin("operationSampling", thrift.STRUCT, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:operationSampling: ", p), err) + } + if err := p.OperationSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.OperationSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:operationSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingStrategyResponse(%+v)", *p) +} diff --git a/vendor/github.com/open-telemetry/opentelemetry-collector/consumer/consumer.go b/vendor/github.com/open-telemetry/opentelemetry-collector/consumer/consumer.go new file mode 100644 index 00000000000..14a16cf17e7 --- /dev/null +++ b/vendor/github.com/open-telemetry/opentelemetry-collector/consumer/consumer.go @@ -0,0 +1,38 @@ +// Copyright 2019, OpenTelemetry 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 consumer contains interfaces that receive and process consumerdata. +package consumer + +import ( + "context" + + "github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata" +) + +// MetricsConsumer is an interface that receives consumerdata.MetricsData, process it as needed, and +// sends it to the next processing node if any or to the destination. +// +// ConsumeMetricsData receives consumerdata.MetricsData for processing by the MetricsConsumer. +type MetricsConsumer interface { + ConsumeMetricsData(ctx context.Context, md consumerdata.MetricsData) error +} + +// TraceConsumer is an interface that receives consumerdata.TraceData, process it as needed, and +// sends it to the next processing node if any or to the destination. +// +// ConsumeTraceData receives consumerdata.TraceData for processing by the TraceConsumer. +type TraceConsumer interface { + ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error +} diff --git a/vendor/vendor.json b/vendor/vendor.json index bc7d61cbad4..52e01742e74 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -2222,24 +2222,44 @@ "revisionTime": "2019-12-11T13:27:55Z" }, { - "checksumSHA1": "J868MJ0VKbQZigstZT/i/PH8zrE=", + "checksumSHA1": "lD2sda8Zs3N17TQNnn5yMistY0Q=", "path": "github.com/jaegertracing/jaeger/model", - "revision": "e4b97b38c4785d9a593483241f0a1d3abe007e1c", - "revisionTime": "2019-11-30T19:27:31Z" + "revision": "1c315785dddc80a39637c2b08b0a9bbe9ab1536c", + "revisionTime": "2019-12-17T11:29:57Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" }, { - "checksumSHA1": "lHuUnLE5USvuwdMJcbXlSWbWB4M=", + "checksumSHA1": "jVQeChfPIzcnAv/TO2ZcIsxwFDU=", + "path": "github.com/jaegertracing/jaeger/model/converter/thrift/jaeger", + "revision": "1c315785dddc80a39637c2b08b0a9bbe9ab1536c", + "revisionTime": "2019-12-17T11:29:57Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "AtckiRr6VaRoISvPbzVz5JzyOkI=", "path": "github.com/jaegertracing/jaeger/proto-gen/api_v2", - "revision": "8c89e641eacafc5315de3c6486d398d6ce0d441c", - "revisionTime": "2019-11-07T23:45:29Z", - "version": "v1.15", - "versionExact": "v1.15.1" + "revision": "1c315785dddc80a39637c2b08b0a9bbe9ab1536c", + "revisionTime": "2019-12-17T11:29:57Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" }, { "checksumSHA1": "AtRTOBopYXf/LJolCbPPa4hmUiM=", "path": "github.com/jaegertracing/jaeger/thrift-gen/jaeger", - "revision": "e4b97b38c4785d9a593483241f0a1d3abe007e1c", - "revisionTime": "2019-11-30T19:27:31Z" + "revision": "1c315785dddc80a39637c2b08b0a9bbe9ab1536c", + "revisionTime": "2019-12-17T11:29:57Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" + }, + { + "checksumSHA1": "MGHjV0xTRHqHac1GtcxUppuPFLE=", + "path": "github.com/jaegertracing/jaeger/thrift-gen/sampling", + "revision": "1c315785dddc80a39637c2b08b0a9bbe9ab1536c", + "revisionTime": "2019-12-17T11:29:57Z", + "version": "v1.16.0", + "versionExact": "v1.16.0" }, { "checksumSHA1": "fPE6hs5I61ZEXc54kkSoFaafqOk=", @@ -2525,6 +2545,14 @@ "revision": "9377a265898fd8318dc67cf37aac27ffb327c2e1", "revisionTime": "2019-12-11T13:27:55Z" }, + { + "checksumSHA1": "//ZjXT6POCFpH5T5LO5teeNdCvo=", + "path": "github.com/open-telemetry/opentelemetry-collector/consumer", + "revision": "c300f13417023e53ddb643b312e6559899b54ac7", + "revisionTime": "2019-12-18T18:22:25Z", + "version": "master", + "versionExact": "master" + }, { "checksumSHA1": "AxRGGTFSZ/tDJAA3ggVLyK7BezU=", "path": "github.com/open-telemetry/opentelemetry-collector/consumer/consumerdata", @@ -2844,6 +2872,12 @@ "revision": "858f37ff9bc48070cde7f2c2895dbe0db1ad9326", "revisionTime": "2019-12-19T14:10:44Z" }, + { + "checksumSHA1": "ZE+byoICO3nIHzeHRc7EQ85hLu4=", + "path": "github.com/stretchr/testify/suite", + "revision": "41d0ae8564c694926432378eec30c1d35e926fb6", + "revisionTime": "2019-12-12T17:09:15Z" + }, { "checksumSHA1": "X6WTt1wvfs59cC1Dr9WxDmitfnE=", "path": "github.com/t-yuki/gocover-cobertura", @@ -2954,6 +2988,14 @@ "version": "v1.7.0", "versionExact": "v1.7.0" }, + { + "checksumSHA1": "3YhQhpZAqSMHPxWk1nIDJTzJMM0=", + "path": "go.elastic.co/apm/apmtest", + "revision": "d66d9b5ecaba855dbd3acc4bebfb6d495e0b5837", + "revisionTime": "2019-11-18T01:19:44Z", + "version": "v1.6.0", + "versionExact": "v1.6.0" + }, { "checksumSHA1": "k47GkPJ3iWtd4Fy5M/4vT7afxNE=", "path": "go.elastic.co/apm/internal/apmcontext", @@ -3106,6 +3148,14 @@ "version": "v1.7.0", "versionExact": "v1.7.0" }, + { + "checksumSHA1": "M2+F+/52KqvfgU7HNh7u0fm9oCg=", + "path": "go.elastic.co/apm/transport/transporttest", + "revision": "d66d9b5ecaba855dbd3acc4bebfb6d495e0b5837", + "revisionTime": "2019-11-18T01:19:44Z", + "version": "v1.6.0", + "versionExact": "v1.6.0" + }, { "checksumSHA1": "ou8/GMlWF1EShL3NuomgkrmDwb0=", "origin": "go.elastic.co/apm/vendor/go.elastic.co/fastjson",