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
// 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:
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.
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"
}
}
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).
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:
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.
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_tomeans 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:
- Components are the building blocks of Alloy configurations, each with a type, label, arguments, and exports
- Connections between components are made by passing exports as arguments, creating a data flow pipeline
- Data types include strings, numbers, booleans, lists, and objects, with durations as strings
- Standard library functions like
sys.envandfile.path_joinare 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?