Capture the Elasticsearch cluster name on OpenTelemetry spans from response headers - #1319
Merged
l-trotta merged 3 commits intoSep 9, 2026
Conversation
|
💚 CLA has been signed |
vagrawal-newrelic
force-pushed
the
feature/otel-cluster-name-discovery
branch
from
September 8, 2026 16:24
effcdda to
85ae4b3
Compare
vagrawal-newrelic
force-pushed
the
feature/otel-cluster-name-discovery
branch
5 times, most recently
from
September 9, 2026 06:34
873235a to
e41949b
Compare
…se headers Read the cluster name from the response headers and stamp it as db.elasticsearch.cluster.name on every client span: prefer the Elastic Cloud proxy header (X-Found-Handling-Cluster), and fall back to the Elastic-Cluster-Name header emitted by self-managed clusters (opt-in via http.headers.cluster_name.enabled). The capture is address-independent, so it survives load balancers and proxies, and needs no extra request.
Cover all scenarios in OpenTelemetryForElasticsearchTest: cloud header (X-Found-Handling-Cluster) only, on-prem header (Elastic-Cluster-Name) only, both present (cloud preferred), neither present, empty cloud header falling back to on-prem, and both headers empty (attribute not stamped).
vagrawal-newrelic
force-pushed
the
feature/otel-cluster-name-discovery
branch
from
September 9, 2026 06:48
e41949b to
b558573
Compare
vagrawal-newrelic
marked this pull request as ready for review
September 9, 2026 07:31
l-trotta
reviewed
Sep 9, 2026
Comment on lines
+63
to
+69
| ## Capturing the {{es}} cluster name [opentelemetry-cluster-name] | ||
|
|
||
| The built-in instrumentation automatically records the `db.elasticsearch.cluster.name` span attribute when {{es}} includes the cluster name in its response headers. You do not need to configure the client. | ||
|
|
||
| To capture this attribute in self-managed {{es}} (version 9.6 and later), set `http.headers.cluster_name.enabled` to `true` on your cluster. | ||
|
|
||
|
|
Contributor
There was a problem hiding this comment.
nit: we should document the difference between the on-prem and cloud value
Contributor
Author
There was a problem hiding this comment.
@l-trotta Thanks for the feedback! updated the docs to spell out the value in each case: the canonical globally-unique cluster id on Elastic Cloud (X-Found-Handling-Cluster) vs the configured cluster.name on self-managed (Elastic-Cluster-Name). Thanks!
Describe the db.elasticsearch.cluster.name span attribute captured from the X-Found-Handling-Cluster (Elastic Cloud) and Elastic-Cluster-Name (self-managed) response headers.
vagrawal-newrelic
force-pushed
the
feature/otel-cluster-name-discovery
branch
from
September 9, 2026 10:46
b558573 to
dcc45b5
Compare
l-trotta
approved these changes
Sep 9, 2026
l-trotta
left a comment
Contributor
There was a problem hiding this comment.
thank you so much! LGTM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Records the Elasticsearch cluster name on the client's OpenTelemetry spans as
db.elasticsearch.cluster.name, read from the response headers. This gives spans an address-independent cluster identity, so telemetry can be correlated to the right cluster even behind a load balancer, proxy or node list — whereserver.addressdoesn't identify the cluster.Resolves #1304.
What it does
In
OpenTelemetryForElasticsearch, once the HTTP response is received, the cluster name is read from the response headers and stamped on the span, in this order of precedence:X-Found-Handling-Cluster— set by the Elastic Cloud proxy (canonical, globally-unique cluster id).Elastic-Cluster-Name— emitted by self-managed Elasticsearch whenhttp.headers.cluster_name.enabled: trueis set (added in Add cluster name header for onprem elasticsearch#157191, available in 9.6+).If neither header is present, the attribute is simply not set. The capture is automatic (no configuration), makes no extra request, and never affects the actual request.
Why headers
Data-plane responses (
_search,_bulk, …) never returncluster_name, andserver.addressreflects whichever node / load balancer / proxy the transport happened to hit — not the cluster's own identity. Reading the value the cluster itself stamps on the response is address-independent and works across all deployment topologies. This mirrors how the .NET client populatesdb.elasticsearch.cluster.name.Testing
Extended
OpenTelemetryForElasticsearchTestwith full scenario coverage:X-Found-Handling-Clusteronly → capturedElastic-Cluster-Nameonly → capturedX-Found-Handling-Clusterwins (precedence)X-Found-Handling-Cluster→ falls back toElastic-Cluster-Name./gradlew checkpasses (checkstyle + tests).Note
This replaces the earlier draft on this branch, which used an opt-in
GET /active-discovery approach. Now that the server-sideElastic-Cluster-Nameheader has merged (elastic/elasticsearch#157191), the self-managed case is covered passively by a header too — so the active-discovery machinery is no longer needed, and the change is just the header read.