diff --git a/collector/go.mod b/collector/go.mod index 538b94145b..1d2deaa8ec 100644 --- a/collector/go.mod +++ b/collector/go.mod @@ -33,7 +33,10 @@ require ( go.opentelemetry.io/collector/confmap/provider/httpprovider v1.56.0 go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.56.0 go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.56.0 + go.opentelemetry.io/collector/exporter/exportertest v0.150.0 go.opentelemetry.io/collector/otelcol v0.150.0 + go.opentelemetry.io/collector/receiver/receivertest v0.150.0 + go.opentelemetry.io/collector/service v0.150.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 ) @@ -202,7 +205,6 @@ require ( go.opentelemetry.io/collector/exporter/debugexporter v0.150.0 // indirect go.opentelemetry.io/collector/exporter/exporterhelper v0.150.0 // indirect go.opentelemetry.io/collector/exporter/exporterhelper/xexporterhelper v0.150.0 // indirect - go.opentelemetry.io/collector/exporter/exportertest v0.150.0 // indirect go.opentelemetry.io/collector/exporter/otlpexporter v0.150.0 // indirect go.opentelemetry.io/collector/exporter/otlphttpexporter v0.150.0 // indirect go.opentelemetry.io/collector/exporter/xexporter v0.150.0 // indirect @@ -234,10 +236,8 @@ require ( go.opentelemetry.io/collector/receiver v1.56.0 // indirect go.opentelemetry.io/collector/receiver/otlpreceiver v0.150.0 // indirect go.opentelemetry.io/collector/receiver/receiverhelper v0.150.0 // indirect - go.opentelemetry.io/collector/receiver/receivertest v0.150.0 // indirect go.opentelemetry.io/collector/receiver/xreceiver v0.150.0 // indirect go.opentelemetry.io/collector/semconv v0.128.0 // indirect - go.opentelemetry.io/collector/service v0.150.0 // indirect go.opentelemetry.io/collector/service/hostcapabilities v0.150.0 // indirect go.opentelemetry.io/contrib/bridges/otelzap v0.18.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 // indirect diff --git a/collector/internal/collector/collector.go b/collector/internal/collector/collector.go index 5f9ea03c7f..a6a6a02d5c 100644 --- a/collector/internal/collector/collector.go +++ b/collector/internal/collector/collector.go @@ -103,8 +103,18 @@ func (c *Collector) Start(ctx context.Context) error { Factories: func() (otelcol.Factories, error) { return c.factories, nil }, - LoggingOptions: []zap.Option{zap.WrapCore(func(_ zapcore.Core) zapcore.Core { - return c.logger.Core() + // TODO: fully decouple extension and collector log levels so that + // OPENTELEMETRY_EXTENSION_LOG_LEVEL only affects extension logs. + LoggingOptions: []zap.Option{zap.WrapCore(func(collectorCore zapcore.Core) zapcore.Core { + extensionCore := c.logger.Core() + if zapcore.LevelOf(collectorCore) == zapcore.InfoLevel { + return extensionCore + } + increased, err := zapcore.NewIncreaseLevelCore(extensionCore, collectorCore) + if err != nil { + return extensionCore + } + return increased })}, } var err error diff --git a/collector/internal/collector/collector_test.go b/collector/internal/collector/collector_test.go new file mode 100644 index 0000000000..8b8b169d04 --- /dev/null +++ b/collector/internal/collector/collector_test.go @@ -0,0 +1,63 @@ +// 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 collector + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/exporter/exportertest" + "go.opentelemetry.io/collector/otelcol" + "go.opentelemetry.io/collector/receiver/receivertest" + "go.opentelemetry.io/collector/service/telemetry/otelconftelemetry" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" +) + +func TestCollectorConfigLogLevelIsOverridden(t *testing.T) { + t.Setenv("OPENTELEMETRY_COLLECTOR_CONFIG_URI", "file:testdata/config-error-level.yaml") + + receivers, err := otelcol.MakeFactoryMap(receivertest.NewNopFactory()) + require.NoError(t, err) + exporters, err := otelcol.MakeFactoryMap(exportertest.NewNopFactory()) + require.NoError(t, err) + + factories := otelcol.Factories{ + Receivers: receivers, + Exporters: exporters, + Telemetry: otelconftelemetry.NewFactory(), + } + + // Use a nop logger so extension logs don't end up in our observer + collector := NewCollector(zap.NewNop(), factories, "test") + // Replace collector logger with an observed core at INFO level. + collectorObservedCore, collectorLogs := observer.New(zapcore.InfoLevel) + collector.logger = zap.New(collectorObservedCore) + + ctx := context.Background() + err = collector.Start(ctx) + require.NoError(t, err) + + err = collector.Stop() + require.NoError(t, err) + + // If the collector config log level is respected, there are no INFO logs + infoLogs := collectorLogs.FilterLevelExact(zapcore.InfoLevel).All() + assert.Empty(t, infoLogs, + "INFO logs from the collector should be suppressed when config sets level: error") +} diff --git a/collector/internal/collector/testdata/config-error-level.yaml b/collector/internal/collector/testdata/config-error-level.yaml new file mode 100644 index 0000000000..805dafe6c4 --- /dev/null +++ b/collector/internal/collector/testdata/config-error-level.yaml @@ -0,0 +1,14 @@ +receivers: + nop: + +exporters: + nop: + +service: + telemetry: + logs: + level: error + pipelines: + traces: + receivers: [nop] + exporters: [nop]