mirror of
https://github.com/hanzoai/otel-collector.git
synced 2026-11-03 02:20:04 +00:00
- Go module: github.com/SigNoz/signoz-otel-collector → github.com/hanzoai/otel-collector - All signoz-prefixed packages → o11y-prefixed - Docker: signoz/* → ghcr.io/hanzoai/otel-collector - ClickHouse exporter → Hanzo Datastore - Env vars: SIGNOZ_* → HANZO_* - Directory renames for all processor/receiver/exporter packages
212 lines
6.9 KiB
Go
212 lines
6.9 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package o11ykafkaexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/kafkaexporter"
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/Shopify/sarama"
|
|
"go.opentelemetry.io/collector/component"
|
|
"go.opentelemetry.io/collector/config/configoptional"
|
|
"go.opentelemetry.io/collector/config/configretry"
|
|
"go.opentelemetry.io/collector/consumer"
|
|
"go.opentelemetry.io/collector/exporter"
|
|
"go.opentelemetry.io/collector/exporter/exporterhelper"
|
|
|
|
"github.com/hanzoai/otel-collector/exporter/o11ykafkaexporter/internal/metadata"
|
|
)
|
|
|
|
const (
|
|
defaultTracesTopic = "otlp_spans"
|
|
defaultMetricsTopic = "otlp_metrics"
|
|
defaultLogsTopic = "otlp_logs"
|
|
defaultEncoding = "otlp_proto"
|
|
defaultBroker = "localhost:9092"
|
|
// default from sarama.NewConfig()
|
|
defaultMetadataRetryMax = 3
|
|
// default from sarama.NewConfig()
|
|
defaultMetadataRetryBackoff = time.Millisecond * 250
|
|
// default from sarama.NewConfig()
|
|
defaultMetadataFull = true
|
|
// default max.message.bytes for the producer
|
|
defaultProducerMaxMessageBytes = 1000000
|
|
// default required_acks for the producer
|
|
defaultProducerRequiredAcks = sarama.WaitForLocal
|
|
// default from sarama.NewConfig()
|
|
defaultCompression = "none"
|
|
// default from sarama.NewConfig()
|
|
defaultFluxMaxMessages = 0
|
|
)
|
|
|
|
// FactoryOption applies changes to kafkaExporterFactory.
|
|
type FactoryOption func(factory *kafkaExporterFactory)
|
|
|
|
// WithTracesMarshalers adds tracesMarshalers.
|
|
func WithTracesMarshalers(tracesMarshalers ...TracesMarshaler) FactoryOption {
|
|
return func(factory *kafkaExporterFactory) {
|
|
for _, marshaler := range tracesMarshalers {
|
|
factory.tracesMarshalers[marshaler.Encoding()] = marshaler
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithMetricsMarshalers adds additional metric marshalers to the exporter factory.
|
|
func WithMetricsMarshalers(metricMarshalers ...MetricsMarshaler) FactoryOption {
|
|
return func(factory *kafkaExporterFactory) {
|
|
for _, marshaler := range metricMarshalers {
|
|
factory.metricsMarshalers[marshaler.Encoding()] = marshaler
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithLogMarshalers adds additional log marshalers to the exporter factory.
|
|
func WithLogsMarshalers(logsMarshalers ...LogsMarshaler) FactoryOption {
|
|
return func(factory *kafkaExporterFactory) {
|
|
for _, marshaler := range logsMarshalers {
|
|
factory.logsMarshalers[marshaler.Encoding()] = marshaler
|
|
}
|
|
}
|
|
}
|
|
|
|
// NewFactory creates Kafka exporter factory.
|
|
func NewFactory(options ...FactoryOption) exporter.Factory {
|
|
f := &kafkaExporterFactory{
|
|
tracesMarshalers: tracesMarshalers(),
|
|
metricsMarshalers: metricsMarshalers(),
|
|
logsMarshalers: logsMarshalers(),
|
|
}
|
|
for _, o := range options {
|
|
o(f)
|
|
}
|
|
return exporter.NewFactory(
|
|
metadata.Type,
|
|
createDefaultConfig,
|
|
exporter.WithTraces(f.createTracesExporter, metadata.TracesStability),
|
|
exporter.WithMetrics(f.createMetricsExporter, metadata.MetricsStability),
|
|
exporter.WithLogs(f.createLogsExporter, metadata.LogsStability),
|
|
)
|
|
}
|
|
|
|
func createDefaultConfig() component.Config {
|
|
return &Config{
|
|
TimeoutConfig: exporterhelper.NewDefaultTimeoutConfig(),
|
|
BackOffConfig: configretry.NewDefaultBackOffConfig(),
|
|
QueueBatchConfig: configoptional.Some(exporterhelper.NewDefaultQueueConfig()),
|
|
Brokers: []string{defaultBroker},
|
|
// using an empty topic to track when it has not been set by user, default is based on traces or metrics.
|
|
Topic: "",
|
|
Encoding: defaultEncoding,
|
|
Metadata: MetadataConfig{
|
|
Full: defaultMetadataFull,
|
|
Retry: MetadataRetryConfig{
|
|
Max: defaultMetadataRetryMax,
|
|
Backoff: defaultMetadataRetryBackoff,
|
|
},
|
|
},
|
|
Producer: Producer{
|
|
MaxMessageBytes: defaultProducerMaxMessageBytes,
|
|
RequiredAcks: defaultProducerRequiredAcks,
|
|
Compression: defaultCompression,
|
|
FlushMaxMessages: defaultFluxMaxMessages,
|
|
},
|
|
}
|
|
}
|
|
|
|
type kafkaExporterFactory struct {
|
|
tracesMarshalers map[string]TracesMarshaler
|
|
metricsMarshalers map[string]MetricsMarshaler
|
|
logsMarshalers map[string]LogsMarshaler
|
|
}
|
|
|
|
func (f *kafkaExporterFactory) createTracesExporter(
|
|
ctx context.Context,
|
|
set exporter.Settings,
|
|
cfg component.Config,
|
|
) (exporter.Traces, error) {
|
|
oCfg := *(cfg.(*Config)) // Clone the config
|
|
if oCfg.Topic == "" {
|
|
oCfg.Topic = defaultTracesTopic
|
|
}
|
|
if oCfg.Encoding == "otlp_json" {
|
|
set.Logger.Info("otlp_json is considered experimental and should not be used in a production environment")
|
|
}
|
|
exp, err := newTracesExporter(oCfg, set, f.tracesMarshalers)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return exporterhelper.NewTraces(
|
|
ctx,
|
|
set,
|
|
&oCfg,
|
|
exp.tracesPusher,
|
|
exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}),
|
|
// Disable exporterhelper Timeout, because we cannot pass a Context to the Producer,
|
|
// and will rely on the sarama Producer Timeout logic.
|
|
exporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: 0}),
|
|
exporterhelper.WithRetry(oCfg.BackOffConfig),
|
|
exporterhelper.WithQueue(oCfg.QueueBatchConfig),
|
|
exporterhelper.WithShutdown(exp.Close))
|
|
}
|
|
|
|
func (f *kafkaExporterFactory) createMetricsExporter(
|
|
ctx context.Context,
|
|
set exporter.Settings,
|
|
cfg component.Config,
|
|
) (exporter.Metrics, error) {
|
|
oCfg := *(cfg.(*Config)) // Clone the config
|
|
if oCfg.Topic == "" {
|
|
oCfg.Topic = defaultMetricsTopic
|
|
}
|
|
if oCfg.Encoding == "otlp_json" {
|
|
set.Logger.Info("otlp_json is considered experimental and should not be used in a production environment")
|
|
}
|
|
exp, err := newMetricsExporter(oCfg, set, f.metricsMarshalers)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return exporterhelper.NewMetrics(
|
|
ctx,
|
|
set,
|
|
&oCfg,
|
|
exp.metricsDataPusher,
|
|
exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}),
|
|
// Disable exporterhelper Timeout, because we cannot pass a Context to the Producer,
|
|
// and will rely on the sarama Producer Timeout logic.
|
|
exporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: 0}),
|
|
exporterhelper.WithRetry(oCfg.BackOffConfig),
|
|
exporterhelper.WithQueue(oCfg.QueueBatchConfig),
|
|
exporterhelper.WithShutdown(exp.Close))
|
|
}
|
|
|
|
func (f *kafkaExporterFactory) createLogsExporter(
|
|
ctx context.Context,
|
|
set exporter.Settings,
|
|
cfg component.Config,
|
|
) (exporter.Logs, error) {
|
|
oCfg := *(cfg.(*Config)) // Clone the config
|
|
if oCfg.Topic == "" {
|
|
oCfg.Topic = defaultLogsTopic
|
|
}
|
|
if oCfg.Encoding == "otlp_json" {
|
|
set.Logger.Info("otlp_json is considered experimental and should not be used in a production environment")
|
|
}
|
|
exp, err := newLogsExporter(oCfg, set, f.logsMarshalers)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return exporterhelper.NewLogs(
|
|
ctx,
|
|
set,
|
|
&oCfg,
|
|
exp.logsDataPusher,
|
|
exporterhelper.WithCapabilities(consumer.Capabilities{MutatesData: false}),
|
|
// Disable exporterhelper Timeout, because we cannot pass a Context to the Producer,
|
|
// and will rely on the sarama Producer Timeout logic.
|
|
exporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: 0}),
|
|
exporterhelper.WithRetry(oCfg.BackOffConfig),
|
|
exporterhelper.WithQueue(oCfg.QueueBatchConfig),
|
|
exporterhelper.WithShutdown(exp.Close))
|
|
}
|