---
title: "otelcol.processor.groupbyattrs | Grafana Alloy documentation"
description: "Learn about otelcol.processor.groupbyattrs"
---

# `otelcol.processor.groupbyattrs`

`otelcol.processor.groupbyattrs` accepts spans, metrics, and traces from other `otelcol` components and groups them under the same resource.

> Note
> 
> `otelcol.processor.groupbyattrs` is a wrapper over the upstream OpenTelemetry Collector [`groupbyattrs`](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/v0.147.0/processor/groupbyattrsprocessor) processor. If necessary, bug reports or feature requests will be redirected to the upstream repository.

We recommend you use the groupbyattrs processor together with [`otelcol.processor.batch`](../otelcol.processor.batch/), as a consecutive step. This will reduce the fragmentation of data by grouping records together under the matching Resource/Instrumentation Library.

You can specify multiple `otelcol.processor.groupbyattrs` components by giving them different labels.

## Usage

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.groupbyattrs "<LABEL>" {
  output {
    metrics = [...]
    logs    = [...]
    traces  = [...]
  }
}
```

## Arguments

You can use the following argument with `otelcol.processor.groupbyattrs`:

Expand table

| Name   | Type           | Description                                                                             | Default | Required |
|--------|----------------|-----------------------------------------------------------------------------------------|---------|----------|
| `keys` | `list(string)` | Keys that will be used to group the spans, log records, or metric data points together. | `[]`    | no       |

`keys` is a string array that’s used for grouping the data. If it’s empty, the processor performs compaction and reassociates all spans with matching Resource and InstrumentationLibrary.

## Blocks

You can use the following blocks with `otelcol.processor.groupbyattrs`:

No valid configuration blocks found.

### `output`

Required

The `output` block configures a set of components to forward resulting telemetry data to.

The following arguments are supported:

Expand table

| Name      | Type                     | Description                           | Default | Required |
|-----------|--------------------------|---------------------------------------|---------|----------|
| `logs`    | `list(otelcol.Consumer)` | List of consumers to send logs to.    | `[]`    | no       |
| `metrics` | `list(otelcol.Consumer)` | List of consumers to send metrics to. | `[]`    | no       |
| `traces`  | `list(otelcol.Consumer)` | List of consumers to send traces to.  | `[]`    | no       |

You must specify the `output` block, but all its arguments are optional. By default, telemetry data is dropped. Configure the `metrics`, `logs`, and `traces` arguments accordingly to send telemetry data to other components.

### `debug_metrics`

The `debug_metrics` block configures the metrics that this component generates to monitor its state.

The following arguments are supported:

Expand table

| Name                               | Type      | Description                                          | Default | Required |
|------------------------------------|-----------|------------------------------------------------------|---------|----------|
| `disable_high_cardinality_metrics` | `boolean` | Whether to disable certain high cardinality metrics. | `true`  | no       |

`disable_high_cardinality_metrics` is the Alloy equivalent to the `telemetry.disableHighCardinalityMetrics` feature gate in the OpenTelemetry Collector. It removes attributes that could cause high cardinality metrics. For example, attributes with IP addresses and port numbers in metrics about HTTP and gRPC connections are removed.

> Note
> 
> If configured, `disable_high_cardinality_metrics` only applies to `otelcol.exporter.*` and `otelcol.receiver.*` components.

## Exported fields

The following fields are exported and can be referenced by other components:

Expand table

| Name    | Type               | Description                                                   |
|---------|--------------------|---------------------------------------------------------------|
| `input` | `otelcol.Consumer` | Accepts `otelcol.Consumer` data for metrics, logs, or traces. |

`input` accepts `otelcol.Consumer` data for any telemetry signal (metrics, logs, or traces).

## Component health

`otelcol.processor.groupbyattrs` is only reported as unhealthy if given an invalid configuration.

## Debug information

`otelcol.processor.groupbyattrs` doesn’t expose any component-specific debug information.

## Debug metrics

`otelcol.processor.groupbyattrs` doesn’t expose any component-specific debug metrics.

## Examples

### Group metrics

Consider the following metrics, all originally associated to the same Resource:

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
Resource {host.name="localhost",source="prom"}
  Metric "gauge-1" (GAUGE)
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-B",id="eth0"}
  Metric "gauge-1" (GAUGE) // Identical to previous Metric
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-B",id="eth0"}
  Metric "mixed-type" (GAUGE)
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-B",id="eth0"}
  Metric "mixed-type" (SUM)
    DataPoint {host.name="host-A",id="eth0"}
    DataPoint {host.name="host-A",id="eth0"}
  Metric "dont-move" (Gauge)
    DataPoint {id="eth0"}
```

With the following configuration, the groupbyattrs will re-associate the metrics with either `host-A` or `host-B`, based on the value of the `host.name` attribute.

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.groupbyattrs "default" {
  keys = [ "host.name" ]
  output {
    metrics = [otelcol.exporter.otlphttp.default.input]
  }
}
```

The output of the processor is:

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
Resource {host.name="localhost",source="prom"}
  Metric "dont-move" (Gauge)
    DataPoint {id="eth0"}
Resource {host.name="host-A",source="prom"}
  Metric "gauge-1"
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
  Metric "mixed-type" (GAUGE)
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
  Metric "mixed-type" (SUM)
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
Resource {host.name="host-B",source="prom"}
  Metric "gauge-1"
    DataPoint {id="eth0"}
    DataPoint {id="eth0"}
  Metric "mixed-type" (GAUGE)
    DataPoint {id="eth0"}
```

This output demonstrates how `otelcol.processor.groupbyattrs` works in various situations:

- The DataPoints for the `gauge-1` (GAUGE) metric were originally split under 2 Metric instances and have been merged in the output.
- The DataPoints of the `mixed-type` (GAUGE) and `mixed-type` (SUM) metrics haven’t been merged under the same Metric, because their DataType is different.
- The `dont-move` metric DataPoints don’t have a `host.name` attribute and therefore remained under the original Resource.
- The new Resources inherited the attributes from the original Resource (`source="prom"`), plus the specified attributes from the processed metrics (`host.name="host-A"` or `host.name="host-B"`).
- The specified “grouping” attributes that are set on the new Resources are also removed from the metric DataPoints.
- While not shown in the above example, the processor also merges collections of records under matching InstrumentationLibrary.

### Compaction

Sometimes telemetry data can become fragmented due to multiple duplicated ResourceSpans/ResourceLogs/ResourceMetrics objects. This leads to additional memory consumption, increased processing costs, inefficient serialization and increase of the export requests. In such situations, `otelcol.processor.groupbyattrs` can be used to compact the data with matching Resource and InstrumentationLibrary properties.

For example, consider this input data:

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
Resource {host.name="localhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=1, ...}
  InstrumentationLibrary {name="OtherLibrary"}
  Spans
    Span {span_id=2, ...}
    
Resource {host.name="localhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=3, ...}
    
Resource {host.name="localhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=4, ...}
    
Resource {host.name="otherhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=5, ...}
```

You can use `otelcol.processor.groupbyattrs` with its default configuration to compact the data:

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.groupbyattrs "default" {
  output {
    metrics = [otelcol.exporter.otlphttp.default.input]
  }
}
```

The output is:

text ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```text
Resource {host.name="localhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=1, ...}
    Span {span_id=3, ...}
    Span {span_id=4, ...}
  InstrumentationLibrary {name="OtherLibrary"}
  Spans
    Span {span_id=2, ...}

Resource {host.name="otherhost"}
  InstrumentationLibrary {name="MyLibrary"}
  Spans
    Span {span_id=5, ...}
```

## Compatible components

`otelcol.processor.groupbyattrs` can accept arguments from the following components:

- Components that export [OpenTelemetry `otelcol.Consumer`](../../../compatibility/#opentelemetry-otelcolconsumer-exporters)

`otelcol.processor.groupbyattrs` has exports that can be consumed by the following components:

- Components that consume [OpenTelemetry `otelcol.Consumer`](../../../compatibility/#opentelemetry-otelcolconsumer-consumers)

> Note
> 
> Connecting some components may not be sensible or components may require further configuration to make the connection work correctly. Refer to the linked documentation for more details.
