Skip to content

Commit

Permalink
[exporter/prometheusremotewrite] Make maxBatchByteSize configurable (#…
Browse files Browse the repository at this point in the history
…23447)

Adding a feature: Making `maxBatchByteSize` a configurable parameter.
This would allow users to adjust it based on the capabilities of their
specific remote storage, offering more flexibility and potentially
improving performance.
Example:
```yaml
exporters:
  prometheusremotewrite:
    endpoint: "https://my-cortex:7900/api/v1/push"
    max_batch_byte_size: 5000000
```

Fixes #21911 

**Testing:** <Describe what testing was performed and which tests were
added.>
Added `MaxBatchByteSize` to `TestLoadConfig(t *testing.T)` in
`config_test.go`

**Documentation:** <Describe the documentation added.>
Added to `README.md`:
- `max_batch_byte_size` (default = `3000000` -> `~2.861 mb`): Maximum
size of a batch of
samples to be sent to the remote write endpoint. If the batch size is
larger
  than this value, it will be split into multiple batches.

---------

Co-authored-by: Alex Boten <aboten@lightstep.com>
  • Loading branch information
yotamloe and Alex Boten committed Oct 11, 2023
1 parent 8bb5533 commit 20b69de
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 32 deletions.
20 changes: 20 additions & 0 deletions .chloggen/prometheus-remote-write-max-batch-byte-size.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use this changelog template to create an entry for release notes.
# If your change doesn't affect end users, such as a test fix or a tooling change,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.

# 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. filelogreceiver)
component: prometheusremotewriteexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: addition of `max_batch_size_bytes` configurable parameter, to allow users to adjust it based on the capabilities of their specific remote storage

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [21911]

# (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:
3 changes: 3 additions & 0 deletions exporter/prometheusremotewriteexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ The following settings can be optionally configured:
- `enabled` (default = false): If `enabled` is `true`, a `_created` metric is
exported for Summary, Histogram, and Monotonic Sum metric points if
`StartTimeUnixNano` is set.
- `max_batch_size_bytes` (default = `3000000` -> `~2.861 mb`): Maximum size of a batch of
samples to be sent to the remote write endpoint. If the batch size is larger
than this value, it will be split into multiple batches.

Example:

Expand Down
11 changes: 11 additions & 0 deletions exporter/prometheusremotewriteexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type Config struct {

HTTPClientSettings confighttp.HTTPClientSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.

// maximum size in bytes of time series batch sent to remote storage
MaxBatchSizeBytes int `mapstructure:"max_batch_size_bytes"`

// ResourceToTelemetrySettings is the option for converting resource attributes to telemetry attributes.
// "Enabled" - A boolean field to enable/disable this option. Default is `false`.
// If enabled, all the resource attributes will be converted to metric labels by default.
Expand Down Expand Up @@ -100,5 +103,13 @@ func (cfg *Config) Validate() error {
Enabled: false,
}
}
if cfg.MaxBatchSizeBytes < 0 {
return fmt.Errorf("max_batch_byte_size must be greater than 0")
}
if cfg.MaxBatchSizeBytes == 0 {
// Defaults to ~2.81MB
cfg.MaxBatchSizeBytes = 3000000
}

return nil
}
3 changes: 2 additions & 1 deletion exporter/prometheusremotewriteexporter/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func TestLoadConfig(t *testing.T) {
{
id: component.NewIDWithName(metadata.Type, "2"),
expected: &Config{
TimeoutSettings: exporterhelper.NewDefaultTimeoutSettings(),
MaxBatchSizeBytes: 3000000,
TimeoutSettings: exporterhelper.NewDefaultTimeoutSettings(),
RetrySettings: exporterhelper.RetrySettings{
Enabled: true,
InitialInterval: 10 * time.Second,
Expand Down
45 changes: 22 additions & 23 deletions exporter/prometheusremotewriteexporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,20 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite"
)

const maxBatchByteSize = 3000000

// prwExporter converts OTLP metrics to Prometheus remote write TimeSeries and sends them to a remote endpoint.
type prwExporter struct {
endpointURL *url.URL
client *http.Client
wg *sync.WaitGroup
closeChan chan struct{}
concurrency int
userAgentHeader string
clientSettings *confighttp.HTTPClientSettings
settings component.TelemetrySettings
retrySettings exporterhelper.RetrySettings

wal *prweWAL
exporterSettings prometheusremotewrite.Settings
endpointURL *url.URL
client *http.Client
wg *sync.WaitGroup
closeChan chan struct{}
concurrency int
userAgentHeader string
maxBatchSizeBytes int
clientSettings *confighttp.HTTPClientSettings
settings component.TelemetrySettings
retrySettings exporterhelper.RetrySettings
wal *prweWAL
exporterSettings prometheusremotewrite.Settings
}

// newPRWExporter initializes a new prwExporter instance and sets fields accordingly.
Expand All @@ -64,14 +62,15 @@ func newPRWExporter(cfg *Config, set exporter.CreateSettings) (*prwExporter, err
userAgentHeader := fmt.Sprintf("%s/%s", strings.ReplaceAll(strings.ToLower(set.BuildInfo.Description), " ", "-"), set.BuildInfo.Version)

prwe := &prwExporter{
endpointURL: endpointURL,
wg: new(sync.WaitGroup),
closeChan: make(chan struct{}),
userAgentHeader: userAgentHeader,
concurrency: cfg.RemoteWriteQueue.NumConsumers,
clientSettings: &cfg.HTTPClientSettings,
settings: set.TelemetrySettings,
retrySettings: cfg.RetrySettings,
endpointURL: endpointURL,
wg: new(sync.WaitGroup),
closeChan: make(chan struct{}),
userAgentHeader: userAgentHeader,
maxBatchSizeBytes: cfg.MaxBatchSizeBytes,
concurrency: cfg.RemoteWriteQueue.NumConsumers,
clientSettings: &cfg.HTTPClientSettings,
settings: set.TelemetrySettings,
retrySettings: cfg.RetrySettings,
exporterSettings: prometheusremotewrite.Settings{
Namespace: cfg.Namespace,
ExternalLabels: sanitizedLabels,
Expand Down Expand Up @@ -159,7 +158,7 @@ func (prwe *prwExporter) handleExport(ctx context.Context, tsMap map[string]*pro
}

// Calls the helper function to convert and batch the TsMap to the desired format
requests, err := batchTimeSeries(tsMap, maxBatchByteSize)
requests, err := batchTimeSeries(tsMap, prwe.maxBatchSizeBytes)
if err != nil {
return err
}
Expand Down
12 changes: 7 additions & 5 deletions exporter/prometheusremotewriteexporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,11 @@ func Test_NewPRWExporter(t *testing.T) {
// Test_Start checks if the client is properly created as expected.
func Test_Start(t *testing.T) {
cfg := &Config{
TimeoutSettings: exporterhelper.TimeoutSettings{},
RetrySettings: exporterhelper.RetrySettings{},
Namespace: "",
ExternalLabels: map[string]string{},
TimeoutSettings: exporterhelper.TimeoutSettings{},
RetrySettings: exporterhelper.RetrySettings{},
MaxBatchSizeBytes: 3000000,
Namespace: "",
ExternalLabels: map[string]string{},
TargetInfo: &TargetInfo{
Enabled: true,
},
Expand Down Expand Up @@ -684,7 +685,8 @@ func Test_PushMetrics(t *testing.T) {
ReadBufferSize: 0,
WriteBufferSize: 512 * 1024,
},
RemoteWriteQueue: RemoteWriteQueue{NumConsumers: 1},
MaxBatchSizeBytes: 3000000,
RemoteWriteQueue: RemoteWriteQueue{NumConsumers: 1},
TargetInfo: &TargetInfo{
Enabled: true,
},
Expand Down
7 changes: 4 additions & 3 deletions exporter/prometheusremotewriteexporter/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ func createMetricsExporter(ctx context.Context, set exporter.CreateSettings,

func createDefaultConfig() component.Config {
return &Config{
Namespace: "",
ExternalLabels: map[string]string{},
TimeoutSettings: exporterhelper.NewDefaultTimeoutSettings(),
Namespace: "",
ExternalLabels: map[string]string{},
MaxBatchSizeBytes: 3000000,
TimeoutSettings: exporterhelper.NewDefaultTimeoutSettings(),
RetrySettings: exporterhelper.RetrySettings{
Enabled: true,
InitialInterval: 50 * time.Millisecond,
Expand Down

0 comments on commit 20b69de

Please sign in to comment.