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

# `otelcol.processor.discovery`

`otelcol.processor.discovery` accepts traces telemetry data from other `otelcol` components. It can be paired with `discovery.*` components, which supply a list of labels for each discovered target. `otelcol.processor.discovery` adds resource attributes to spans which have a hostname matching the one in the `__address__` label provided by the `discovery.*` component.

> Note
> 
> `otelcol.processor.discovery` is a custom component unrelated to any processors from the OpenTelemetry Collector.

Multiple `otelcol.processor.discovery` components can be specified by giving them different labels.

> Note
> 
> It can be difficult to follow [OpenTelemetry semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md) when adding resource attributes via `otelcol.processor.discovery`:
> 
> - `discovery.relabel` and most `discovery.*` processes such as `discovery.kubernetes` can only emit [Prometheus-compatible labels](https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels).
> - Prometheus labels use underscores (`_`) in labels names, whereas [OpenTelemetry semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/README.md) use dots (`.`).
> - Although `otelcol.processor.discovery` is able to work with non-Prometheus labels such as ones containing dots, the fact that `discovery.*` components are generally only compatible with Prometheus naming conventions makes it hard to follow OpenTelemetry semantic conventions in `otelcol.processor.discovery`.
> 
> If your use case is to add resource attributes which contain Kubernetes metadata, consider using `otelcol.processor.k8sattributes` instead.
> 
> The main use case for `otelcol.processor.discovery` is for users who migrate to Alloy from Grafana Agent Static mode `prom_sd_operation_type`/`prom_sd_pod_associations` [configuration options](/docs/agent/latest/static/configuration/traces-config/).

## Usage

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

```alloy
otelcol.processor.discovery "<LABEL>" {
  targets = [...]
  output {
    traces  = [...]
  }
}
```

## Arguments

You can use the following arguments with `otelcol.processor.discovery`:

Expand table

| Name               | Type                | Description                                                           | Default                                                         | Required |
|--------------------|---------------------|-----------------------------------------------------------------------|-----------------------------------------------------------------|----------|
| `targets`          | `list(map(string))` | List of target labels to apply to the spans.                          |                                                                 | yes      |
| `operation_type`   | `string`            | Configures whether to update a span’s attribute if it already exists. | `"upsert"`                                                      | no       |
| `pod_associations` | `list(string)`      | Configures how to decide the hostname of the span.                    | `["ip", "net.host.ip", "k8s.pod.ip", "hostname", "connection"]` | no       |

`targets` could come from `discovery.*` components:

1. The `__address__` label will be matched against the IP address of incoming spans.
   
   - If `__address__` contains a port, it’s ignored.
2. If a match is found, then relabeling rules are applied.
   
   - Labels starting with `__` won’t be added to the spans.

The supported values for `operation_type` are:

- `insert`: Inserts a new resource attribute if the key doesn’t already exist.
- `update`: Updates a resource attribute if the key already exists.
- `upsert`: Either inserts a new resource attribute if the key doesn’t already exist, or updates a resource attribute if the key does exist.

The supported values for `pod_associations` are:

- `ip`: The hostname will be sourced from an `ip` resource attribute.
- `net.host.ip`: The hostname will be sourced from a `net.host.ip` resource attribute.
- `k8s.pod.ip`: The hostname will be sourced from a `k8s.pod.ip` resource attribute.
- `hostname`: The hostname will be sourced from a `host.name` resource attribute.
- `connection`: The hostname will be sourced from the context from the incoming requests (gRPC and HTTP).

If multiple `pod_associations` methods are enabled, the order of evaluation is honored. For example, when `pod_associations` is `["ip", "net.host.ip"]`, `"net.host.ip"` may be matched only if `"ip"` hasn’t already matched.

## Blocks

You can use the following block with `otelcol.processor.discovery`:

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 |
|----------|--------------------------|--------------------------------------|---------|----------|
| `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 `traces` argument accordingly to send telemetry data to other components.

## Exported fields

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

Expand table

| Name    | Type               | Description                                                      |
|---------|--------------------|------------------------------------------------------------------|
| `input` | `otelcol.Consumer` | A value that other components can use to send telemetry data to. |

`input` accepts `otelcol.Consumer` OTLP-formatted data for telemetry signals of these types:

- traces

## Component health

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

## Debug information

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

## Examples

### Basic usage

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

```alloy
discovery.http "dynamic_targets" {
    url              = "https://example.com/scrape_targets"
    refresh_interval = "15s"
}

otelcol.processor.discovery "default" {
    targets = discovery.http.dynamic_targets.targets

    output {
        traces = [otelcol.exporter.otlphttp.default.input]
    }
}
```

### Use more than one discovery process

Outputs from more than one discovery process can be combined via the `array.concat` function.

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

```alloy
discovery.http "dynamic_targets" {
    url              = "https://example.com/scrape_targets"
    refresh_interval = "15s"
}

discovery.kubelet "k8s_pods" {
  bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"
  namespaces        = ["default", "kube-system"]
}

otelcol.processor.discovery "default" {
    targets = array.concat(discovery.http.dynamic_targets.targets, discovery.kubelet.k8s_pods.targets)

    output {
        traces = [otelcol.exporter.otlphttp.default.input]
    }
}
```

### Use a preconfigured list of attributes

It’s not necessary to use a discovery component. In the following example, both a `test_label` and a `test.label.with.dots` resource attributes will be added to a span if its IP address is “1.2.2.2”. The `__internal_label__` will be not be added to the span, because it begins with a double underscore (`__`).

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

```alloy
otelcol.processor.discovery "default" {
    targets = [{
        "__address__"          = "1.2.2.2",
        "__internal_label__"   = "test_val",
        "test_label"           = "test_val2",
        "test.label.with.dots" = "test.val2.with.dots"}]

    output {
        traces = [otelcol.exporter.otlphttp.default.input]
    }
}
```

## Compatible components

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

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

`otelcol.processor.discovery` 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.
