Component(s)
Most OTel Collector components
Add a description
In the last two upgrades it was noted that most OTel components we wrap start from a "zero" config with no defaults applied. This can cause problems during upgrades when new fields are introduced and instead of us inheriting an upstream default we inject a "zero" value resulting in unexpected behavior.
We should invert all of these so that we start from upstream defaults and override based on our exposed configuration. Doing this isn't a small task I did use AI to research and group these for us to start,
Group 1: pure no-ops (7)
Upstream createDefaultConfig returns &Config{}, so seeding changes nothing. No goldens move. Cheapest way to establish the pattern.
| Component |
Convert() |
otelcol.auth.basic |
auth/basic/basic.go:112 |
otelcol.auth.headers |
auth/headers/headers.go:50 |
otelcol.auth.sigv4 |
auth/sigv4/sigv4.go:46 |
otelcol.processor.attributes |
processor/attributes/attributes.go:62 |
otelcol.processor.redaction |
processor/redaction/redaction.go:157 |
otelcol.processor.span |
processor/span/span.go:81 |
otelcol.receiver.fluentforward |
receiver/fluentforward/fluentforward.go:63 |
Group 2: one-line seed (7)
Already build into a named var, so the fix is one line at the top.
mapstructure.Decode into a zero struct, identical shape to the #6842 k8sattributes fix:
| Component |
Convert() |
otelcol.exporter.kafka |
exporter/kafka/kafka.go:276 |
otelcol.receiver.kafka |
receiver/kafka/kafka.go:207 |
otelcol.receiver.vcenter |
receiver/vcenter/vcenter.go:404 |
var result X.Config + field assignment:
| Component |
Convert() |
Note |
otelcol.exporter.googlecloud |
exporter/googlecloud/googlecloud.go:66 |
half-done: seeds embedded collector.DefaultConfig() and hardcodes the factory's 12s timeout, but never calls the exporter factory default |
otelcol.exporter.googlecloudpubsub |
exporter/googlecloudpubsub/googlecloudpubsub.go:71 |
|
otelcol.processor.cumulativetodelta |
processor/cumulativetodelta/cumulativetodelta.go:109 |
|
otelcol.receiver.file_stats |
receiver/file_stats/types_convert.go:18 |
|
Group 3: small struct literals (19)
Flat upstream configs, 4 or fewer default fields. Batchable 4-6 per PR by kind.
| Component |
Convert() |
otelcol.auth.bearer |
auth/bearer/bearer.go:64 |
otelcol.auth.google |
auth/google/google.go:81 |
otelcol.connector.signaltometrics |
connector/signaltometrics/signaltometrics.go:75 |
otelcol.exporter.faro |
exporter/faro/faro.go:48 |
otelcol.exporter.loadbalancing |
exporter/loadbalancing/loadbalancing.go:123 |
otelcol.exporter.otlp |
exporter/otlp/otlp.go:62 |
otelcol.exporter.otlphttp |
exporter/otlphttp/otlphttp.go:73 |
otelcol.processor.batch |
processor/batch/batch.go:74 |
otelcol.processor.deltatocumulative |
processor/deltatocumulative/deltatocumulative.go:79 |
otelcol.processor.groupbyattrs |
processor/groupbyattrs/groupbyattrs.go:59 |
otelcol.processor.interval |
processor/interval/interval.go:79 |
otelcol.processor.metric_start_time |
processor/metricstarttime/metricstarttime.go:85 |
otelcol.processor.probabilistic_sampler |
processor/probabilistic_sampler/probabilistic_sampler.go:78 |
otelcol.receiver.awsecscontainermetrics |
receiver/awsecscontainermetrics/awsecscontainermetrics.go:52 |
otelcol.receiver.cloudflare |
receiver/cloudflare/cloudflare.go:77 |
otelcol.receiver.faro |
receiver/faro/faro.go:57 |
otelcol.receiver.googlecloudpubsub |
receiver/googlecloudpubsub/googlecloudpubsub.go:98 |
otelcol.receiver.influxdb |
receiver/influxdb/influxdb.go:63 |
otelcol.receiver.zipkin |
receiver/zipkin/zipkin.go:58 |
Group 4: large / nested struct literals (13)
configoptional wrappers, pointer sub-structs, feature-gate-dependent values, side-effecting default helpers. One PR each.
| Component |
Convert() |
Landmine |
otelcol.connector.count |
connector/count/count.go:119 |
|
otelcol.connector.servicegraph |
connector/servicegraph/servicegraph.go:151 |
|
otelcol.connector.spanmetrics |
connector/spanmetrics/spanmetrics.go:190 |
Histogram unit default reads a feature gate |
otelcol.exporter.datadog |
exporter/datadog/datadog.go:89 |
default is datadogconfig.CreateDefaultConfig(), deeply nested |
otelcol.exporter.file |
exporter/file/file.go:138 |
Rotation / GroupBy pointer sub-structs |
otelcol.exporter.splunkhec |
exporter/splunkhec/config/splunkhec.go:266 |
20 default fields |
otelcol.exporter.syslog |
exporter/syslog/syslog.go:72 |
|
otelcol.extension.jaeger_remote_sampling |
extension/jaeger_remote_sampling/jaeger_remote_sampling.go:82 |
vendored in-tree copy, so the factory is ours |
otelcol.receiver.datadog |
receiver/datadog/datadog.go:119 |
nested Intake / Proxy |
otelcol.receiver.jaeger |
receiver/jaeger/jaeger.go:68 |
protocols wrapped in configoptional |
otelcol.receiver.otlp |
receiver/otlp/otlp.go:87 |
protocols wrapped in configoptional |
otelcol.receiver.solace |
receiver/solace/solace.go:129 |
Flow wrapped in configoptional |
otelcol.storage.file |
storage/file/file.go:199 |
default calls getDefaultDirectory() |
Group 5: behavior fixes (6)
Upstream default sets a non-zero field that Alloy never assigns and doesn't expose, so these already run differently from the collector. Each needs a release note. Two of them need a new Alloy argument, not just a seeded default.
| Component |
Convert() |
Divergence |
otelcol.exporter.awss3 |
exporter/awss3/awss3.go:76 |
BackOffConfig zero-valued vs configretry.NewDefaultBackOffConfig(); no retry_on_failure block exists |
otelcol.exporter.debug |
exporter/debug/debug.go:76 |
QueueConfig zero-valued vs configoptional.Default(NewDefaultQueueConfig()); no sending_queue block exists |
otelcol.processor.memory_limiter |
processor/memorylimiter/memorylimiter.go:101 |
MinGCIntervalWhenSoftLimited is 0 vs 10s |
otelcol.processor.resourcedetection |
processor/resourcedetection/resourcedetection.go:281 |
ClientConfig never referenced anywhere in the component vs defaultClientConfig() |
otelcol.receiver.splunkhec |
receiver/splunkhec/splunkhec.go:135 |
Ack.Path is "" vs /services/collector/ack |
otelcol.receiver.awscloudwatch |
receiver/awscloudwatch/awscloudwatch.go:66 |
whole Metrics block zeroed (ControllerConfig, Period, Delay). Confirm inert before writing up: Alloy only exposes logs |
Tip
React with 👍 if this issue is important to you.
Component(s)
Most OTel Collector components
Add a description
In the last two upgrades it was noted that most OTel components we wrap start from a "zero" config with no defaults applied. This can cause problems during upgrades when new fields are introduced and instead of us inheriting an upstream default we inject a "zero" value resulting in unexpected behavior.
We should invert all of these so that we start from upstream defaults and override based on our exposed configuration. Doing this isn't a small task I did use AI to research and group these for us to start,
Group 1: pure no-ops (7)
Upstream
createDefaultConfigreturns&Config{}, so seeding changes nothing. No goldens move. Cheapest way to establish the pattern.Convert()otelcol.auth.basicauth/basic/basic.go:112otelcol.auth.headersauth/headers/headers.go:50otelcol.auth.sigv4auth/sigv4/sigv4.go:46otelcol.processor.attributesprocessor/attributes/attributes.go:62otelcol.processor.redactionprocessor/redaction/redaction.go:157otelcol.processor.spanprocessor/span/span.go:81otelcol.receiver.fluentforwardreceiver/fluentforward/fluentforward.go:63Group 2: one-line seed (7)
Already build into a named var, so the fix is one line at the top.
mapstructure.Decodeinto a zero struct, identical shape to the #6842 k8sattributes fix:Convert()otelcol.exporter.kafkaexporter/kafka/kafka.go:276otelcol.receiver.kafkareceiver/kafka/kafka.go:207otelcol.receiver.vcenterreceiver/vcenter/vcenter.go:404var result X.Config+ field assignment:Convert()otelcol.exporter.googlecloudexporter/googlecloud/googlecloud.go:66collector.DefaultConfig()and hardcodes the factory's 12s timeout, but never calls the exporter factory defaultotelcol.exporter.googlecloudpubsubexporter/googlecloudpubsub/googlecloudpubsub.go:71otelcol.processor.cumulativetodeltaprocessor/cumulativetodelta/cumulativetodelta.go:109otelcol.receiver.file_statsreceiver/file_stats/types_convert.go:18Group 3: small struct literals (19)
Flat upstream configs, 4 or fewer default fields. Batchable 4-6 per PR by kind.
Convert()otelcol.auth.bearerauth/bearer/bearer.go:64otelcol.auth.googleauth/google/google.go:81otelcol.connector.signaltometricsconnector/signaltometrics/signaltometrics.go:75otelcol.exporter.faroexporter/faro/faro.go:48otelcol.exporter.loadbalancingexporter/loadbalancing/loadbalancing.go:123otelcol.exporter.otlpexporter/otlp/otlp.go:62otelcol.exporter.otlphttpexporter/otlphttp/otlphttp.go:73otelcol.processor.batchprocessor/batch/batch.go:74otelcol.processor.deltatocumulativeprocessor/deltatocumulative/deltatocumulative.go:79otelcol.processor.groupbyattrsprocessor/groupbyattrs/groupbyattrs.go:59otelcol.processor.intervalprocessor/interval/interval.go:79otelcol.processor.metric_start_timeprocessor/metricstarttime/metricstarttime.go:85otelcol.processor.probabilistic_samplerprocessor/probabilistic_sampler/probabilistic_sampler.go:78otelcol.receiver.awsecscontainermetricsreceiver/awsecscontainermetrics/awsecscontainermetrics.go:52otelcol.receiver.cloudflarereceiver/cloudflare/cloudflare.go:77otelcol.receiver.faroreceiver/faro/faro.go:57otelcol.receiver.googlecloudpubsubreceiver/googlecloudpubsub/googlecloudpubsub.go:98otelcol.receiver.influxdbreceiver/influxdb/influxdb.go:63otelcol.receiver.zipkinreceiver/zipkin/zipkin.go:58Group 4: large / nested struct literals (13)
configoptionalwrappers, pointer sub-structs, feature-gate-dependent values, side-effecting default helpers. One PR each.Convert()otelcol.connector.countconnector/count/count.go:119otelcol.connector.servicegraphconnector/servicegraph/servicegraph.go:151otelcol.connector.spanmetricsconnector/spanmetrics/spanmetrics.go:190otelcol.exporter.datadogexporter/datadog/datadog.go:89datadogconfig.CreateDefaultConfig(), deeply nestedotelcol.exporter.fileexporter/file/file.go:138Rotation/GroupBypointer sub-structsotelcol.exporter.splunkhecexporter/splunkhec/config/splunkhec.go:266otelcol.exporter.syslogexporter/syslog/syslog.go:72otelcol.extension.jaeger_remote_samplingextension/jaeger_remote_sampling/jaeger_remote_sampling.go:82otelcol.receiver.datadogreceiver/datadog/datadog.go:119Intake/Proxyotelcol.receiver.jaegerreceiver/jaeger/jaeger.go:68configoptionalotelcol.receiver.otlpreceiver/otlp/otlp.go:87configoptionalotelcol.receiver.solacereceiver/solace/solace.go:129Flowwrapped inconfigoptionalotelcol.storage.filestorage/file/file.go:199getDefaultDirectory()Group 5: behavior fixes (6)
Upstream default sets a non-zero field that Alloy never assigns and doesn't expose, so these already run differently from the collector. Each needs a release note. Two of them need a new Alloy argument, not just a seeded default.
Convert()otelcol.exporter.awss3exporter/awss3/awss3.go:76BackOffConfigzero-valued vsconfigretry.NewDefaultBackOffConfig(); noretry_on_failureblock existsotelcol.exporter.debugexporter/debug/debug.go:76QueueConfigzero-valued vsconfigoptional.Default(NewDefaultQueueConfig()); nosending_queueblock existsotelcol.processor.memory_limiterprocessor/memorylimiter/memorylimiter.go:101MinGCIntervalWhenSoftLimitedis 0 vs 10sotelcol.processor.resourcedetectionprocessor/resourcedetection/resourcedetection.go:281ClientConfignever referenced anywhere in the component vsdefaultClientConfig()otelcol.receiver.splunkhecreceiver/splunkhec/splunkhec.go:135Ack.Pathis""vs/services/collector/ackotelcol.receiver.awscloudwatchreceiver/awscloudwatch/awscloudwatch.go:66Metricsblock zeroed (ControllerConfig,Period,Delay). Confirm inert before writing up: Alloy only exposes logsTip
React with 👍 if this issue is important to you.