Caution
Grafana Alloy is the new name for our distribution of the OTel collector. Grafana Agent has been deprecated and is in Long-Term Support (LTS) through October 31, 2025. Grafana Agent will reach an End-of-Life (EOL) on November 1, 2025. Read more about why we recommend migrating to Grafana Alloy.
Important: This documentation is about an older version. It's relevant only to the release noted, many of the features and functions have been updated or replaced. Please view the current version.
Components configuration language
Components are the defining feature of Grafana Agent Flow. They are small, reusable pieces of business logic that perform a single task (like retrieving secrets or collecting Prometheus metrics) and can be wired together to form programmable pipelines of telemetry data.
Under the hood, components are orchestrated via the component controller, which is responsible for scheduling them, reporting their health and debug status, re-evaluating their arguments and providing their exports.
Configuring components
Components are created by defining a top-level River block. All components are identified by their name, describing what the component is responsible for, while some allow or require to provide an extra user-specified label.
The components docs contain a list of all available components. Each one has a complete reference page, so getting a component to work for you should be as easy as reading its documentation and copy/pasting from an example.
Arguments and exports
Most user interactions with components will center around two basic concepts; arguments and exports.
Arguments are settings which modify the behavior of a component. They can be any number of attributes or nested unlabeled blocks, some of them being required and some being optional. Any optional arguments that are not set will take on their default values.
Exports are zero or more output values that can be referred to by other components, and can be of any River type.
Here’s a quick example; the following block defines a local.file
component
labeled “targets”. The local.file.targets
component will then expose the
file content
as a string in its exports.
The filename
attribute is a required argument; the user can also define a
number of optional ones, in this case detector
, poll_frequency
and
is_secret
, which configure how and how often the file should be polled
as well as whether its contents are sensitive or not.
local.file "targets" {
// Required argument
filename = "/etc/agent/targets"
// Optional arguments: Components may have some optional arguments that
// do not need to be defined.
//
// The optional arguments for local.file are is_secret, detector, and
// poll_frequency.
// Exports: a single field named `content`
// It can be referred to as `local.file.targets.content`
}
Referencing components
To wire components together, one can use the exports of one as the arguments to another by using references. References can only appear in components.
For example, here’s a component that scrapes Prometheus metrics. The targets
field is populated with two scrape targets; a constant one localhost:9001
and
an expression that ties the target to the value of
local.file.targets.content
.
prometheus.scrape "default" {
targets = [
{ "__address__" = local.file.targets.content }, // tada!
{ "__address__" = "localhost:9001" },
]
forward_to = [prometheus.remote_write.default.receiver]
scrape_config {
job_name = "default"
}
}
Every time the file contents change, the local.file
will update its exports,
so the new value will be provided to the prometheus.scrape
targets field.
Each argument and exported field has an underlying type. River will type-check expressions before assigning a value to an attribute; the documentation of each component will have more information about the ways that you can wire components together.
In the previous example, the contents of the local.file.targets.content
expression must first be evaluated in a concrete value then type-checked and
substituted into prometheus.scrape.default
for it to be configured in turn.