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