Send data from an upstream OpenTelemetry Collector
This guide shows how to forward telemetry data from an existing (upstream) OpenTelemetry Collector to a self-managed Elastic Stack using an Elastic Distribution of OpenTelemetry (EDOT) Collector configured as a gateway. The examples use the contrib distribution (otelcol-contrib), but the same approach works with any OTel Collector distribution, including vendor distributions and custom builds assembled with the OpenTelemetry Collector Builder.
Use this setup if you:
- Already run an existing OpenTelemetry Collector and want to add Elastic as a backend without replacing your current setup
- Need to send telemetry to multiple observability backends from a single Collector
- Evaluate Elastic alongside another backend before committing to a full migration
- Use a technology or language for which Elastic doesn't provide an EDOT SDK
Your services send telemetry to an OpenTelemetry Collector (for example, otelcol-contrib), which forwards it over OTLP/gRPC to the EDOT Collector gateway. The gateway applies Elastic-specific processing and writes directly to Elasticsearch.
flowchart LR
S["Your services"] -->|OTLP| U["Upstream otelcol-contrib<br/>(one per host)"]
U -->|"OTLP/gRPC :4317"| G
subgraph G["EDOT Collector (gateway)"]
P["elasticapm processor<br/>enriches spans"]
C["elasticapm connector<br/>generates aggregated metrics"]
end
G -->|"elasticsearch exporter<br/>mapping.mode: otel"| E[("Elasticsearch")]
The elasticsearch exporter with mapping.mode: otel is the recommended path for self-managed deployments.
The Managed OTLP endpoint is an alternative ingest path available only on Elastic Cloud, so it doesn't apply to self-managed deployments. Sending directly to APM Server or the managed intake service through OTLP is also possible, but the EDOT gateway path in this guide is recommended for full APM functionality.
You’ll need:
- A running self-managed Elasticsearch cluster
- The EDOT Collector installed on the gateway host. It ships as part of the Elastic Agent package and runs as Elastic Agent in
otelmode. - An existing OpenTelemetry Collector installed on your agent hosts. This guide uses
otelcol-contrib. - Network connectivity from your Collector hosts to the EDOT gateway host on port 4317
-
Create an Elasticsearch API key
The EDOT gateway authenticates to Elasticsearch using an API key.
- Find API keys in the navigation menu or use the global search field.
- Select Create API key.
- Give the key a name (for example,
edot-gateway) and assign itauto_configureandcreate_docindex privileges on thelogs-*.otel-*,metrics-*.otel-*, andtraces-*.otel-*indices. - Copy the encoded key to use as the value of the
ELASTIC_API_KEYenvironment variable in the gateway configuration.
-
Configure the EDOT gateway
Set the following environment variables on the gateway host before starting the Collector:
export ELASTIC_ENDPOINT=https://your-elasticsearch:9200 export ELASTIC_API_KEY=your-encoded-api-keyCreate the following configuration file and save it as
gateway.ymlon the gateway host:receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 connectors: elasticapm: {} processors: elasticapm: {} exporters: elasticsearch/otel: endpoints: - ${env:ELASTIC_ENDPOINT} api_key: ${env:ELASTIC_API_KEY} mapping: mode: otel service: pipelines: traces: receivers: [otlp] processors: [elasticapm] exporters: [elasticapm, elasticsearch/otel] metrics: receivers: [otlp] processors: [] exporters: [elasticsearch/otel] metrics/aggregated-otel-metrics: receivers: [elasticapm] processors: [] exporters: [elasticsearch/otel] logs: receivers: [otlp] processors: [] exporters: [elasticsearch/otel]Key components in this configuration:
elasticapmprocessor (underprocessors): Enriches spans with attributes required by the APM UI.elasticapmconnector (underconnectors): Generates pre-aggregated APM metrics from trace data. It appears as an exporter in thetracespipeline and as a receiver in themetrics/aggregated-otel-metricspipeline.elasticsearch/otelexporter: Writes data directly to Elasticsearch using native OpenTelemetry data streams (mapping.mode: otel). The exporter handles batching automatically usingsending_queue. Refer to Performance and batching to customize throughput for your environment.
NoteThe
elasticapmconnector and processor are required for full APM functionality (service maps, transaction histograms, service-level indicators). You only need them when exporting directly to Elasticsearch. If you send data to the Managed OTLP endpoint or APM Server or the managed intake service, they are not required.Refer to APM services missing due to misconfigured elasticapm connector for more information.
Start the EDOT gateway. The EDOT Collector is the Elastic Agent binary run in
otelmode, so start it with theotelsubcommand:elastic-agent otel --config gateway.yml
-
Configure the contrib Collector
Configure the OTLP exporter to point to the EDOT gateway. On each contrib Collector host, add or update the
exportersandservicesections in your existingconfig.yml:exporters: otlp: endpoint: "gateway-host:4317" tls: insecure: true service: pipelines: traces: exporters: [otlp] metrics: exporters: [otlp] logs: exporters: [otlp]- Set to
falseand configureca_filefor production
Replace
gateway-hostwith the hostname or IP of your EDOT gateway host. In production, setinsecure: falseand configureca_filewith the path to the CA certificate used to secure communication between the contrib Collector and the gateway. Refer to the TLS configuration settings for the full list of options.- Set to
Set the
deployment.environmentresource attribute in your contrib Collector so that services appear under the correct environment in the Kibana APM Service Map. Without it, all services show as "unset" in the environment selector:processors: resource: attributes: - key: deployment.environment action: insert value: productionRefer to Attributes and labels for more details.
Restart the contrib Collector to apply the changes.
-
Verify data in Kibana
After starting both Collectors, wait a few minutes for data to appear. Then verify in Kibana:
- Find Applications in the navigation menu or use the global search field, then go to Services to confirm your services appear.
- From Applications, go to Service Map to confirm environment-based filtering works.
- Find Discover in the navigation menu or use the global search field and check the
traces-generic.otel-default,logs-generic.otel-default, andmetrics-generic.otel-defaultdata streams for incoming data.
If no data appears, refer to No logs, metrics, or traces visible in Kibana for troubleshooting tips.