From 967071c7f09dca4a8e08a5df5f4044c67b66775d Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 26 Jul 2021 18:04:52 -0700 Subject: [PATCH] Enabel tracez z-pages from otel-go, disable opencensus (#3698) Signed-off-by: Bogdan Drutu --- extension/zpagesextension/zpagesextension.go | 2 - .../zpagesextension/zpagesextension_test.go | 18 ++++++++- go.mod | 2 + go.sum | 4 ++ service/collector.go | 34 ++++++++++------ service/collector_test.go | 3 +- service/internal/otel_trace_sampler.go | 39 +++++++++++++++++++ service/service.go | 29 +++++++------- service/settings.go | 8 ++++ service/zpages.go | 8 ++++ 10 files changed, 118 insertions(+), 29 deletions(-) create mode 100644 service/internal/otel_trace_sampler.go diff --git a/extension/zpagesextension/zpagesextension.go b/extension/zpagesextension/zpagesextension.go index 8f8a616e29d..d4b741dde00 100644 --- a/extension/zpagesextension/zpagesextension.go +++ b/extension/zpagesextension/zpagesextension.go @@ -18,7 +18,6 @@ import ( "context" "net/http" - "go.opencensus.io/zpages" "go.uber.org/zap" "go.opentelemetry.io/collector/component" @@ -33,7 +32,6 @@ type zpagesExtension struct { func (zpe *zpagesExtension) Start(_ context.Context, host component.Host) error { zPagesMux := http.NewServeMux() - zpages.Handle(zPagesMux, "/debug") hostZPages, ok := host.(interface { RegisterZPages(mux *http.ServeMux, pathPrefix string) diff --git a/extension/zpagesextension/zpagesextension_test.go b/extension/zpagesextension/zpagesextension_test.go index fe06ce77471..fb3d376b162 100644 --- a/extension/zpagesextension/zpagesextension_test.go +++ b/extension/zpagesextension/zpagesextension_test.go @@ -18,17 +18,33 @@ import ( "context" "net" "net/http" + "path" "runtime" "testing" "github.com/stretchr/testify/require" "go.uber.org/zap" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/testutil" ) +type zpagesHost struct { + component.Host +} + +func newZPagesHost() *zpagesHost { + return &zpagesHost{Host: componenttest.NewNopHost()} +} + +func (*zpagesHost) RegisterZPages(mux *http.ServeMux, pathPrefix string) { + mux.HandleFunc(path.Join(pathPrefix, "tracez"), func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) +} + func TestZPagesExtensionUsage(t *testing.T) { cfg := &Config{ TCPAddr: confignet.TCPAddr{ @@ -39,7 +55,7 @@ func TestZPagesExtensionUsage(t *testing.T) { zpagesExt := newServer(cfg, zap.NewNop()) require.NotNil(t, zpagesExt) - require.NoError(t, zpagesExt.Start(context.Background(), componenttest.NewNopHost())) + require.NoError(t, zpagesExt.Start(context.Background(), newZPagesHost())) t.Cleanup(func() { require.NoError(t, zpagesExt.Shutdown(context.Background())) }) // Give a chance for the server goroutine to run. diff --git a/go.mod b/go.mod index f7d12addcc4..86bd5609d6b 100644 --- a/go.mod +++ b/go.mod @@ -49,8 +49,10 @@ require ( go.opentelemetry.io/collector/model v0.30.1 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.21.0 + go.opentelemetry.io/contrib/zpages v0.0.0-20210722161726-7668016acb73 // indirect go.opentelemetry.io/otel v1.0.0-RC1 go.opentelemetry.io/otel/oteltest v1.0.0-RC1 + go.opentelemetry.io/otel/sdk v1.0.0-RC1 go.opentelemetry.io/otel/trace v1.0.0-RC1 go.uber.org/atomic v1.9.0 go.uber.org/zap v1.18.1 diff --git a/go.sum b/go.sum index fd58ea81e0c..9326cf3f554 100644 --- a/go.sum +++ b/go.sum @@ -1246,6 +1246,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0/go.mod h1:Vm5u/mtkj1OMhtao0v+BGo2LUoLCgHYXvRmj0jWITlE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.21.0 h1:G1vNyNfKknFvrKVC8ga8EYIECy0s5D/QPW4QPRSMhwc= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.21.0/go.mod h1:JQAtechjxLEL81EjmbRwxBq/XEzGaHcsPuDHAx54hg4= +go.opentelemetry.io/contrib/zpages v0.0.0-20210722161726-7668016acb73 h1:PiFJH3VOaYus2l1ogMKKMoCNXhNjaEhYTe+88s1E3pI= +go.opentelemetry.io/contrib/zpages v0.0.0-20210722161726-7668016acb73/go.mod h1:NAkejuYm41lpyL43Fu1XdnCOYxN5NVV80/MJ03JQ/X8= go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc= go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= go.opentelemetry.io/otel/internal/metric v0.21.0 h1:gZlIBo5O51hZOOZz8vEcuRx/l5dnADadKfpT70AELoo= @@ -1254,6 +1256,8 @@ go.opentelemetry.io/otel/metric v0.21.0 h1:ZtcJlHqVE4l8Su0WOLOd9fEPheJuYEiQ0wr9w go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc= go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk= go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= +go.opentelemetry.io/otel/sdk v1.0.0-RC1 h1:Sy2VLOOg24bipyC29PhuMXYNJrLsxkie8hyI7kUlG9Q= +go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58= go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= diff --git a/service/collector.go b/service/collector.go index d99e30e73d2..a55db285367 100644 --- a/service/collector.go +++ b/service/collector.go @@ -27,6 +27,9 @@ import ( "syscall" "github.com/spf13/cobra" + "go.opentelemetry.io/contrib/zpages" + "go.opentelemetry.io/otel" + sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.uber.org/zap" "go.opentelemetry.io/collector/component" @@ -37,16 +40,11 @@ import ( "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/extension/ballastextension" "go.opentelemetry.io/collector/internal/collector/telemetry" + "go.opentelemetry.io/collector/service/internal" "go.opentelemetry.io/collector/service/internal/builder" "go.opentelemetry.io/collector/service/parserprovider" ) -const ( - servicezPath = "servicez" - pipelinezPath = "pipelinez" - extensionzPath = "extensionz" -) - // State defines Collector's state. type State int @@ -74,6 +72,9 @@ type Collector struct { rootCmd *cobra.Command logger *zap.Logger + tracerProvider *sdktrace.TracerProvider + zPagesSpanProcessor *zpages.SpanProcessor + service *service stateChannel chan State @@ -117,6 +118,15 @@ func New(set CollectorSettings) (*Collector, error) { return fmt.Errorf("failed to get logger: %w", err) } + col.zPagesSpanProcessor = zpages.NewSpanProcessor() + col.tracerProvider = sdktrace.NewTracerProvider( + sdktrace.WithSampler(internal.AlwaysRecord()), + sdktrace.WithSpanProcessor(col.zPagesSpanProcessor)) + + // Set the constructed tracer provider as Global, in case any component uses the + // global TracerProvider. + otel.SetTracerProvider(col.tracerProvider) + return col.execute(cmd.Context()) }, } @@ -241,11 +251,13 @@ func (col *Collector) setupConfigurationComponents(ctx context.Context) error { col.logger.Info("Applying configuration...") service, err := newService(&svcSettings{ - BuildInfo: col.info, - Factories: col.factories, - Config: cfg, - Logger: col.logger, - AsyncErrorChannel: col.asyncErrorChannel, + BuildInfo: col.info, + Factories: col.factories, + Config: cfg, + Logger: col.logger, + TracerProvider: col.tracerProvider, + ZPagesSpanProcessor: col.zPagesSpanProcessor, + AsyncErrorChannel: col.asyncErrorChannel, }) if err != nil { return err diff --git a/service/collector_test.go b/service/collector_test.go index 83d7f7c3d83..2125d92a360 100644 --- a/service/collector_test.go +++ b/service/collector_test.go @@ -222,7 +222,8 @@ func assertMetrics(t *testing.T, prefix string, metricsPort uint16, mandatoryLab func assertZPages(t *testing.T) { paths := []string{ "/debug/tracez", - "/debug/rpcz", + // TODO: enable this when otel-metrics is used and this page is available. + // "/debug/rpcz", "/debug/pipelinez", "/debug/servicez", "/debug/extensionz", diff --git a/service/internal/otel_trace_sampler.go b/service/internal/otel_trace_sampler.go new file mode 100644 index 00000000000..15141bee7b4 --- /dev/null +++ b/service/internal/otel_trace_sampler.go @@ -0,0 +1,39 @@ +// Copyright The 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 internal + +import ( + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +type recordSampler struct{} + +func (r recordSampler) ShouldSample(parameters sdktrace.SamplingParameters) sdktrace.SamplingResult { + return sdktrace.SamplingResult{Decision: sdktrace.RecordOnly} +} + +func (r recordSampler) Description() string { + return "Always record sampler" +} + +func AlwaysRecord() sdktrace.Sampler { + rs := &recordSampler{} + return sdktrace.ParentBased( + rs, + sdktrace.WithRemoteParentSampled(sdktrace.AlwaysSample()), + sdktrace.WithRemoteParentNotSampled(rs), + sdktrace.WithLocalParentSampled(sdktrace.AlwaysSample()), + sdktrace.WithRemoteParentSampled(rs)) +} diff --git a/service/service.go b/service/service.go index 91b1eb1e784..de08cc615ff 100644 --- a/service/service.go +++ b/service/service.go @@ -18,7 +18,7 @@ import ( "context" "fmt" - "go.opentelemetry.io/otel" + "go.opentelemetry.io/contrib/zpages" "go.opentelemetry.io/otel/trace" "go.uber.org/zap" @@ -30,12 +30,13 @@ import ( // service represents the implementation of a component.Host. type service struct { - factories component.Factories - buildInfo component.BuildInfo - config *config.Config - logger *zap.Logger - tracerProvider trace.TracerProvider - asyncErrorChannel chan error + factories component.Factories + buildInfo component.BuildInfo + config *config.Config + logger *zap.Logger + tracerProvider trace.TracerProvider + zPagesSpanProcessor *zpages.SpanProcessor + asyncErrorChannel chan error builtExporters builder.Exporters builtReceivers builder.Receivers @@ -45,13 +46,13 @@ type service struct { func newService(set *svcSettings) (*service, error) { srv := &service{ - factories: set.Factories, - buildInfo: set.BuildInfo, - config: set.Config, - logger: set.Logger, - // TODO: Configure the right tracer provider. - tracerProvider: otel.GetTracerProvider(), - asyncErrorChannel: set.AsyncErrorChannel, + factories: set.Factories, + buildInfo: set.BuildInfo, + config: set.Config, + logger: set.Logger, + tracerProvider: set.TracerProvider, + zPagesSpanProcessor: set.ZPagesSpanProcessor, + asyncErrorChannel: set.AsyncErrorChannel, } if err := srv.config.Validate(); err != nil { diff --git a/service/settings.go b/service/settings.go index bb66914b464..ff9363005fd 100644 --- a/service/settings.go +++ b/service/settings.go @@ -15,6 +15,8 @@ package service import ( + "go.opentelemetry.io/contrib/zpages" + sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.uber.org/zap" "go.opentelemetry.io/collector/component" @@ -36,6 +38,12 @@ type svcSettings struct { // Logger represents the logger used for all the components. Logger *zap.Logger + // TracerProvider represents the TracerProvider used for all the components. + TracerProvider *sdktrace.TracerProvider + + // ZPagesSpanProcessor represents the SpanProcessor for tracez page. + ZPagesSpanProcessor *zpages.SpanProcessor + // AsyncErrorChannel is the channel that is used to report fatal errors. AsyncErrorChannel chan error } diff --git a/service/zpages.go b/service/zpages.go index c89a7d11479..928e239d855 100644 --- a/service/zpages.go +++ b/service/zpages.go @@ -19,12 +19,19 @@ import ( "path" "sort" + otelzpages "go.opentelemetry.io/contrib/zpages" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/internal/version" "go.opentelemetry.io/collector/service/internal/zpages" ) const ( + tracezPath = "tracez" + servicezPath = "servicez" + pipelinezPath = "pipelinez" + extensionzPath = "extensionz" + zPipelineName = "zpipelinename" zComponentName = "zcomponentname" zComponentKind = "zcomponentkind" @@ -32,6 +39,7 @@ const ( ) func (srv *service) RegisterZPages(mux *http.ServeMux, pathPrefix string) { + mux.Handle(path.Join(pathPrefix, tracezPath), otelzpages.NewTracezHandler(srv.zPagesSpanProcessor)) mux.HandleFunc(path.Join(pathPrefix, servicezPath), srv.handleServicezRequest) mux.HandleFunc(path.Join(pathPrefix, pipelinezPath), srv.handlePipelinezRequest) mux.HandleFunc(path.Join(pathPrefix, extensionzPath), func(w http.ResponseWriter, r *http.Request) {