Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .chloggen/debugexporter-output-paths.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. receiver/otlp)
component: exporter/debug

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add `output_paths` configuration option to allow redirecting output when `use_internal_logger` is false

# One or more tracking issues or pull requests related to the change
issues: [10472]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
The `output_paths` option accepts an array of destinations (stdout, stderr, or file paths) and defaults to stdout.
This option can only be used when `use_internal_logger` is set to false.

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
3 changes: 2 additions & 1 deletion exporter/debugexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ The following settings are optional:
Refer to [Zap docs](https://godoc.org/go.uber.org/zap/zapcore#NewSampler) for more details
on how sampling parameters impact number of messages.
- `use_internal_logger` (default = `true`): uses the collector's internal logger for output. See [below](#using-the-collectors-internal-logger) for description.
- `output_paths` (default = `[stdout]` when `use_internal_logger` is `false`): list of destinations for the exporter's output when bypassing the collector logger. Accepts `stdout`, `stderr`, or filesystem paths supported by Zap.
- `sending_queue` (disabled by default): see [Sending Queue](../exporterhelper/README.md#sending-queue) for the full set of available options.

Example configuration:
Expand Down Expand Up @@ -138,7 +139,7 @@ This comes with the following consequences:

When `use_internal_logger` is set to `false`, the exporter does not use the collector's internal logger.
Changing the values in `service::telemetry::logs` has no effect on the exporter's output.
The exporter's output is sent to `stdout`.
The exporter's output is sent to `stdout` by default and can be redirected via `output_paths`.

[internal_telemetry]: https://opentelemetry.io/docs/collector/internal-telemetry/
[internal_logs_config]: https://opentelemetry.io/docs/collector/internal-telemetry/#configure-internal-logs
Expand Down
14 changes: 14 additions & 0 deletions exporter/debugexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
// UseInternalLogger defines whether the exporter sends the output to the collector's internal logger.
UseInternalLogger bool `mapstructure:"use_internal_logger"`

// OutputPaths holds the list of destinations for the exporter's output when UseInternalLogger is false.
OutputPaths []string `mapstructure:"output_paths"`

QueueConfig configoptional.Optional[exporterhelper.QueueBatchConfig] `mapstructure:"sending_queue"`

// prevent unkeyed literal initialization
Expand All @@ -48,5 +51,16 @@
return fmt.Errorf("verbosity level %q is not supported", cfg.Verbosity)
}

if len(cfg.OutputPaths) > 0 {
if cfg.UseInternalLogger {
return fmt.Errorf("output_paths requires use_internal_logger to be false")

Check failure on line 56 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / CodeQL-Build

error-format: fmt.Errorf can be replaced with errors.New (perfsprint)

Check failure on line 56 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / lint

error-format: fmt.Errorf can be replaced with errors.New (perfsprint)
}
for _, path := range cfg.OutputPaths {

Check failure on line 58 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / CodeQL-Build

slicescontains: Loop can be simplified using slices.Contains (modernize)

Check failure on line 58 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / lint

slicescontains: Loop can be simplified using slices.Contains (modernize)
if path == "" {
return fmt.Errorf("output_paths cannot contain empty values")

Check failure on line 60 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / CodeQL-Build

error-format: fmt.Errorf can be replaced with errors.New (perfsprint)

Check failure on line 60 in exporter/debugexporter/config.go

View workflow job for this annotation

GitHub Actions / lint

error-format: fmt.Errorf can be replaced with errors.New (perfsprint)
}
}
}

return nil
}
34 changes: 34 additions & 0 deletions exporter/debugexporter/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestUnmarshalConfig(t *testing.T) {
Verbosity: configtelemetry.LevelDetailed,
SamplingInitial: 10,
SamplingThereafter: 50,
OutputPaths: []string{"stderr"},
QueueConfig: configoptional.Default(queueCfg),
},
},
Expand Down Expand Up @@ -81,6 +82,16 @@ func Test_UnmarshalMarshalled(t *testing.T) {
Verbosity: configtelemetry.LevelDetailed,
},
},
"OutputPathsSpecified": {
inCfg: &Config{
UseInternalLogger: false,
OutputPaths: []string{"stderr"},
},
expectedConfig: &Config{
UseInternalLogger: false,
OutputPaths: []string{"stderr"},
},
},
} {
t.Run(name, func(t *testing.T) {
conf := confmap.New()
Expand Down Expand Up @@ -125,6 +136,29 @@ func TestValidate(t *testing.T) {
Verbosity: configtelemetry.LevelDetailed,
},
},
{
name: "output paths with internal logger",
cfg: &Config{
UseInternalLogger: true,
OutputPaths: []string{"stderr"},
},
expectedErr: "output_paths requires use_internal_logger to be false",
},
{
name: "output paths empty entry",
cfg: &Config{
UseInternalLogger: false,
OutputPaths: []string{""},
},
expectedErr: "output_paths cannot contain empty values",
},
{
name: "output paths valid",
cfg: &Config{
UseInternalLogger: false,
OutputPaths: []string{"stderr"},
},
},
}

for _, tt := range tests {
Expand Down
11 changes: 11 additions & 0 deletions exporter/debugexporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ func createTestCases() []testCase {
return cfg
}(),
},
{
name: "custom output paths",
config: func() *Config {
cfg := createDefaultConfig().(*Config)
cfg.QueueConfig = configoptional.Some(exporterhelper.NewDefaultQueueConfig())
cfg.QueueConfig.Get().QueueSize = 10
cfg.UseInternalLogger = false
cfg.OutputPaths = []string{"stderr"}
return cfg
}(),
},
}
}

Expand Down
8 changes: 6 additions & 2 deletions exporter/debugexporter/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ func createCustomLogger(exporterConfig *Config) *zap.Logger {
encoderConfig.LevelKey = ""
// Do not prefix the output with current timestamp.
encoderConfig.TimeKey = ""
outputPaths := exporterConfig.OutputPaths
if len(outputPaths) == 0 {
outputPaths = []string{"stdout"}
}
zapConfig := zap.Config{
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
DisableCaller: true,
Expand All @@ -135,8 +139,8 @@ func createCustomLogger(exporterConfig *Config) *zap.Logger {
},
Encoding: "console",
EncoderConfig: encoderConfig,
// Send exporter's output to stdout. This should be made configurable.
OutputPaths: []string{"stdout"},
// Honor optional output paths (stdout by default).
OutputPaths: outputPaths,
}
return zap.Must(zapConfig.Build())
}
2 changes: 2 additions & 0 deletions exporter/debugexporter/testdata/config_verbosity.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ verbosity: detailed
sampling_initial: 10
sampling_thereafter: 50
use_internal_logger: false
output_paths:
- stderr
Loading