---
title: "loki.enrich | Grafana Alloy documentation"
description: "The loki.enrich component enriches logs with labels from service discovery."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# `loki.enrich`

> **EXPERIMENTAL**: This is an [experimental](https://grafana.com/docs/release-life-cycle/) component. Experimental components are subject to frequent breaking changes, and may be removed with no equivalent replacement. To enable and use an experimental component, you must set the `stability.level` [flag](https://grafana.com/docs/alloy/next/reference/cli/run/) to `experimental`.

The `loki.enrich` component enriches logs with additional labels from service discovery targets. It matches labels from incoming logs against labels from discovered targets, and copies specified labels from the matched target to the log entry. If no match occurs, the component forwards the log entry unchanged.

Use the `target_to_log_match` argument to specify which target labels correspond to which log labels. The map keys are target label names and the values are the corresponding log label names. All labels in the map must match for enrichment to occur.

> Warning
> 
> The `target_match_label` and `logs_match_label` arguments are deprecated in favor of `target_to_log_match`. These deprecated arguments will be removed in a future release.
> 
> The deprecated arguments behave as follows:
> 
> - `target_match_label` is the target label to match against.
> - `logs_match_label` is the log label to match against `target_match_label`. If you don’t set it, the component uses the value of `target_match_label`.
> - If you set `logs_match_label` without `target_match_label` or `target_to_log_match`, the component fails to start.
> - If you set `target_to_log_match`, the component ignores `target_match_label` and `logs_match_label`.
> 
> To migrate, replace `target_match_label = "hostname"` with `target_to_log_match = {"hostname" = "hostname"}`. If you also set `logs_match_label`, use it as the map value. For example, replace `target_match_label = "hostname"` and `logs_match_label = "host"` with `target_to_log_match = {"hostname" = "host"}`.

## Usage

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

```alloy
loki.enrich "<LABEL>" {
  targets = <DISCOVERY_COMPONENT>.targets

  target_to_log_match = {
    "<TARGET_LABEL_1>" = "<LOG_LABEL_1>",
    "<TARGET_LABEL_2>" = "<LOG_LABEL_2>",
  }

  labels_to_copy = ["<LABEL>", ...]

  forward_to = [<RECEIVER_LIST>]
}
```

## Arguments

You can use the following arguments with `loki.enrich`:

Expand table

| Name                  | Type                 | Description                                                                              | Default | Required |
|-----------------------|----------------------|------------------------------------------------------------------------------------------|---------|----------|
| `forward_to`          | `list(LogsReceiver)` | List of receivers to send log entries to.                                                |         | yes      |
| `targets`             | `list(map(string))`  | List of targets from a discovery component.                                              |         | yes      |
| `labels_to_copy`      | `list(string)`       | List of labels to copy from discovered targets to logs. If empty, all labels are copied. |         | no       |
| `logs_match_label`    | `string`             | Deprecated. Use `target_to_log_match` instead.                                           |         | no       |
| `target_match_label`  | `string`             | Deprecated. Use `target_to_log_match` instead.                                           |         | no       |
| `target_to_log_match` | `map(string)`        | Map of target label names to log label names. All entries must match for enrichment.     |         | no       |

> Note
> 
> `target_to_log_match` and `target_match_label` are both optional, but you must set at least one of them. If you set neither, the component fails to start.

The keys and values in `target_to_log_match` can’t be empty strings.

## Blocks

The `loki.enrich` component doesn’t support any blocks. You can configure this component with arguments.

## Exports

The following values are exported:

Expand table

| Name       | Type                | Description                                                 |
|------------|---------------------|-------------------------------------------------------------|
| `receiver` | `loki.LogsReceiver` | A receiver that can be used to send logs to this component. |

## Example

The following example enriches syslog entries with labels from an HTTP service discovery target. It matches the connection IP address and tenant label before it forwards entries to Loki.

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

```alloy
// Configure HTTP discovery
discovery.http "default" {
    url = "http://network-inventory.example.com/prometheus_sd"
}

discovery.relabel "default" {
    targets = discovery.http.default.targets
    rule {
        action        = "replace"
        source_labels = ["__inventory_rack"]
        target_label  = "rack"
    }
    rule {
        action        = "replace"
        source_labels = ["__inventory_datacenter"]
        target_label  = "datacenter"
    }
    rule {
        action        = "replace"
        source_labels = ["__inventory_environment"]
        target_label  = "environment"
    }
    rule {
        action        = "replace"
        source_labels = ["__inventory_tenant"]
        target_label  = "tenant"
    }
    rule {
        action        = "replace"
        source_labels = ["__inventory_primary_ip"]
        target_label  = "primary_ip"
    }
}

loki.relabel "syslog" {
    forward_to = []

    rule {
        source_labels = ["__syslog_connection_ip_address"]
        target_label  = "source_ip"
    }
}

// Receive syslog messages
loki.source.syslog "incoming" {
    listener {
        address  = ":514"
        protocol = "tcp"
        labels   = {
            job    = "syslog",
            tenant = "production",
        }
    }

    relabel_rules = loki.relabel.syslog.rules
    forward_to    = [loki.enrich.default.receiver]
}

// Enrich logs using HTTP discovery
loki.enrich "default" {
    // Use targets from HTTP discovery (after relabeling)
    targets = discovery.relabel.default.output

    target_to_log_match = {
        "primary_ip" = "source_ip",
        "tenant"     = "tenant",
    }

    forward_to = [loki.write.default.receiver]
}

loki.write "default" {
    endpoint {
        url = "http://loki:3100/loki/api/v1/push"
    }
}
```

## Component behavior

The component matches logs to discovered targets and enriches them with additional labels:

1. For each log entry, it looks up the log labels specified by `target_to_log_match`.
2. It matches those values against the corresponding target labels. All label pairs must match the same target.
3. If a match is found, it copies the requested `labels_to_copy` from the discovered target to the log entry. If `labels_to_copy` is empty, all labels are copied.
4. The log entry, enriched or unchanged, is forwarded to the configured receivers.

The component handles the following cases:

- If no target matches a log entry, the component forwards the log entry unchanged.
- If a log entry is missing any of the labels in `target_to_log_match`, or any of those labels has an empty value, the component forwards the log entry unchanged.
- If a target is missing any of the matching labels, or any of them has an empty value, the component ignores that target.
- If multiple targets have the same values for all matching labels, the component uses the last of those targets in the `targets` list. The discovery component determines the order of targets, and the order can change between updates. To get predictable results, make sure the matching labels identify a single target.

> Caution
> 
> By default, `loki.enrich` is ready as soon as it starts, even if no targets have been discovered. If telemetry is sent to this component before the metadata is synced, then it will be passed though as-is, without enrichment. This is most likely to impact `loki.enrich` on startup for a short time before the `discovery` components have sent a new list of targets.

## Compatible components

`loki.enrich` can accept arguments from the following components:

- Components that export [Targets](https://grafana.com/docs/alloy/next/reference/compatibility/#targets-exporters)
- Components that export [Loki `LogsReceiver`](https://grafana.com/docs/alloy/next/reference/compatibility/#loki-logsreceiver-exporters)

`loki.enrich` has exports that can be consumed by the following components:

- Components that consume [Loki `LogsReceiver`](https://grafana.com/docs/alloy/next/reference/compatibility/#loki-logsreceiver-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.
