Snippets · Destinations
Send metrics with Prometheus remote write
Prometheus-compatible stores accept remote write. The prometheusremotewrite exporter converts OpenTelemetry metrics to time series, and resource_to_telemetry_conversion decides whether resource attributes such as deployment.environment.name become labels on every series.
- Signals
- Metrics
- Source
- OTLP
- Destination
- Prometheus remote write
OpenTelemetry Collector
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 25
batch:
timeout: 5s
exporters:
prometheusremotewrite:
endpoint: https://prometheus.example.internal/api/v1/write
headers:
Authorization: Bearer ${env:PROMETHEUS_WRITE_TOKEN}
resource_to_telemetry_conversion:
enabled: true
target_info:
enabled: true
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 300s
service:
pipelines:
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheusremotewrite]
LinkMesh
Library › Destinations › Prometheus Remote Write
- Endpoint
- https://prometheus.example.internal/api/v1/write
- Headers
- {"Authorization":"Bearer ${env:PROMETHEUS_WRITE_TOKEN}"}
- Promote Selected Resource Attributes To Labels
- true
What LinkMesh then pushes to the collector, under exporters:
prometheusremotewrite/output_dst_00000502:
endpoint: https://prometheus.example.internal/api/v1/write
headers:
Authorization: Bearer ${env:PROMETHEUS_WRITE_TOKEN}
The same, as an API call (see automation recipes):
curl -X POST "$LINKMESH/destinations" \
-H "Authorization: Bearer $LMSAT" \
-H "Content-Type: application/json" \
-d '{
"defaultConfig": {
"endpoint": "https://prometheus.example.internal/api/v1/write",
"headers": {
"Authorization": "Bearer ${env:PROMETHEUS_WRITE_TOKEN}"
},
"promote_resource_attributes": true
},
"exporterType": "prometheusremotewrite",
"name": "Prometheus Remote Write",
"signalTypes": [
"metrics"
]
}'The rest of the collector config above (otlp, memory_limiter, batch) is not part of this template: in LinkMesh those are separate sources, processors and destinations on the route.
Generated from LinkMesh's template catalogue by linkmesh-server snippet-render 1.464.3, not written by hand.
Download config.yamlValidated with otelcol-contrib v0.161.0 on 2026-10-26
Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0).
The gotcha
Without resource_to_telemetry_conversion your resource attributes are not on the series. In our test, with it off, orders_total arrived with only job and route as labels, and deployment_environment_name existed only on the separate target_info series, so every query needs a join; with it on, every series carried deployment_environment_name and service_name.
Manage this across a fleet
LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).
Doing this in LinkMesh: Destinations
Related snippets
- Count error logs per service as a metric (count connector)Alert on error rates without storing the logs: count them in the collector and keep only the counter.
- RED metrics from traces (spanmetrics connector) to PrometheusRequest rate, errors and latency per service and endpoint, computed from the spans you already send - no metrics SDK needed.
- Agents to a gateway tier, load-balanced by trace IDAgents route every span of a trace to the same gateway, so tail sampling on the gateways sees complete traces.
- Send to Azure Monitor (Application Insights)Logs, metrics and traces to Application Insights, authenticated by the connection string from the environment.