From e173ec7d86f2f2c761c8a1fb227ee458a7386833 Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 20 May 2026 11:38:09 +0100 Subject: [PATCH 1/2] Document label-based routing for Prometheus remote write endpoint --- .../tsds-ingest-prometheus-remote-write.md | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md b/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md index 520eb5ce24..d6c74348f4 100644 --- a/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md +++ b/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md @@ -80,7 +80,12 @@ The endpoint accepts `POST` requests with: ## Send data to different data streams By default, metrics are ingested into the `metrics-generic.prometheus-default` data stream. -You can control the target data stream using URL path parameters: +You can control the target data stream using URL path parameters or per-time-series labels. +In both cases, dataset and namespace values are sanitized — any character that is not alphanumeric, a hyphen, or an underscore is replaced with `_`. + +### Route by URL path + +Set the dataset and namespace via URL path segments: | Endpoint | Data stream | | --- | --- | @@ -88,7 +93,7 @@ You can control the target data stream using URL path parameters: | `/_prometheus/metrics/{dataset}/api/v1/write` | `metrics-{dataset}.prometheus-default` | | `/_prometheus/metrics/{dataset}/{namespace}/api/v1/write` | `metrics-{dataset}.prometheus-{namespace}` | -For example, to route infrastructure metrics into a dedicated data stream, configure the remote write URL as: +For example, to route infrastructure metrics into a dedicated data stream: ```yaml remote_write: @@ -97,6 +102,28 @@ remote_write: This sends data to the `metrics-infrastructure.prometheus-production` data stream. +### Route by labels + +You can also route individual time series to different data streams by attaching `data_stream_dataset` and `data_stream_namespace` labels to each time series. These labels take precedence over the URL path when set, and allow a single remote write endpoint to fan out metrics to multiple data streams. + +These routing labels are control fields and are not stored in the document's `labels` object. + +If only one of the two labels is present on a time series, the other value falls back to the URL path segment (or the default if no path segment was given). + +Use `write_relabel_configs` to add routing labels before sending: + +```yaml +remote_write: + - url: "https:///_prometheus/api/v1/write" + write_relabel_configs: + - target_label: data_stream_dataset + replacement: myapp + - target_label: data_stream_namespace + replacement: production +``` + +This attaches `data_stream_dataset=myapp` and `data_stream_namespace=production` to every time series in this remote write target, routing all metrics to `metrics-myapp.prometheus-production`. + ## Data mapping Incoming Prometheus time series are mapped as follows: @@ -105,7 +132,9 @@ Incoming Prometheus time series are mapped as follows: | --- | --- | --- | | Timestamp | `@timestamp` | The sample timestamp (in milliseconds) | | `__name__` label | `metrics.` | The metric value, stored as a field named after the metric | -| All labels | `labels.` | Mapped as time series dimensions | +| `data_stream_dataset` label | _(routing only)_ | Routes the time series to the specified dataset; not stored in `labels` | +| `data_stream_namespace` label | _(routing only)_ | Routes the time series to the specified namespace; not stored in `labels` | +| All other labels (including `__name__`) | `labels.` | Mapped as time series dimensions | ### Metric types From 4fc8477da5fab4704c25a9be5e719bd206ca134a Mon Sep 17 00:00:00 2001 From: Felix Barnsteiner Date: Wed, 20 May 2026 11:42:50 +0100 Subject: [PATCH 2/2] Apply style guide fixes: active voice, complete sentences --- .../data-streams/tsds-ingest-prometheus-remote-write.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md b/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md index d6c74348f4..b19aaa7863 100644 --- a/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md +++ b/manage-data/data-store/data-streams/tsds-ingest-prometheus-remote-write.md @@ -81,7 +81,7 @@ The endpoint accepts `POST` requests with: By default, metrics are ingested into the `metrics-generic.prometheus-default` data stream. You can control the target data stream using URL path parameters or per-time-series labels. -In both cases, dataset and namespace values are sanitized — any character that is not alphanumeric, a hyphen, or an underscore is replaced with `_`. +In both cases, Elasticsearch sanitizes dataset and namespace values, replacing any character that is not alphanumeric, a hyphen, or an underscore with `_`. ### Route by URL path @@ -93,7 +93,7 @@ Set the dataset and namespace via URL path segments: | `/_prometheus/metrics/{dataset}/api/v1/write` | `metrics-{dataset}.prometheus-default` | | `/_prometheus/metrics/{dataset}/{namespace}/api/v1/write` | `metrics-{dataset}.prometheus-{namespace}` | -For example, to route infrastructure metrics into a dedicated data stream: +For example, to route infrastructure metrics to a dedicated data stream, set the remote write URL to: ```yaml remote_write: @@ -106,7 +106,7 @@ This sends data to the `metrics-infrastructure.prometheus-production` data strea You can also route individual time series to different data streams by attaching `data_stream_dataset` and `data_stream_namespace` labels to each time series. These labels take precedence over the URL path when set, and allow a single remote write endpoint to fan out metrics to multiple data streams. -These routing labels are control fields and are not stored in the document's `labels` object. +Elasticsearch treats these as control fields and does not store them in the document's `labels` object. If only one of the two labels is present on a time series, the other value falls back to the URL path segment (or the default if no path segment was given).