From d72869d11de716bc39af2c7a1cf84baceaf88115 Mon Sep 17 00:00:00 2001 From: Andrzej Stencel Date: Tue, 9 Apr 2024 11:04:05 +0200 Subject: [PATCH 1/5] [chore][exporter/debug] refactor code to make independent from Logging exporter This is in preparation to implement https://github.com/open-telemetry/opentelemetry-collector/issues/7806 (draft PR: https://github.com/open-telemetry/opentelemetry-collector/pull/9298). --- exporter/debugexporter/exporter.go | 83 ++++++++++++++++++++++++++++++ exporter/debugexporter/factory.go | 57 ++++++++++++++------ exporter/debugexporter/go.mod | 4 +- 3 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 exporter/debugexporter/exporter.go diff --git a/exporter/debugexporter/exporter.go b/exporter/debugexporter/exporter.go new file mode 100644 index 00000000000..e08ec46fefc --- /dev/null +++ b/exporter/debugexporter/exporter.go @@ -0,0 +1,83 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package debugexporter + +import ( + "context" + + "go.uber.org/zap" + + "go.opentelemetry.io/collector/config/configtelemetry" + "go.opentelemetry.io/collector/exporter/internal/otlptext" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" +) + +type debugExporter struct { + verbosity configtelemetry.Level + logger *zap.Logger + logsMarshaler plog.Marshaler + metricsMarshaler pmetric.Marshaler + tracesMarshaler ptrace.Marshaler +} + +func newDebugExporter(logger *zap.Logger, verbosity configtelemetry.Level) *debugExporter { + return &debugExporter{ + verbosity: verbosity, + logger: logger, + logsMarshaler: otlptext.NewTextLogsMarshaler(), + metricsMarshaler: otlptext.NewTextMetricsMarshaler(), + tracesMarshaler: otlptext.NewTextTracesMarshaler(), + } +} + +func (s *debugExporter) pushTraces(_ context.Context, td ptrace.Traces) error { + s.logger.Info("TracesExporter", + zap.Int("resource spans", td.ResourceSpans().Len()), + zap.Int("spans", td.SpanCount())) + if s.verbosity != configtelemetry.LevelDetailed { + return nil + } + + buf, err := s.tracesMarshaler.MarshalTraces(td) + if err != nil { + return err + } + s.logger.Info(string(buf)) + return nil +} + +func (s *debugExporter) pushMetrics(_ context.Context, md pmetric.Metrics) error { + s.logger.Info("MetricsExporter", + zap.Int("resource metrics", md.ResourceMetrics().Len()), + zap.Int("metrics", md.MetricCount()), + zap.Int("data points", md.DataPointCount())) + if s.verbosity != configtelemetry.LevelDetailed { + return nil + } + + buf, err := s.metricsMarshaler.MarshalMetrics(md) + if err != nil { + return err + } + s.logger.Info(string(buf)) + return nil +} + +func (s *debugExporter) pushLogs(_ context.Context, ld plog.Logs) error { + s.logger.Info("LogsExporter", + zap.Int("resource logs", ld.ResourceLogs().Len()), + zap.Int("log records", ld.LogRecordCount())) + if s.verbosity != configtelemetry.LevelDetailed { + return nil + } + + buf, err := s.logsMarshaler.MarshalLogs(ld) + if err != nil { + return err + } + s.logger.Info(string(buf)) + return nil +} diff --git a/exporter/debugexporter/factory.go b/exporter/debugexporter/factory.go index e9e75130dd6..f0f6ae8ed62 100644 --- a/exporter/debugexporter/factory.go +++ b/exporter/debugexporter/factory.go @@ -5,12 +5,17 @@ package debugexporter // import "go.opentelemetry.io/collector/exporter/debugexp import ( "context" + "time" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" + "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter" "go.opentelemetry.io/collector/exporter/debugexporter/internal/metadata" - "go.opentelemetry.io/collector/exporter/internal/common" + "go.opentelemetry.io/collector/exporter/exporterhelper" + "go.opentelemetry.io/collector/exporter/internal/otlptext" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) // The value of "type" key in configuration. @@ -42,27 +47,47 @@ func createDefaultConfig() component.Config { func createTracesExporter(ctx context.Context, set exporter.CreateSettings, config component.Config) (exporter.Traces, error) { cfg := config.(*Config) - return common.CreateTracesExporter(ctx, set, config, &common.Common{ - Verbosity: cfg.Verbosity, - SamplingInitial: cfg.SamplingInitial, - SamplingThereafter: cfg.SamplingThereafter, - }) + exporterLogger := createLogger(cfg, set.TelemetrySettings.Logger) + debugExporter := newDebugExporter(exporterLogger, cfg.Verbosity) + return exporterhelper.NewTracesExporter(ctx, set, config, + debugExporter.pushTraces, + exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}), + exporterhelper.WithTimeout(exporterhelper.TimeoutSettings{Timeout: 0}), + exporterhelper.WithShutdown(otlptext.LoggerSync(exporterLogger)), + ) } func createMetricsExporter(ctx context.Context, set exporter.CreateSettings, config component.Config) (exporter.Metrics, error) { cfg := config.(*Config) - return common.CreateMetricsExporter(ctx, set, config, &common.Common{ - Verbosity: cfg.Verbosity, - SamplingInitial: cfg.SamplingInitial, - SamplingThereafter: cfg.SamplingThereafter, - }) + exporterLogger := createLogger(cfg, set.TelemetrySettings.Logger) + debugExporter := newDebugExporter(exporterLogger, cfg.Verbosity) + return exporterhelper.NewMetricsExporter(ctx, set, config, + debugExporter.pushMetrics, + exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}), + exporterhelper.WithTimeout(exporterhelper.TimeoutSettings{Timeout: 0}), + exporterhelper.WithShutdown(otlptext.LoggerSync(exporterLogger)), + ) } func createLogsExporter(ctx context.Context, set exporter.CreateSettings, config component.Config) (exporter.Logs, error) { cfg := config.(*Config) - return common.CreateLogsExporter(ctx, set, config, &common.Common{ - Verbosity: cfg.Verbosity, - SamplingInitial: cfg.SamplingInitial, - SamplingThereafter: cfg.SamplingThereafter, - }) + exporterLogger := createLogger(cfg, set.TelemetrySettings.Logger) + debugExporter := newDebugExporter(exporterLogger, cfg.Verbosity) + return exporterhelper.NewLogsExporter(ctx, set, config, + debugExporter.pushLogs, + exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}), + exporterhelper.WithTimeout(exporterhelper.TimeoutSettings{Timeout: 0}), + exporterhelper.WithShutdown(otlptext.LoggerSync(exporterLogger)), + ) +} + +func createLogger(cfg *Config, logger *zap.Logger) *zap.Logger { + core := zapcore.NewSamplerWithOptions( + logger.Core(), + 1*time.Second, + cfg.SamplingInitial, + cfg.SamplingThereafter, + ) + + return zap.New(core) } diff --git a/exporter/debugexporter/go.mod b/exporter/debugexporter/go.mod index 276754fc04a..2d3529c91c7 100644 --- a/exporter/debugexporter/go.mod +++ b/exporter/debugexporter/go.mod @@ -7,11 +7,13 @@ require ( go.opentelemetry.io/collector/component v0.97.0 go.opentelemetry.io/collector/config/configtelemetry v0.97.0 go.opentelemetry.io/collector/confmap v0.97.0 + go.opentelemetry.io/collector/consumer v0.97.0 go.opentelemetry.io/collector/exporter v0.97.0 go.opentelemetry.io/collector/pdata v1.4.0 go.opentelemetry.io/otel/metric v1.24.0 go.opentelemetry.io/otel/trace v1.24.0 go.uber.org/goleak v1.3.0 + go.uber.org/zap v1.27.0 ) require ( @@ -40,7 +42,6 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect go.opentelemetry.io/collector v0.97.0 // indirect go.opentelemetry.io/collector/config/configretry v0.97.0 // indirect - go.opentelemetry.io/collector/consumer v0.97.0 // indirect go.opentelemetry.io/collector/extension v0.97.0 // indirect go.opentelemetry.io/collector/receiver v0.97.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect @@ -48,7 +49,6 @@ require ( go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect From 804b55a4d77c0844bcd0120c27a16182e77d06b4 Mon Sep 17 00:00:00 2001 From: Andrzej Stencel Date: Tue, 9 Apr 2024 13:08:59 +0200 Subject: [PATCH 2/5] make goporto --- exporter/debugexporter/exporter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/debugexporter/exporter.go b/exporter/debugexporter/exporter.go index e08ec46fefc..53134b94014 100644 --- a/exporter/debugexporter/exporter.go +++ b/exporter/debugexporter/exporter.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package debugexporter +package debugexporter // import "go.opentelemetry.io/collector/exporter/debugexporter" import ( "context" From 651ae912fa3d99ddeae1bef7d1620b4e14f0fc4e Mon Sep 17 00:00:00 2001 From: Andrzej Stencel Date: Tue, 9 Apr 2024 13:12:07 +0200 Subject: [PATCH 3/5] make fmt --- exporter/debugexporter/factory.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/exporter/debugexporter/factory.go b/exporter/debugexporter/factory.go index f0f6ae8ed62..b91b1950f7e 100644 --- a/exporter/debugexporter/factory.go +++ b/exporter/debugexporter/factory.go @@ -7,6 +7,9 @@ import ( "context" "time" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/consumer" @@ -14,8 +17,6 @@ import ( "go.opentelemetry.io/collector/exporter/debugexporter/internal/metadata" "go.opentelemetry.io/collector/exporter/exporterhelper" "go.opentelemetry.io/collector/exporter/internal/otlptext" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" ) // The value of "type" key in configuration. From 8dce26b26d3d5d8fd5514552747d0c084b5fa504 Mon Sep 17 00:00:00 2001 From: Andrzej Stencel Date: Mon, 15 Apr 2024 13:12:36 +0200 Subject: [PATCH 4/5] add note on modifying similar code --- exporter/debugexporter/exporter.go | 4 ++++ exporter/internal/common/logging_exporter.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/exporter/debugexporter/exporter.go b/exporter/debugexporter/exporter.go index 53134b94014..191ac562563 100644 --- a/exporter/debugexporter/exporter.go +++ b/exporter/debugexporter/exporter.go @@ -1,6 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// NOTE: If you are making changes to this file, consider whether you want to make similar changes +// to the Logging exporter in /exporter/internal/common/logging_exporter.go, which has similar logic. +// This is especially important for security issues. + package debugexporter // import "go.opentelemetry.io/collector/exporter/debugexporter" import ( diff --git a/exporter/internal/common/logging_exporter.go b/exporter/internal/common/logging_exporter.go index 026018465f4..1dcdf000cdc 100644 --- a/exporter/internal/common/logging_exporter.go +++ b/exporter/internal/common/logging_exporter.go @@ -1,6 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +// NOTE: If you are making changes to this file, consider whether you want to make similar changes +// to the Debug exporter in /exporter/debug/exporter.go, which has similar logic. +// This is especially important for security issues. + package common // import "go.opentelemetry.io/collector/exporter/internal/common" import ( From 0db1fcd3ab2ad9c5e0d463665fcc3fcee678f69e Mon Sep 17 00:00:00 2001 From: Andrzej Stencel Date: Mon, 15 Apr 2024 13:14:15 +0200 Subject: [PATCH 5/5] fix path --- exporter/internal/common/logging_exporter.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/internal/common/logging_exporter.go b/exporter/internal/common/logging_exporter.go index 1dcdf000cdc..1d34f1f5620 100644 --- a/exporter/internal/common/logging_exporter.go +++ b/exporter/internal/common/logging_exporter.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 // NOTE: If you are making changes to this file, consider whether you want to make similar changes -// to the Debug exporter in /exporter/debug/exporter.go, which has similar logic. +// to the Debug exporter in /exporter/debugexporter/exporter.go, which has similar logic. // This is especially important for security issues. package common // import "go.opentelemetry.io/collector/exporter/internal/common"