From d668979fc13ae119b0006134baa5bbe5d9bfd9b8 Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:00:22 -0300 Subject: [PATCH 1/3] Checking if the endpoint is down when connecting --- e2e/basic/basic.go | 7 +++--- e2e/basic/go.mod | 1 + e2e/basic/go.sum | 3 +++ trace/exporter.go | 55 +++++++++++++++++++++++++++++++++++++----- trace/exporter_test.go | 7 ++++-- trace/provider.go | 3 +-- 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/e2e/basic/basic.go b/e2e/basic/basic.go index 66ef354..cef7e22 100644 --- a/e2e/basic/basic.go +++ b/e2e/basic/basic.go @@ -12,6 +12,7 @@ import ( "github.com/TykTechnologies/opentelemetry/config" "github.com/TykTechnologies/opentelemetry/trace" + "github.com/sirupsen/logrus" "go.opentelemetry.io/otel/attribute" ) @@ -21,15 +22,15 @@ func main() { cfg := config.OpenTelemetry{ Enabled: true, - Exporter: "grpc", - Endpoint: "otel-collector:4317", + Exporter: "http", + Endpoint: "localhost:4318", ConnectionTimeout: 10, ResourceName: "e2e-basic", } log.Println("Initializing OpenTelemetry at e2e-basic:", cfg.Endpoint) - provider, err := trace.NewProvider(trace.WithContext(ctx), trace.WithConfig(&cfg)) + provider, err := trace.NewProvider(trace.WithContext(ctx), trace.WithConfig(&cfg), trace.WithLogger(logrus.New())) if err != nil { log.Printf("error on otel provider init %s", err.Error()) return diff --git a/e2e/basic/go.mod b/e2e/basic/go.mod index ed63521..e1fa8b0 100644 --- a/e2e/basic/go.mod +++ b/e2e/basic/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/TykTechnologies/opentelemetry v0.0.0-20230627083938-06db14948ffe + github.com/sirupsen/logrus v1.9.3 go.opentelemetry.io/otel v1.16.0 ) diff --git a/e2e/basic/go.sum b/e2e/basic/go.sum index 2d7da24..e0f38bc 100644 --- a/e2e/basic/go.sum +++ b/e2e/basic/go.sum @@ -53,6 +53,7 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -146,6 +147,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -288,6 +290,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/trace/exporter.go b/trace/exporter.go index fce3e56..483ae6c 100644 --- a/trace/exporter.go +++ b/trace/exporter.go @@ -3,6 +3,9 @@ package trace import ( "context" "fmt" + "net" + "net/http" + "strings" "time" "github.com/TykTechnologies/opentelemetry/config" @@ -13,24 +16,44 @@ import ( sdktrace "go.opentelemetry.io/otel/sdk/trace" ) -func exporterFactory(ctx context.Context, cfg *config.OpenTelemetry) (sdktrace.SpanExporter, error) { +func exporterFactory(ctx context.Context, provider *traceProvider) (sdktrace.SpanExporter, error) { var client otlptrace.Client - switch cfg.Exporter { + switch provider.cfg.Exporter { case config.GRPCEXPORTER: - client = newGRPCClient(ctx, cfg) + client = newGRPCClient(ctx, provider.cfg) + + if !isGRPCEndpointActive(provider.cfg.Endpoint) { + provider.logger.Error("GRPC endpoint: ", provider.cfg.Endpoint, " is down") + } case config.HTTPEXPORTER: - client = newHTTPClient(ctx, cfg) + client = newHTTPClient(ctx, provider.cfg) + + if !isHTTPEndpointActive(provider.cfg.Endpoint) { + provider.logger.Error("HTTP endpoint: ", provider.cfg.Endpoint, " is down") + } default: - return nil, fmt.Errorf("invalid exporter type: %s", cfg.Exporter) + return nil, fmt.Errorf("invalid exporter type: %s", provider.cfg.Exporter) } - ctx, cancel := context.WithTimeout(ctx, time.Duration(cfg.ConnectionTimeout)*time.Second) + ctx, cancel := context.WithTimeout(ctx, time.Duration(provider.cfg.ConnectionTimeout)*time.Second) defer cancel() // Create the trace exporter return otlptrace.New(ctx, client) } +func isGRPCEndpointActive(endpoint string) bool { + conn, err := net.DialTimeout("tcp", endpoint, time.Second) + + if err != nil { + return false + } + + conn.Close() + + return true +} + func newGRPCClient(ctx context.Context, cfg *config.OpenTelemetry) otlptrace.Client { return otlptracegrpc.NewClient( otlptracegrpc.WithEndpoint(cfg.Endpoint), @@ -39,6 +62,26 @@ func newGRPCClient(ctx context.Context, cfg *config.OpenTelemetry) otlptrace.Cli ) } +func isHTTPEndpointActive(endpoint string) bool { + client := http.Client{ + Timeout: time.Second, + } + + // Check if the endpoint has a protocol scheme (http/https), if not, append one + if !strings.HasPrefix(strings.ToLower(endpoint), "http") { + endpoint = "http://" + endpoint + } + + // Using Head method to avoid downloading the whole body + req, err := http.NewRequestWithContext(context.Background(), http.MethodHead, endpoint, nil) + if err != nil { + return false + } + + _, err = client.Do(req) + return err == nil +} + func newHTTPClient(ctx context.Context, cfg *config.OpenTelemetry) otlptrace.Client { return otlptracehttp.NewClient( otlptracehttp.WithEndpoint(cfg.Endpoint), diff --git a/trace/exporter_test.go b/trace/exporter_test.go index bcfb204..85ab7d2 100644 --- a/trace/exporter_test.go +++ b/trace/exporter_test.go @@ -109,8 +109,11 @@ func Test_ExporterFactory(t *testing.T) { tc.givenConfig.Endpoint = endpoint } - - exporter, err := exporterFactory(ctx, tc.givenConfig) + provider := &traceProvider{ + cfg: tc.givenConfig, + logger: &mockLogger{}, + } + exporter, err := exporterFactory(ctx, provider) if tc.expectedErr != nil { assert.NotNil(t, err) assert.Equal(t, tc.expectedErr.Error(), err.Error()) diff --git a/trace/provider.go b/trace/provider.go index 6c0f335..7dbb990 100644 --- a/trace/provider.go +++ b/trace/provider.go @@ -90,7 +90,7 @@ func NewProvider(opts ...Option) (Provider, error) { } // create the exporter - here's where connecting to the collector happens - exporter, err := exporterFactory(provider.ctx, provider.cfg) + exporter, err := exporterFactory(provider.ctx, provider) if err != nil { provider.logger.Error("failed to create exporter", err) return provider, fmt.Errorf("failed to create exporter: %w", err) @@ -128,7 +128,6 @@ func NewProvider(opts ...Option) (Provider, error) { }) provider.logger.Info("Tracer provider initialized successfully") - return provider, nil } From 5799eb457f8f5d0f5570af5e67428429ecc9a2cb Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:01:55 -0300 Subject: [PATCH 2/3] restoring basic.go file --- e2e/basic/basic.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/basic/basic.go b/e2e/basic/basic.go index cef7e22..96f45bc 100644 --- a/e2e/basic/basic.go +++ b/e2e/basic/basic.go @@ -22,8 +22,8 @@ func main() { cfg := config.OpenTelemetry{ Enabled: true, - Exporter: "http", - Endpoint: "localhost:4318", + Exporter: "grpc", + Endpoint: "localhost:4317", ConnectionTimeout: 10, ResourceName: "e2e-basic", } From 721fe9078848aa91045ab046224ff42eedab5dc8 Mon Sep 17 00:00:00 2001 From: Matias <83959431+mativm02@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:06:06 -0300 Subject: [PATCH 3/3] linting --- trace/exporter.go | 1 + 1 file changed, 1 insertion(+) diff --git a/trace/exporter.go b/trace/exporter.go index 483ae6c..ba2ae56 100644 --- a/trace/exporter.go +++ b/trace/exporter.go @@ -79,6 +79,7 @@ func isHTTPEndpointActive(endpoint string) bool { } _, err = client.Do(req) + return err == nil }