Skip to main content

Understanding the Alloy Configuration Language

Now that you have Grafana Alloy installed, it's time to understand the configuration language (River). This declarative language defines a graph of components that collect, process, and forward telemetry data.

Learning Goals​

By the end of this lesson, you will be able to:

  • Understand the basic syntax and structure of Alloy configurations
  • Define components and connect them using exports and arguments
  • Work with Alloy's core data types and expressions
  • Read and reason about complete pipeline configurations

The Structure of an Alloy Configuration​

Alloy configurations describe a graph of components. Each component performs a specific function and connects to other components by passing exports into arguments.

Basic Configuration Structure​

minimal.alloy
// A simple scrape with no downstream receiver yet
prometheus.scrape "default" {
targets = [
{ "__address__" = "localhost:9090" },
]
forward_to = []
}

This defines a single prometheus.scrape component named "default". Components are identified by their type (prometheus.scrape) and label ("default").

Components: The Building Blocks​

Components have:

  • A type (like prometheus.scrape)
  • A label (like "default", unique per component type)
  • Arguments (inputs to the component)
  • Exports (outputs from the component)

Here is a real example from the course that uses an exporter plus a scrape component:

docs/grafanaalloy/examples/02-system.alloy
prometheus.exporter.unix "local" { }

prometheus.scrape "host" {
targets = prometheus.exporter.unix.local.targets
forward_to = [prometheus.relabel.common_labels.receiver]
}

Connecting Components​

You connect components by passing exports into arguments. The prometheus.exporter.unix.local.targets export above becomes the targets argument for prometheus.scrape.

connected.alloy
prometheus.scrape "node_exporter" {
targets = [
{ "__address__" = "node-exporter:9100", "instance" = "server-01" },
]
forward_to = [prometheus.remote_write.production.receiver]
}

prometheus.remote_write "production" {
endpoint {
url = "http://prometheus:9090/api/v1/write"
}
}
tip

Exports are referenced as component_type.label.export (for example, prometheus.remote_write.production.receiver).

Alloy Data Types and Expressions​

Alloy supports strings, numbers, booleans, lists, maps, and durations (as strings).

types.alloy
string_value = "Hello, Alloy!"
integer_value = 42
float_value = 3.14159
enabled = true
scrape_interval = "30s"

labels = {
"job" = "node_exporter",
"environment" = "production",
}

targets = [
{ "__address__" = "localhost:9100", "job" = "node" },
{ "__address__" = "localhost:9200", "job" = "app" },
]

Standard Library Examples​

Alloy includes a small standard library for common operations:

stdlib.alloy
api_key = sys.env("GCLOUD_RW_API_KEY")
hostname = constants.hostname
config_path = file.path_join("/etc/alloy", "config.alloy")

Putting It Together: A Real Pipeline​

In this course, most examples forward metrics to the common relabeler defined in 01-global.alloy. That relabeler then forwards to the configured remote write endpoints.

docs/grafanaalloy/examples/03-redis.alloy
prometheus.exporter.redis "local" {
redis_addr = "localhost:6379"
}

prometheus.scrape "redis" {
targets = prometheus.exporter.redis.local.targets
forward_to = [prometheus.relabel.common_labels.receiver]

}

Common Pitfalls​

  • Missing component connections: Forgetting to connect components via forward_to means data won't flow.
  • Duplicate labels: Each component instance must have a unique label within its component type.
  • Type mismatches: Passing a string where a number or list is expected causes validation errors.
  • Wrong export references: Use component_type.label.export, not just a label name.
  • Duration formatting: Durations must be strings like "30s".

Summary​

In this lesson, you've learned the fundamentals of the Alloy configuration language:

  1. Components are the building blocks of Alloy configurations, each with a type, label, arguments, and exports
  2. Connections between components are made by passing exports as arguments, creating a data flow pipeline
  3. Data types include strings, numbers, booleans, lists, and objects, with durations as strings
  4. Standard library functions like sys.env and file.path_join are used in expressions

The declarative nature of Alloy's configuration language allows you to focus on the pipeline you want, not the plumbing required to build it.

Quiz​

Alloy Configuration Language - Quick Check

What is the purpose of a component label in Alloy?

Question 1/5