Loading

Configure profiles collection

The Elastic Distribution of OpenTelemetry (EDOT) Collector includes a profiling receiver, which offers an eBPF-based, system-wide profiler.

To activate and configure profiling and send profiles to Elastic Cloud or Elasticsearch, follow these instructions.

Important

OpenTelemetry profiling is still under active development. Refer to The State of Profiling blog post for more information.

Follow these steps to turn on profiling.

Before EDOT Collector ingests profiling data into Elasticsearch, make sure that Universal Profiling is configured for ingestion.

Follow these steps to configure profiles collection through the EDOT Collector.

receivers:
  profiling:

service:
  pipelines:
    profiles:
      receivers: [ profiling ]
      exporters: [ elasticsearch ]
		
receivers:
  profiling:
    SamplesPerSecond: 19

service:
  pipelines:
    profiles:
      receivers: [ profiling ]
      exporters: [ elasticsearch ]
		
Note

Elasticsearch OTel Profiles is still under development and therefore protected by a feature gate.

  1. Activate profiling in the Collector

    To activate profiling in the EDOT Collector, start it using the additional argument --feature-gates=service.profilesSupport.

    For example:

    sudo ./otelcol --config otel.yml --feature-gates=service.profilesSupport
    		

The profiling receiver is only available on Linux. Running it on an operating system other than Linux results in an error.

The supported Linux kernel versions are either 5.4 and later for x86_64 or 5.5 and later for ARM64.

The profiling receiver handles native runtimes, like C, C++, Go and Rust, as well as various interpreters.

The minimum supported versions of each interpreter are:

  • JVM/JDK: 7
  • Python: 3.6
  • V8: 8.1.0
  • Perl: 5.28
  • PHP: 7.3
  • Ruby: 2.5
  • .Net: 6
  • Erlang/OTP 27.2.4

The profilingmetrics connector transforms profiling data into OpenTelemetry metrics. It walks each sample's stack trace and produces per-resource delta metrics that break down CPU time by frame type (kernel, native, JVM, Go, Python, etc.), shared library, kernel subsystem, and system call. This reduces ingest traffic and storage costs compared to sending raw profiling data, while still providing actionable insight into where your application spends its time.

The generated metrics power the Elastic OTel Profiling Metrics integration dashboards.

The following example sends profiling data through the connector and exports the resulting metrics to Elasticsearch:

connectors:
  profilingmetrics:
    metrics:
      samples.frame_type:
        enabled: true
      samples.classification:
        enabled: true

receivers:
  profiling:
    SamplesPerSecond: 19

service:
  pipelines:
    profiles:
      receivers: [ profiling ]
      exporters: [ profilingmetrics ]
    metrics:
      receivers: [ profilingmetrics ]
      exporters: [ elasticsearch ]
		
connectors:
  profilingmetrics:

receivers:
  profiling:

service:
  pipelines:
    profiles:
      receivers: [ profiling ]
      exporters: [ profilingmetrics ]
    metrics:
      receivers: [ profilingmetrics ]
      exporters: [ elasticsearch ]
		

The connector supports the following settings:

Setting Type Default Description
flush_interval duration 30s Time window for aggregating delta metrics in memory before flushing. Set to 0s to disable aggregation and forward metrics on every received profile.
metrics object Per-metric toggle. Each key is a metric name with an enabled boolean.
aggregations list [] List of custom aggregation rules. Each entry has a match (regex applied to function names) and a label (value used in the output metric attribute).

By default, the connector emits per-runtime sample count metrics (samples.kernel.count, samples.native.count, samples.go.count, samples.jvm.count, etc.) with attributes for shared library names (shlib_name), kernel subsystem classification (kernel_area, kernel_proto, kernel_io), and system call names (syscall_name).

Two additional metrics are available but disabled by default:

  • samples.frame_type — frame counts grouped by frame type.
  • samples.classification — language-specific classification (Go package, JVM class).
Important

samples.kernel.count and samples.user.count must both be enabled. Their sum is the only reliable way to compute the total sample count.

In Kubernetes, we suggest deploying the EDOT Collector with a profiling receiver as a DaemonSet. This ensures comprehensive, node-level profiling across the entire cluster, providing consistent data collection, resilience, scalability, and simplified management. This approach is recommended for optimal performance and full observability.