Skip to content

Add OTLP Metrics ingest support - #2127

Draft
gareth-ellis wants to merge 31 commits into
elastic:masterfrom
gareth-ellis:otlp
Draft

gareth-ellis wants to merge 31 commits into
elastic:masterfrom
gareth-ellis:otlp

Conversation

@gareth-ellis

@gareth-ellis gareth-ellis commented May 22, 2026 •

Copy link
Copy Markdown
Member

This commit adds support for indexing to the _otlp/v1/metrics endpoint of elasticsearch.

There's quite a bit more than just a new runner here, as follows:

  • To index to _otlp, you need an otel dataset. Currently I have created these via metricsgenreceiver.
  • Once you have a json otel dataset, you have two choices:
    • Use the json doc as is, prior to a race starting that required an otlp dataset, then a .pb file will be created - this is the protobuf version of your json doc.
    • Alternatively you can store this file along with your corpus, and the .pb file will be collected instead. This will save time, especially if running the benchmark multiple times.

@gareth-ellis

Copy link
Copy Markdown
Member Author

This is split into 6 PRs now:
The recommended review/merge order applies:

#2134 and #2135 — fully independent, can merge in any order, in parallel.
#2136 and #2137 — both need #2135, can review in parallel once #2135 is in.
#2138 — needs #2135 + #2136 + #2137.
#2139 — needs #2138.

Comment thread esrally/driver/runner.py Outdated
* ``body``: Raw binary protobuf payload (bytes).

Optional parameters:
* ``endpoint``: OTLP endpoint path. Defaults to ``/_otlp/v1/metrics``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could a signal-type attribute be considered with possible values of metrics, logs, or traces instead of endpoint?

@gbanasiak gbanasiak mentioned this pull request Oct 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Retry parameters are dropped, prepared variants can resolve incorrectly, and corpus validation can accept corrupt or mismatched files.

12 open findings
What changed in this PR

Adds end-to-end OTLP metrics benchmarking through Elasticsearch’s native OTLP endpoint.

Changes:

  • Adds OTLP corpus conversion, preparation, partitioning, and gzip support.
  • Introduces the otlp-ingest operation with retries and metrics.
  • Adds dependencies, documentation, and comprehensive tests.
File Description
uv.lock Locks OTLP protobuf dependencies.
pyproject.toml Defines OTLP and development dependencies.
create-notice.sh Adds dependency license notices.
esrally/​utils/​io.py Converts and reads protobuf corpus files.
esrally/​track/​track.py Registers the OTLP format and operation.
esrally/​track/​params.py Adds OTLP corpus partitioning and parameters.
esrally/​track/​loader.py Adds format-aware corpus preparation.
esrally/​driver/​runner.py Implements OTLP HTTP ingestion and retries.
tests/​utils/​io_test.py Tests conversion and record indexing.
tests/​track/​params_test.py Tests OTLP parameter sourcing.
tests/​track/​loader_test.py Tests corpus preparation and parsing.
tests/​driver/​runner_test.py Tests OTLP request and retry behavior.
docs/​track.rst Documents the new format and operation.
docs/​otlp_ingest.rst Adds the OTLP usage guide.
docs/​index.rst Includes the guide in documentation navigation.
docs/​advanced.rst Updates preparation architecture documentation.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread esrally/track/loader.py
Comment on lines +689 to +691
# like bulk: trust an existing offset file and only verify when we have to build it
if os.path.exists(pb_file.pb_path + ".offset"):
return True

@gbanasiak gbanasiak Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is intentional. The same behavior is present in case of bulk corpus. The assumption is if someone uploaded offset file into the corpus store they want to reduce the corpus preparation time aggressively. We can change this assumption for both OTLP and bulk in unison but not in this PR.

Comment thread esrally/utils/io.py Outdated
Comment thread esrally/driver/runner.py
Comment thread esrally/track/loader.py Outdated
Comment thread esrally/track/params.py Outdated
Comment thread docs/otlp_ingest.rst
Comment thread docs/otlp_ingest.rst Outdated
Comment thread docs/otlp_ingest.rst Outdated
Comment thread docs/otlp_ingest.rst Outdated
Comment thread tests/track/loader_test.py
@gbanasiak gbanasiak changed the title Add OTLP support to rally Add OTLP Metrics ingest support Oct 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread esrally/track/loader.py
Comment on lines +443 to +444
suffixes = DOCUMENT_SET_FORMATS[document_set.source_format].prepared_file_suffixes()
resolved = first_existing_with_any_suffix(data_root, document_set.document_file, suffixes)
Comment thread esrally/track/loader.py
pb_archive_path = pb_path + archive_ext
try:
preparator.downloader.download(document_set.base_url, pb_archive_path)
except exceptions.DataError:
Comment thread docs/advanced.rst
Comment on lines +561 to +565
if len(data_root) == 1:
preparator.prepare_document_set(document_set, data_root[0], fmt)
# attempt to prepare everything in the current directory and fallback to the corpus directory
elif not preparator.prepare_bundled_document_set(document_set, data_root[0], fmt):
preparator.prepare_document_set(document_set, data_root[1], fmt)
Comment thread docs/otlp_ingest.rst Outdated
Comment thread docs/otlp_ingest.rst
Comment on lines +419 to +421
When a challenge runs ``otlp-ingest`` with multiple clients (``"clients": N``), Rally splits the corpus across clients so each client reads a distinct, non-overlapping slice of the records. Partitioning uses the ``.pb.offset`` index for O(1) seek to each client's starting record.

Each client's slice size is ``floor(total_records / N)``; the final client gets any remainder. This guarantees each record is sent exactly once per pass across all clients.
… include the complete source path'

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants