Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[elasticsearchexporter] support dynamic mapping modes #38114

Merged
merged 10 commits into from
Feb 28, 2025

Conversation

axw
Copy link
Contributor

@axw axw commented Feb 22, 2025

Description

Add support for controlling the mapping mode via a client metadata key (typically an HTTP or gRPC header), X-Elastic-Mapping-Mode. This will override the mode specified in mapping::mode, which now serves as the default.

We also introduce mapping::allowed_modes config which restricts mapping modes to those listed. This will allow an administrator to lock down the allowed mapping modes that can be specified through client metadata.

Because we want to set "require_data_stream=true" for otel mode, and we no longer know ahead of time which mapping mode will be used, we now create a BulkIndexer per mapping mode.

Link to tracking issue

Closes #36092

Testing

  • Added unit tests
  • Tested against a live collector with telemetrygen, passing --otlp-header X-Elastic-Mapping-Mode=\"<mode>\"

Documentation

Updated README.

@axw axw changed the title [elasticsearchexporter] dynamic mapping mode [elasticsearchexporter] support dynamic mapping modes Feb 22, 2025
@axw axw force-pushed the mappingmode-context branch 3 times, most recently from f03e17b to 9b5fd32 Compare February 22, 2025 09:15
Add support for controlling the mapping mode via a
client metadata key (typically an HTTP or gRPC header),
X-Elastic-Mapping-Mode. This will override the mode
specified in `mapping::mode`, which now serves as the
default.

We also introduce `mapping::allowed_modes` config
which restricts the mapping modes to those listed.
This will allow an administrator to lock down the
allowed mapping modes that can be specified through
client metadata.

Because we want to set "require_data_stream=true"
for otel mode, and we no longer know ahead of time
which mapping mode will be used, we now create a
BulkIndexer per mapping mode.
@axw axw force-pushed the mappingmode-context branch from 9b5fd32 to 2ef0941 Compare February 22, 2025 09:23
@axw axw marked this pull request as ready for review February 23, 2025 23:25
@axw axw requested a review from a team as a code owner February 23, 2025 23:25
@axw axw requested a review from dehaansa February 23, 2025 23:25
Copy link
Contributor

@carsonip carsonip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! I just realize this may not work with sending_queue::enabled: true as client metadata isn't persisted (in memory or on disk). Do we have a plan how to make it work? May not be a blocker if it is consistent with how other parts of es exporter do not work with client metadata. But as we're adding the feature to README, we should note that it is broken if sending queue is enabled.

e.g. Tests fail (not very clear as mapping mode is not asserted) with this change

diff --git a/exporter/elasticsearchexporter/exporter_test.go b/exporter/elasticsearchexporter/exporter_test.go
index 1795f2898c..0c52f157a6 100644
--- a/exporter/elasticsearchexporter/exporter_test.go
+++ b/exporter/elasticsearchexporter/exporter_test.go
@@ -2214,6 +2214,7 @@ func newUnstartedTestLogsExporter(t *testing.T, url string, fns ...func(*Config)
 		cfg.Endpoints = []string{url}
 		cfg.NumWorkers = 1
 		cfg.Flush.Interval = 10 * time.Millisecond
+		cfg.QueueSettings.Enabled = true
 	}}, fns...)...)
 	exp, err := f.CreateLogs(context.Background(), exportertest.NewNopSettings(metadata.Type), cfg)
 	require.NoError(t, err)

rec := newBulkRecorder()
server := newESTestServer(t, func(docs []itemRequest) ([]itemResponse, error) {
rec.Record(docs)
return itemsAllOK(docs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to quickly check if the supplied mapping mode is respected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what the check function is doing -- it's verifying the document structure is as expected for the given mapping mode.

@axw
Copy link
Contributor Author

axw commented Feb 24, 2025

thanks! I just realize this may not work with sending_queue::enabled: true as client metadata isn't persisted (in memory or on disk). Do we have a plan how to make it work? May not be a blocker if it is consistent with how other parts of es exporter do not work with client metadata. But as we're adding the feature to README, we should note that it is broken if sending queue is enabled.

IMO that's a bug in sending_queue, and there should be a baseline expectation that all components maintain client metadata. For now I have added a comment in the README.

@carsonip
Copy link
Contributor

IMO that's a bug in sending_queue, and there should be a baseline expectation that all components maintain client metadata. For now I have added a comment in the README.

I looked into it and realize the test failed because the error didn't propagate up the chain. It is not because client metadata isn't propagated in context. Although I wonder if client context is persisted for persistent queue after restart. Let's get to the bottom of it soon, but it is not a blocker.

That's what the check function is doing -- it's verifying the document structure is as expected for the given mapping mode.

😢 I missed it as I was incorrectly assuming that bodymap test failed because client metadata isn't persisted

axw and others added 2 commits February 26, 2025 15:03
Co-authored-by: Carson Ip <carsonip@users.noreply.github.com>
mappingMode := e.config.MappingMode()
mappingMode, err := e.getMappingMode(ctx)
if err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be a permanent error?

Suggested change
return err
return consumererror.NewPermanent(err)

By the way, it looks like the Elasticsearch exporter does not use consumererror.NewPermanent() anywhere. Does this mean it never returns permanent errors to its callers? Perhaps something worth looking at?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a second thought, this is probably not a blocker for this PR, but rather a wider issue to look into, as the Elasticsearch exporter does not seem to make use of permanent errors anywhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @andrzej-stencel, agreed that we should look into that, and that it's a broader issue.

@andrzej-stencel andrzej-stencel merged commit 6bb304e into open-telemetry:main Feb 28, 2025
156 checks passed
@github-actions github-actions bot added this to the next release milestone Feb 28, 2025
@axw axw deleted the mappingmode-context branch March 1, 2025 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[exporter/elasticsearch] Automatic Mapping mode detection via request metadata
4 participants