<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Collect and forward data with Grafana Alloy on Grafana Labs</title><link>https://grafana.com/docs/alloy/v1.15/collect/</link><description>Recent content in Collect and forward data with Grafana Alloy on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/alloy/v1.15/collect/index.xml" rel="self" type="application/rss+xml"/><item><title>Choose a Grafana Alloy component</title><link>https://grafana.com/docs/alloy/v1.15/collect/choose-component/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/choose-component/</guid><content><![CDATA[&lt;h1 id=&#34;choose-a--grafana-alloy-component&#34;&gt;Choose a  Grafana Alloy component&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; are the building blocks of Grafana Alloy, and there is a &lt;a href=&#34;../../reference/components/&#34;&gt;large number of them&lt;/a&gt;.
The components you select and configure depend on the telemetry signals you want to collect.&lt;/p&gt;
&lt;h2 id=&#34;metrics-for-infrastructure&#34;&gt;Metrics for infrastructure&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;prometheus.*&lt;/code&gt; components to collect infrastructure metrics.
This gives you the best experience with &lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/&#34;&gt;Grafana Infrastructure Observability&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, you can get metrics for a Linux host using &lt;code&gt;prometheus.exporter.unix&lt;/code&gt;, and metrics for a MongoDB instance using &lt;code&gt;prometheus.exporter.mongodb&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can also scrape any Prometheus endpoint using &lt;code&gt;prometheus.scrape&lt;/code&gt;.
Use &lt;code&gt;discovery.*&lt;/code&gt; components to find targets for &lt;code&gt;prometheus.scrape&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;metrics-for-applications&#34;&gt;Metrics for applications&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;otelcol.receiver.*&lt;/code&gt; components to collect application metrics.
This gives you the best experience with &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/introduction/&#34;&gt;Grafana Application Observability&lt;/a&gt;, which is OpenTelemetry-native.&lt;/p&gt;
&lt;p&gt;For example, use &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; to collect metrics from OpenTelemetry-instrumented applications.&lt;/p&gt;
&lt;p&gt;If your application is already instrumented with Prometheus metrics, there is no need to use &lt;code&gt;otelcol.*&lt;/code&gt; components.
Use &lt;code&gt;prometheus.*&lt;/code&gt; components for the entire pipeline and send the metrics using &lt;code&gt;prometheus.remote_write&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;logs-from-infrastructure&#34;&gt;Logs from infrastructure&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;loki.*&lt;/code&gt; components to collect infrastructure logs.
The &lt;code&gt;loki.*&lt;/code&gt; components label your logs in a way that resembles Prometheus metrics.
This makes it easy to correlate infrastructure metrics collected by &lt;code&gt;prometheus.*&lt;/code&gt; components
with logs collected by &lt;code&gt;loki.*&lt;/code&gt; components.&lt;/p&gt;
&lt;p&gt;For example, the label that both &lt;code&gt;prometheus.*&lt;/code&gt; and &lt;code&gt;loki.*&lt;/code&gt; components would use for a Kubernetes namespace is called &lt;code&gt;namespace&lt;/code&gt;.
On the other hand, gathering logs using an &lt;code&gt;otelcol.*&lt;/code&gt; component might use the &lt;a href=&#34;https://opentelemetry.io/docs/concepts/semantic-conventions/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry semantics&lt;/a&gt; label called &lt;code&gt;k8s.namespace.name&lt;/code&gt;,
which wouldn&amp;rsquo;t correspond to the &lt;code&gt;namespace&lt;/code&gt; label that&amp;rsquo;s common in the Prometheus ecosystem.&lt;/p&gt;
&lt;h2 id=&#34;logs-from-applications&#34;&gt;Logs from applications&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;otelcol.receiver.*&lt;/code&gt; components to collect application logs.
This gathers the application logs in an OpenTelemetry-native way, making it easier to
correlate the logs with OpenTelemetry metrics and traces coming from the application.
All application telemetry must follow the &lt;a href=&#34;https://opentelemetry.io/docs/concepts/semantic-conventions/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry semantic conventions&lt;/a&gt;, simplifying this correlation.&lt;/p&gt;
&lt;p&gt;For example, if your application runs on Kubernetes, every trace, log, and metric can have a &lt;code&gt;k8s.namespace.name&lt;/code&gt; resource attribute.&lt;/p&gt;
&lt;h2 id=&#34;traces&#34;&gt;Traces&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;otelcol.receiver.*&lt;/code&gt; components to collect traces.&lt;/p&gt;
&lt;p&gt;If your application isn&amp;rsquo;t yet instrumented for tracing, use &lt;code&gt;beyla.ebpf&lt;/code&gt; to generate traces for it automatically.&lt;/p&gt;
&lt;h2 id=&#34;profiles&#34;&gt;Profiles&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;pyroscope.*&lt;/code&gt; components to collect profiles.&lt;/p&gt;
&lt;h2 id=&#34;frontend-telemetry&#34;&gt;Frontend telemetry&lt;/h2&gt;
&lt;p&gt;In order to use &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/frontend-observability/&#34;&gt;Grafana Cloud Frontend Observability&lt;/a&gt;, you have to collect and forward frontend telemetry using &lt;code&gt;otelcol.receiver.faro&lt;/code&gt; and &lt;code&gt;otelcol.exporter.faro&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can also gather frontend telemetry using &lt;code&gt;faro.receiver&lt;/code&gt; and send it to Grafana Cloud, but &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/frontend-observability/&#34;&gt;Grafana Cloud Frontend Observability&lt;/a&gt; will not work and you will need to create your own dashboards.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;faro.receiver&lt;/code&gt; is recommended only for a self-hosted Grafana setup.&lt;/p&gt;
]]></content><description>&lt;h1 id="choose-a--grafana-alloy-component">Choose a Grafana Alloy component&lt;/h1>
&lt;p>&lt;a href="../../get-started/components/">Components&lt;/a> are the building blocks of Grafana Alloy, and there is a &lt;a href="../../reference/components/">large number of them&lt;/a>.
The components you select and configure depend on the telemetry signals you want to collect.&lt;/p></description></item><item><title>Set up meta-monitoring to collect Alloy telemetry</title><link>https://grafana.com/docs/alloy/v1.15/collect/metamonitoring/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/metamonitoring/</guid><content><![CDATA[&lt;h1 id=&#34;set-up-meta-monitoring-to-collect-alloy-telemetry&#34;&gt;Set up meta-monitoring to collect Alloy telemetry&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect its own telemetry and forward it to the backend of your choosing.&lt;/p&gt;
&lt;p&gt;This topic describes how to collect and forward metrics, logs, and traces data from Alloy.&lt;/p&gt;
&lt;h2 id=&#34;components-and-configuration-blocks-used-in-this-topic&#34;&gt;Components and configuration blocks used in this topic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.exporter.self/&#34;&gt;&lt;code&gt;prometheus.exporter.self&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/logging/&#34;&gt;&lt;code&gt;logging&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/config-blocks/tracing/&#34;&gt;&lt;code&gt;tracing&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Identify where to send Alloy&amp;rsquo;s telemetry data.&lt;/li&gt;
&lt;li&gt;Be familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;meta-monitoring-metrics&#34;&gt;Meta-monitoring metrics&lt;/h2&gt;
&lt;p&gt;Alloy exposes its internal metrics using the Prometheus exposition format.&lt;/p&gt;
&lt;p&gt;The metrics are exposed on a &lt;code&gt;/metrics&lt;/code&gt; endpoint on an address configurable via the &lt;code&gt;--server.http.listen-addr&lt;/code&gt; &lt;a href=&#34;../../reference/cli/run/&#34;&gt;command line flag&lt;/a&gt;.
For example, &lt;code&gt;127.0.0.1:12345/metrics&lt;/code&gt;.
However, it&amp;rsquo;s also possible to access the same metrics using the &lt;code&gt;prometheus.exporter.self&lt;/code&gt; component.&lt;/p&gt;
&lt;p&gt;In this task, you use the &lt;a href=&#34;../../reference/components/prometheus/prometheus.exporter.self/&#34;&gt;&lt;code&gt;prometheus.exporter.self&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt; components to scrape Alloy&amp;rsquo;s internal metrics and forward it to compatible Alloy components.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.exporter.self&lt;/code&gt; component to your configuration. The component accepts no arguments.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.exporter.self &amp;#34;&amp;lt;SELF_LABEL&amp;gt;&amp;#34; {
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SELF_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component such as &lt;code&gt;default&lt;/code&gt; or &lt;code&gt;metamonitoring&lt;/code&gt;. The label must be unique across all &lt;code&gt;prometheus.exporter.self&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.scrape&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;&amp;lt;SCRAPE_LABEL&amp;gt;&amp;#34; {
  targets    = prometheus.exporter.self.&amp;lt;SELF_LABEL&amp;gt;.targets
  forward_to = [&amp;lt;METRICS_RECEIVER_LIST&amp;gt;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SCRAPE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the scrape component such as &lt;code&gt;default&lt;/code&gt;. The label must be unique across all &lt;code&gt;prometheus.scrape&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;METRICS_RECEIVER_LIST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of component receivers to forward metrics to.
For example, to send to a remote write component, use &lt;code&gt;prometheus.remote_write.WRITE_LABEL.receiver&lt;/code&gt;.
Similarly, to send data to a relabeling component, use &lt;code&gt;prometheus.relabel.PROCESS_LABEL.receiver&lt;/code&gt;.
To use data in the OTLP format, you can send data to a converter component, like &lt;code&gt;otelcol.receiver.prometheus.OTEL.receiver&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring a possible sequence of components.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.exporter.self &amp;#34;default&amp;#34; {
}

prometheus.scrape &amp;#34;metamonitoring&amp;#34; {
  targets    = prometheus.exporter.self.default.targets
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://mimir:9009/api/v1/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;meta-monitoring-logs&#34;&gt;Meta-monitoring logs&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;../../reference/config-blocks/logging/&#34;&gt;logging&lt;/a&gt; block defines the logging behavior of Alloy.&lt;/p&gt;
&lt;p&gt;In this task, you use the &lt;a href=&#34;../../reference/config-blocks/logging/&#34;&gt;logging&lt;/a&gt; block to forward Alloy&amp;rsquo;s logs to a compatible component.
The block is specified without a label and can only be provided once per configuration file.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;logging&lt;/code&gt; configuration block to the top level of your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;logging {
  level    = &amp;#34;&amp;lt;LOG_LEVEL&amp;gt;&amp;#34;
  format   = &amp;#34;&amp;lt;LOG_FORMAT&amp;gt;&amp;#34;
  write_to = [&amp;lt;LOGS_RECEIVER_LIST&amp;gt;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LOG_LEVEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The log level to use for Alloy&amp;rsquo;s logs. If the attribute isn&amp;rsquo;t set, it defaults to &lt;code&gt;info&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LOG_FORMAT&amp;gt;&lt;/code&gt;&lt;/em&gt;: The log format to use for Alloy&amp;rsquo;s logs. If the attribute isn&amp;rsquo;t set, it defaults to &lt;code&gt;logfmt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LOGS_RECEIVER_LIST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of component receivers to forward logs to.
For example, to send to a processing component, use &lt;code&gt;loki.process.PROCESS_LABEL.receiver&lt;/code&gt;.
Similarly, to send data to a relabeling component, use &lt;code&gt;loki.relabel.PROCESS_LABEL.receiver&lt;/code&gt;.
To use data in the OTLP format, you can send data to a converter component, like &lt;code&gt;otelcol.receiver.loki.OTEL.receiver&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring the logging block and sending to a compatible component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;logging {
  level    = &amp;#34;warn&amp;#34;
  format   = &amp;#34;json&amp;#34;
  write_to = [loki.write.default.receiver]
}

loki.write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://loki:3100/loki/api/v1/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;meta-monitoring-traces&#34;&gt;Meta-monitoring traces&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;../../reference/config-blocks/tracing/&#34;&gt;tracing&lt;/a&gt; block defines the tracing behavior of Alloy.&lt;/p&gt;
&lt;p&gt;In this task, you use the &lt;a href=&#34;../../reference/config-blocks/tracing/&#34;&gt;tracing&lt;/a&gt; block to forward Alloy internal traces to a compatible component. The block is specified without a label and can only be provided once per configuration file.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;tracing&lt;/code&gt; configuration block to the top level of your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;tracing {
  sampling_fraction = &amp;lt;SAMPLING_FRACTION&amp;gt;
  write_to          = [&amp;lt;TRACES_RECEIVER_LIST&amp;gt;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SAMPLING_FRACTION&amp;gt;&lt;/code&gt;&lt;/em&gt;: The fraction of traces to keep. If the attribute isn&amp;rsquo;t set, it defaults to &lt;code&gt;0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;TRACES_RECEIVER_LIST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of component receivers to forward traces to.
For example, to send to an OpenTelemetry exporter component use &lt;code&gt;otelcol.exporter.otlp.EXPORT_LABEL.input&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring the tracing block and sending to a compatible component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;tracing {
  sampling_fraction = 0.1
  write_to          = [otelcol.exporter.otlp.default.input]
}

otelcol.exporter.otlp &amp;#34;default&amp;#34; {
    client {
        endpoint = &amp;#34;tempo:4317&amp;#34;
    }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="set-up-meta-monitoring-to-collect-alloy-telemetry">Set up meta-monitoring to collect Alloy telemetry&lt;/h1>
&lt;p>You can configure Alloy to collect its own telemetry and forward it to the backend of your choosing.&lt;/p></description></item><item><title>Receive traces and metrics from Datadog-instrumented applications</title><link>https://grafana.com/docs/alloy/v1.15/collect/datadog-traces-metrics/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/datadog-traces-metrics/</guid><content><![CDATA[&lt;h1 id=&#34;receive-traces-and-metrics-from-datadog-instrumented-applications&#34;&gt;Receive traces and metrics from Datadog-instrumented applications&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect &lt;a href=&#34;https://www.datadoghq.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Datadog&lt;/a&gt; traces and metrics and forward them to any OpenTelemetry-compatible database.&lt;/p&gt;
&lt;p&gt;This topic describes how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure Alloy to send traces and metrics.&lt;/li&gt;
&lt;li&gt;Configure the Alloy Datadog Receiver.&lt;/li&gt;
&lt;li&gt;Configure the Datadog Agent to forward traces and metrics to the Alloy Datadog Receiver.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that at least one instance of the &lt;a href=&#34;https://docs.datadoghq.com/agent/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Datadog Agent&lt;/a&gt; is collecting metrics and traces.&lt;/li&gt;
&lt;li&gt;Identify where to write the collected telemetry.
Metrics can be written to &lt;a href=&#34;https://prometheus.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus&lt;/a&gt; or any other OpenTelemetry-compatible database such as Grafana Mimir, Grafana Cloud, or Grafana Enterprise Metrics.
Traces can be written to Grafana Tempo, Grafana Cloud, or Grafana Enterprise Traces.&lt;/li&gt;
&lt;li&gt;Be familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;configure-alloy-to-send-traces-and-metrics&#34;&gt;Configure Alloy to send traces and metrics&lt;/h2&gt;
&lt;p&gt;Before components can collect Datadog telemetry signals, you must have a component responsible for writing this telemetry somewhere.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlp/&#34;&gt;otelcol.exporter.otlp&lt;/a&gt; component is responsible for delivering OTLP data to OpenTelemetry-compatible endpoints.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;&amp;lt;OTLP_ENDPOINT_URL&amp;gt;&amp;#34;
    auth     = otelcol.auth.basic.auth.handler
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;OTLP_ENDPOINT_URL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The full URL of the OpenTelemetry-compatible endpoint where metrics and traces are sent, such as &lt;code&gt;https://otlp-gateway-prod-eu-west-2.grafana.net/otlp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your endpoint requires basic authentication, paste the following inside the &lt;code&gt;endpoint&lt;/code&gt; block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;basic_auth {
  username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication password or API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;configure-the-alloy-datadog-receiver&#34;&gt;Configure the Alloy Datadog Receiver&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.processor.batch&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.processor.batch &amp;#34;default&amp;#34; {
  output {
    metrics = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.processor.deltatocumulative&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.processor.deltatocumulative &amp;#34;default&amp;#34; {
  max_stale = &amp;#34;&amp;lt;MAX_STALE&amp;gt;&amp;#34;
  max_streams = &amp;lt;MAX_STREAMS&amp;gt;
  output {
    metrics = [otelcol.processor.batch.default.input]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MAX_STALE&amp;gt;&lt;/code&gt;&lt;/em&gt;: How long until a series not receiving new samples is removed, such as &amp;ldquo;5m&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MAX_STREAMS&amp;gt;&lt;/code&gt;&lt;/em&gt;: The upper limit of streams to track. New streams exceeding this limit are dropped.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.receiver.datadog&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.datadog &amp;#34;default&amp;#34; {
  endpoint = &amp;#34;&amp;lt;HOST&amp;gt;:&amp;lt;PORT&amp;gt;&amp;#34;
  output {
    metrics = [otelcol.processor.deltatocumulative.default.input]
    traces  = [otelcol.processor.batch.default.input]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt;: The host address where the receiver listens.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PORT&amp;gt;&lt;/code&gt;&lt;/em&gt;: The port where the receiver listens.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your endpoint requires basic authentication, paste the following inside the &lt;code&gt;endpoint&lt;/code&gt; block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;basic_auth {
  username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication password or API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;configure-datadog-agent-to-forward-telemetry-to-the-alloy-datadog-receiver&#34;&gt;Configure Datadog Agent to forward telemetry to the Alloy Datadog Receiver&lt;/h2&gt;
&lt;p&gt;You can set up your Datadog Agent to forward Datadog metrics and traces simultaneously to Alloy and Datadog.&lt;/p&gt;
&lt;p&gt;We recommend this approach for current Datadog users who want to try using Alloy.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following environment variables to your Datadog-agent installation.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;DD_ADDITIONAL_ENDPOINTS=&amp;#39;{&amp;#34;http://&amp;lt;DATADOG_RECEIVER_HOST&amp;gt;:&amp;lt;DATADOG_RECEIVER_PORT&amp;gt;&amp;#34;: [&amp;#34;datadog-receiver&amp;#34;]}&amp;#39;
DD_APM_ADDITIONAL_ENDPOINTS=&amp;#39;{&amp;#34;http://&amp;lt;DATADOG_RECEIVER_HOST&amp;gt;:&amp;lt;DATADOG_RECEIVER_PORT&amp;gt;&amp;#34;: [&amp;#34;datadog-receiver&amp;#34;]}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;DD_ADDITIONAL_ENDPOINTS&lt;/code&gt; is used for forwarding metrics, whereas &lt;code&gt;DD_APM_ADDITIONAL_ENDPOINTS&lt;/code&gt; is for traces.&lt;/p&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DATADOG_RECEIVER_HOST&amp;gt;&lt;/code&gt;&lt;/em&gt;: The hostname where the Alloy receiver is found.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DATADOG_RECEIVER_PORT&amp;gt;&lt;/code&gt;&lt;/em&gt;: The port where the Alloy receiver is exposed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, you might want your Datadog Agent to send metrics only to Alloy.
You can do this by setting up your Datadog Agent in the following way:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Replace the DD_URL in the configuration YAML:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt; dd_url: http://&amp;lt;DATADOG_RECEIVER_HOST&amp;gt;:&amp;lt;DATADOG_RECEIVER_PORT&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or by setting an environment variable:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;DD_URL=&amp;#39;{&amp;#34;http://&amp;lt;DATADOG_RECEIVER_HOST&amp;gt;:&amp;lt;DATADOG_RECEIVER_PORT&amp;gt;&amp;#34;: [&amp;#34;datadog-receiver&amp;#34;]}&amp;#39;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;run-alloy&#34;&gt;Run Alloy&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;otelcol.receiver.datadog&lt;/code&gt; component is experimental.
To use this component, you need to start Alloy with additional command line flags:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;alloy run config.alloy --stability.level=experimental&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="receive-traces-and-metrics-from-datadog-instrumented-applications">Receive traces and metrics from Datadog-instrumented applications&lt;/h1>
&lt;p>You can configure Alloy to collect &lt;a href="https://www.datadoghq.com/" target="_blank" rel="noopener noreferrer">Datadog&lt;/a> traces and metrics and forward them to any OpenTelemetry-compatible database.&lt;/p>
&lt;p>This topic describes how to:&lt;/p></description></item><item><title>Collect Kubernetes logs and forward them to Loki</title><link>https://grafana.com/docs/alloy/v1.15/collect/logs-in-kubernetes/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/logs-in-kubernetes/</guid><content><![CDATA[&lt;h1 id=&#34;collect-kubernetes-logs-and-forward-them-to-loki&#34;&gt;Collect Kubernetes logs and forward them to Loki&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect logs and forward them to a &lt;a href=&#34;/oss/loki/&#34;&gt;Loki&lt;/a&gt; database.&lt;/p&gt;
&lt;p&gt;To collect Kubernetes logs, you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure a &lt;code&gt;loki.write&lt;/code&gt; component to deliver logs.&lt;/li&gt;
&lt;li&gt;Set up collection components for system logs, Pod logs, or Kubernetes Cluster Events.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;components-used&#34;&gt;Components used&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;&lt;code&gt;discovery.kubernetes&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.relabel/&#34;&gt;&lt;code&gt;discovery.relabel&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/local/local.file_match/&#34;&gt;&lt;code&gt;local.file_match&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.file/&#34;&gt;&lt;code&gt;loki.source.file&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.kubernetes/&#34;&gt;&lt;code&gt;loki.source.kubernetes&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.kubernetes_events/&#34;&gt;&lt;code&gt;loki.source.kubernetes_events&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.process/&#34;&gt;&lt;code&gt;loki.process&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that you&amp;rsquo;re familiar with log labeling when working with Loki.&lt;/li&gt;
&lt;li&gt;Identify where you want to write collected logs.
You can write logs to Loki endpoints such as Grafana Loki, Grafana Cloud, or Grafana Enterprise Logs.&lt;/li&gt;
&lt;li&gt;Ensure that you&amp;rsquo;re familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;configure-logs-delivery&#34;&gt;Configure logs delivery&lt;/h2&gt;
&lt;p&gt;Before components can collect logs, you must have a component responsible for writing those logs somewhere.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt; component delivers logs to a Loki endpoint.
After you define a &lt;code&gt;loki.write&lt;/code&gt; component, other Alloy components can forward logs to it.&lt;/p&gt;
&lt;p&gt;To configure a &lt;code&gt;loki.write&lt;/code&gt; component for logs delivery, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;loki.write&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;loki.write &amp;#34;&amp;lt;LABEL&amp;gt;&amp;#34; {
  endpoint {
    url = &amp;#34;&amp;lt;LOKI_URL&amp;gt;&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;loki.write&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LOKI_URL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The full URL of the Loki endpoint where you send logs, such as &lt;code&gt;https://logs-us-central1.grafana.net/loki/api/v1/push&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your endpoint requires basic authentication, paste the following inside the &lt;code&gt;endpoint&lt;/code&gt; block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;basic_auth {
  username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication password or API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you have more than one endpoint to write logs to, repeat the &lt;code&gt;endpoint&lt;/code&gt; block for additional endpoints.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring &lt;code&gt;loki.write&lt;/code&gt; with multiple endpoints, mixed usage of basic authentication, and a &lt;code&gt;loki.source.file&lt;/code&gt; component.
The &lt;code&gt;loki.source.file&lt;/code&gt; component collects logs from the file system on the Alloy container.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;loki.write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://localhost:3100/loki/api/v1/push&amp;#34;
  }

  endpoint {
    url = &amp;#34;https://logs-us-central1.grafana.net/loki/api/v1/push&amp;#34;

    // Get basic authentication based on environment variables.
    basic_auth {
      username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
      password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
    }
  }
}

loki.source.file &amp;#34;example&amp;#34; {
  // Collect logs from the default listen address.
  targets = [
    {__path__ = &amp;#34;/tmp/foo.txt&amp;#34;, &amp;#34;color&amp;#34; = &amp;#34;pink&amp;#34;},
    {__path__ = &amp;#34;/tmp/bar.txt&amp;#34;, &amp;#34;color&amp;#34; = &amp;#34;blue&amp;#34;},
    {__path__ = &amp;#34;/tmp/baz.txt&amp;#34;, &amp;#34;color&amp;#34; = &amp;#34;grey&amp;#34;},
  ]

  forward_to = [loki.write.default.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The remote write username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The remote write password.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information on configuring logs delivery, refer to &lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;loki.write&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;collect-logs-from-kubernetes&#34;&gt;Collect logs from Kubernetes&lt;/h2&gt;
&lt;p&gt;You can configure Alloy to collect all kinds of logs from Kubernetes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;System logs&lt;/li&gt;
&lt;li&gt;Pod logs&lt;/li&gt;
&lt;li&gt;Kubernetes Events&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the component architecture, you can follow one or all of the following sections.
Complete the &lt;a href=&#34;#configure-logs-delivery&#34;&gt;Configure logs delivery&lt;/a&gt; section first, then proceed to the log type you want to collect.&lt;/p&gt;
&lt;h3 id=&#34;system-logs&#34;&gt;System logs&lt;/h3&gt;
&lt;p&gt;To collect system logs, use the following components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/local/local.file_match/&#34;&gt;&lt;code&gt;local.file_match&lt;/code&gt;&lt;/a&gt;: Discovers files on the local file system.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.file/&#34;&gt;&lt;code&gt;loki.source.file&lt;/code&gt;&lt;/a&gt;: Reads log entries from files.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;: Sends logs to the Loki endpoint.
Configure this component in the &lt;a href=&#34;#configure-logs-delivery&#34;&gt;Configure logs delivery&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following example collects system logs:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// local.file_match discovers files on the local filesystem using glob patterns and the doublestar library. It returns an array of file paths.
local.file_match &amp;#34;node_logs&amp;#34; {
  path_targets = [{
      // Monitor syslog to scrape node-logs
      __path__  = &amp;#34;/var/log/syslog&amp;#34;,
      job       = &amp;#34;node/syslog&amp;#34;,
      node_name = sys.env(&amp;#34;HOSTNAME&amp;#34;),
      cluster   = &amp;lt;CLUSTER_NAME&amp;gt;,
  }]
}

// loki.source.file reads log entries from files and forwards them to other loki.* components.
// You can specify multiple loki.source.file components by giving them different labels.
loki.source.file &amp;#34;node_logs&amp;#34; {
  targets    = local.file_match.node_logs.targets
  forward_to = [loki.write.&amp;lt;WRITE_COMPONENT_NAME&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for this specific Kubernetes cluster, such as &lt;code&gt;production&lt;/code&gt; or &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;WRITE_COMPONENT_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your &lt;code&gt;loki.write&lt;/code&gt; component, such as &lt;code&gt;default&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;pod-logs&#34;&gt;Pod logs&lt;/h3&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;You can also get Pod logs through the log files on each node, but that approach requires system privileges.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;



&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;When you deploy Alloy as a DaemonSet, ensure that you &lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/#limit-to-only-pods-on-the-same-node&#34;&gt;configure discovery&lt;/a&gt; to only collect logs from the same node.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Use the following components to collect Pod logs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;&lt;code&gt;discovery.kubernetes&lt;/code&gt;&lt;/a&gt;: Discovers Pod information and lists them for components to use.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.relabel/&#34;&gt;&lt;code&gt;discovery.relabel&lt;/code&gt;&lt;/a&gt;: Enforces relabeling strategies on the list of Pods.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.kubernetes/&#34;&gt;&lt;code&gt;loki.source.kubernetes&lt;/code&gt;&lt;/a&gt;: Tails logs from a list of Kubernetes Pods targets.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.process/&#34;&gt;&lt;code&gt;loki.process&lt;/code&gt;&lt;/a&gt;: Modifies logs before sending them to the next component.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;: Sends logs to the Loki endpoint.
Configure this component in the &lt;a href=&#34;#configure-logs-delivery&#34;&gt;Configure logs delivery&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following example uses the Kubernetes API to collect logs, which doesn&amp;rsquo;t require system privileges:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// discovery.kubernetes allows you to find scrape targets from Kubernetes resources.
// It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.
discovery.kubernetes &amp;#34;pod&amp;#34; {
  role = &amp;#34;pod&amp;#34;
  // Restrict to pods on the node to reduce cpu &amp;amp; memory usage
  selectors {
    role = &amp;#34;pod&amp;#34;
    field = &amp;#34;spec.nodeName=&amp;#34; &amp;#43; coalesce(sys.env(&amp;#34;HOSTNAME&amp;#34;), constants.hostname)
  }
}

// discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.
// If no rules are defined, then the input targets are exported as-is.
discovery.relabel &amp;#34;pod_logs&amp;#34; {
  targets = discovery.kubernetes.pod.targets

  // Label creation - &amp;#34;namespace&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;namespace&amp;#34;
  }

  // Label creation - &amp;#34;pod&amp;#34; field from &amp;#34;__meta_kubernetes_pod_name&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;pod&amp;#34;
  }

  // Label creation - &amp;#34;container&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;container&amp;#34;
  }

  // Label creation -  &amp;#34;app&amp;#34; field from &amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_label_app_kubernetes_io_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;app&amp;#34;
  }

  // Label creation -  &amp;#34;job&amp;#34; field from &amp;#34;__meta_kubernetes_namespace&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_namespace&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;job&amp;#34;
    separator = &amp;#34;/&amp;#34;
    replacement = &amp;#34;$1&amp;#34;
  }

  // Label creation - &amp;#34;__path__&amp;#34; field from &amp;#34;__meta_kubernetes_pod_uid&amp;#34; and &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;
  // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_uid&amp;#34;, &amp;#34;__meta_kubernetes_pod_container_name&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;__path__&amp;#34;
    separator = &amp;#34;/&amp;#34;
    replacement = &amp;#34;/var/log/pods/*$1/*.log&amp;#34;
  }

  // Label creation -  &amp;#34;container_runtime&amp;#34; field from &amp;#34;__meta_kubernetes_pod_container_id&amp;#34;
  rule {
    source_labels = [&amp;#34;__meta_kubernetes_pod_container_id&amp;#34;]
    action = &amp;#34;replace&amp;#34;
    target_label = &amp;#34;container_runtime&amp;#34;
    regex = `^(\S&amp;#43;):\/\/.&amp;#43;$`
    replacement = &amp;#34;$1&amp;#34;
  }
}

// loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.
loki.source.kubernetes &amp;#34;pod_logs&amp;#34; {
  targets    = discovery.relabel.pod_logs.output
  forward_to = [loki.process.pod_logs.receiver]
}

// loki.process receives log entries from other Loki components, applies one or more processing stages,
// and forwards the results to the list of receivers in the component&amp;#39;s arguments.
loki.process &amp;#34;pod_logs&amp;#34; {
  stage.static_labels {
      values = {
        cluster = &amp;#34;&amp;lt;CLUSTER_NAME&amp;gt;&amp;#34;,
      }
  }

  forward_to = [loki.write.&amp;lt;WRITE_COMPONENT_NAME&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for this specific Kubernetes cluster, such as &lt;code&gt;production&lt;/code&gt; or &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;WRITE_COMPONENT_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your &lt;code&gt;loki.write&lt;/code&gt; component, such as &lt;code&gt;default&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;Use raw strings delimited by backticks for &lt;code&gt;regex&lt;/code&gt; values.
Raw strings don&amp;rsquo;t process escape sequences, so patterns like &lt;code&gt;\S&lt;/code&gt; and &lt;code&gt;\d&lt;/code&gt; work without double escaping.
Double-quoted strings require escaping, for example &lt;code&gt;regex = &amp;quot;\\S&amp;quot;&lt;/code&gt; instead of &lt;code&gt;regex = &amp;quot;\S&amp;quot;&lt;/code&gt;.
If you forget to escape, you get &lt;code&gt;unknown escape sequence&lt;/code&gt; errors.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;



&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Refer to [Limit to only Pods on the same node][discovery.kubernetes_samenode] for more information about restricting to Pods on the same node.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;kubernetes-cluster-events&#34;&gt;Kubernetes Cluster Events&lt;/h3&gt;
&lt;p&gt;Use the following components to collect Kubernetes cluster events:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.kubernetes_events/&#34;&gt;&lt;code&gt;loki.source.kubernetes_events&lt;/code&gt;&lt;/a&gt;: Tails events from the Kubernetes API.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.process/&#34;&gt;&lt;code&gt;loki.process&lt;/code&gt;&lt;/a&gt;: Modifies logs before sending them to the next component.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;: Sends logs to the Loki endpoint.
Configure this component in the &lt;a href=&#34;#configure-logs-delivery&#34;&gt;Configure logs delivery&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following example collects Kubernetes cluster events:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;// loki.source.kubernetes_events tails events from the Kubernetes API and converts them
// into log lines to forward to other Loki components.
loki.source.kubernetes_events &amp;#34;cluster_events&amp;#34; {
  job_name   = &amp;#34;integrations/kubernetes/eventhandler&amp;#34;
  log_format = &amp;#34;logfmt&amp;#34;
  forward_to = [
    loki.process.cluster_events.receiver,
  ]
}

// loki.process receives log entries from other loki components, applies one or more processing stages,
// and forwards the results to the list of receivers in the component&amp;#39;s arguments.
loki.process &amp;#34;cluster_events&amp;#34; {
  forward_to = [loki.write.&amp;lt;WRITE_COMPONENT_NAME&amp;gt;.receiver]

  stage.static_labels {
    values = {
      cluster = &amp;#34;&amp;lt;CLUSTER_NAME&amp;gt;&amp;#34;,
    }
  }

  stage.labels {
    values = {
      kubernetes_cluster_events = &amp;#34;job&amp;#34;,
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for this specific Kubernetes cluster, such as &lt;code&gt;production&lt;/code&gt; or &lt;code&gt;us-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;WRITE_COMPONENT_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your &lt;code&gt;loki.write&lt;/code&gt; component, such as &lt;code&gt;default&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.process/&#34;&gt;Process and transform logs with loki.process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;Configure log delivery endpoints with loki.write&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;Discover Kubernetes resources with discovery.kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="collect-kubernetes-logs-and-forward-them-to-loki">Collect Kubernetes logs and forward them to Loki&lt;/h1>
&lt;p>You can configure Alloy to collect logs and forward them to a &lt;a href="/oss/loki/">Loki&lt;/a> database.&lt;/p>
&lt;p>To collect Kubernetes logs, you:&lt;/p></description></item><item><title>Collect Azure Event Hubs logs and forward them to Loki</title><link>https://grafana.com/docs/alloy/v1.15/collect/azure-event-hubs-logs/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/azure-event-hubs-logs/</guid><content><![CDATA[&lt;h1 id=&#34;collect-azure-event-hubs-logs-and-forward-them-to-loki&#34;&gt;Collect Azure Event Hubs logs and forward them to Loki&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect logs from Azure Event Hubs and forward them to Loki.
For more information about monitoring Azure resources in Grafana Cloud, refer to &lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/&#34;&gt;Monitor Microsoft Azure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This topic describes how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prepare your Azure environment with Workload Identity authentication.&lt;/li&gt;
&lt;li&gt;Configure Azure Event Hubs and install Alloy.&lt;/li&gt;
&lt;li&gt;Optionally extract labels from Azure resource logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;components-used-in-this-topic&#34;&gt;Components used in this topic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.source.azure_event_hubs/&#34;&gt;&lt;code&gt;loki.source.azure_event_hubs&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.process/&#34;&gt;&lt;code&gt;loki.process&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;Ensure you have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Azure administrator access with &lt;code&gt;Microsoft.Authorization/roleAssignments/write&lt;/code&gt; permissions, such as &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Role Based Access Control Administrator&lt;/a&gt; or &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#user-access-administrator&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;User Access Administrator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learn.microsoft.com/en-us/cli/azure/install-azure-cli&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Azure CLI&lt;/a&gt; installed and authenticated&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/tools/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;kubectl&lt;/code&gt;&lt;/a&gt; installed and configured to access your AKS cluster&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://helm.sh/docs/intro/install/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Helm&lt;/a&gt; installed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prepare-your-azure-environment&#34;&gt;Prepare your Azure environment&lt;/h2&gt;
&lt;p&gt;Azure Event Hubs exposes different endpoints depending on the protocol:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Protocol&lt;/th&gt;
              &lt;th&gt;Port&lt;/th&gt;
              &lt;th&gt;When to use&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Kafka&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;9093&lt;/code&gt; (TLS)&lt;/td&gt;
              &lt;td&gt;Applications send events using Kafka clients or Kafka Connect.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;AMQP&lt;/td&gt;
              &lt;td&gt;&lt;code&gt;5671&lt;/code&gt; (TLS)&lt;/td&gt;
              &lt;td&gt;Applications send events using Azure SDKs or AMQP client libraries.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;Both protocols use the hostname &lt;code&gt;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;.servicebus.windows.net&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;loki.source.azure_event_hubs&lt;/code&gt; component uses the Kafka protocol, so the examples in this procedure use port &lt;code&gt;9093&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Use the Azure portal to &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;create or reuse a resource group&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create or reuse an &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-cli&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Azure Kubernetes Service&lt;/a&gt; (AKS) cluster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Microsoft Entra Workload ID&lt;/a&gt; and &lt;a href=&#34;https://learn.microsoft.com/en-us/azure/aks/use-oidc-issuer&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenID Connect&lt;/a&gt; in your AKS cluster.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az aks update \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --name &amp;lt;AKS_CLUSTER_NAME&amp;gt; \
    --enable-oidc-issuer \
    --enable-workload-identity&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;AKS_CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your AKS cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retrieve the OIDC issuer URL for your cluster.
You need this value when creating the federated credential.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az aks show \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --name &amp;lt;AKS_CLUSTER_NAME&amp;gt; \
    --query &amp;#34;oidcIssuerProfile.issuerUrl&amp;#34; \
    --output tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;AKS_CLUSTER_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your AKS cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;a href=&#34;https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;user-assigned managed identity&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az identity create \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --name &amp;lt;MANAGED_IDENTITY_NAME&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MANAGED_IDENTITY_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: A name for your managed identity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retrieve the client ID for your managed identity.
You need this value for the ServiceAccount annotation and Alloy configuration.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az identity show \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --name &amp;lt;MANAGED_IDENTITY_NAME&amp;gt; \
    --query clientId \
    --output tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MANAGED_IDENTITY_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your managed identity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes namespace for Alloy.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;kubectl create namespace alloy&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a Kubernetes ServiceAccount with the workload identity annotation.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;kubectl apply -f - &amp;lt;&amp;lt;EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: alloy
  namespace: alloy
  annotations:
    azure.workload.identity/client-id: &amp;#34;&amp;lt;CLIENT_ID&amp;gt;&amp;#34;
EOF&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;CLIENT_ID&amp;gt;&lt;/code&gt;&lt;/em&gt;: The client ID from the previous step&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;How Azure Workload Identity authentication works&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;&lt;p&gt;Azure Workload Identity connects three components:&lt;/p&gt;
&lt;p&gt;Kubernetes ServiceAccount
: The ServiceAccount annotation &lt;code&gt;azure.workload.identity/client-id&lt;/code&gt; specifies which managed identity the Pod can impersonate.&lt;/p&gt;
&lt;p&gt;Federated credential
: The federated credential on the managed identity trusts tokens from your AKS cluster&amp;rsquo;s OIDC issuer for a specific ServiceAccount (&lt;code&gt;system:serviceaccount:&amp;lt;namespace&amp;gt;:&amp;lt;name&amp;gt;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Runtime token exchange
: When the Pod runs, AKS issues a token for the ServiceAccount.
Azure validates this token against the federated credential and returns an access token for the managed identity.
Alloy uses this token to authenticate to Event Hubs without a connection string.&lt;/p&gt;
&lt;p&gt;If authentication fails, verify:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The OIDC issuer URL matches your cluster&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--subject&lt;/code&gt; value matches &lt;code&gt;system:serviceaccount:&amp;lt;namespace&amp;gt;:&amp;lt;serviceaccount&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The managed identity &lt;code&gt;clientId&lt;/code&gt; matches the ServiceAccount annotation&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--audiences&lt;/code&gt; value is &lt;code&gt;api://AzureADTokenExchange&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a federated identity credential to link your managed identity with the Kubernetes ServiceAccount.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az identity federated-credential create \
    --name alloy-federated-credential \
    --identity-name &amp;lt;MANAGED_IDENTITY_NAME&amp;gt; \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --issuer &amp;lt;OIDC_ISSUER_URL&amp;gt; \
    --subject system:serviceaccount:alloy:alloy \
    --audiences api://AzureADTokenExchange&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MANAGED_IDENTITY_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your managed identity&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;OIDC_ISSUER_URL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The OIDC issuer URL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;!-- vale Grafana.Headings = NO --&gt;
&lt;h2 id=&#34;configure-azure-event-hubs&#34;&gt;Configure Azure Event Hubs&lt;/h2&gt;
&lt;!-- vale Grafana.Headings = YES --&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow the steps to &lt;a href=&#34;/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/config-azure-logs/#set-up-azure-event-hubs&#34;&gt;Set up Azure Event Hubs&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Assign the &lt;code&gt;Azure Event Hubs Data Receiver&lt;/code&gt; role to your managed identity.&lt;/p&gt;
&lt;p&gt;Get the managed identity principal ID:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;PRINCIPAL_ID=$(az identity show \
    --resource-group &amp;lt;RESOURCE_GROUP&amp;gt; \
    --name &amp;lt;MANAGED_IDENTITY_NAME&amp;gt; \
    --query principalId \
    --output tsv)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Assign the role at namespace scope for least-privilege access:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az role assignment create \
    --assignee $PRINCIPAL_ID \
    --role &amp;#34;Azure Event Hubs Data Receiver&amp;#34; \
    --scope /subscriptions/&amp;lt;SUBSCRIPTION_ID&amp;gt;/resourceGroups/&amp;lt;RESOURCE_GROUP&amp;gt;/providers/Microsoft.EventHub/namespaces/&amp;lt;EVENTHUB_NAMESPACE&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;MANAGED_IDENTITY_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your managed identity&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure resource group&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SUBSCRIPTION_ID&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure subscription ID&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;&lt;/code&gt;&lt;/em&gt;: The name of your Event Hub namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;Role assignment scope options&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;&lt;p&gt;Assign the role at the smallest scope that meets your requirements:&lt;/p&gt;
&lt;p&gt;Namespace scope (recommended)
: Grants access only to the specific Event Hub namespace. Use this for least-privilege access.&lt;/p&gt;
&lt;p&gt;Resource group or subscription scope
: Grants access to all Event Hubs in the resource group or subscription. Use this only if Alloy must read from multiple namespaces.&lt;/p&gt;
&lt;p&gt;Example resource group scope:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az role assignment create \
    --assignee $PRINCIPAL_ID \
    --role &amp;#34;Azure Event Hubs Data Receiver&amp;#34; \
    --scope /subscriptions/&amp;lt;SUBSCRIPTION_ID&amp;gt;/resourceGroups/&amp;lt;RESOURCE_GROUP&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To verify the assignment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az role assignment list --assignee $PRINCIPAL_ID --scope &amp;lt;SCOPE&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;install-alloy&#34;&gt;Install Alloy&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the Grafana Helm repository.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;helm repo add grafana https://grafana.github.io/helm-charts
helm repo update&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retrieve the tenant ID for your Azure subscription.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az account show --query tenantId --output tsv&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;values.yaml&lt;/code&gt; file with the following configuration.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-warning&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Warning&lt;/p&gt;&lt;p&gt;Don&amp;rsquo;t store sensitive credentials directly in &lt;code&gt;values.yaml&lt;/code&gt; or commit them to version control.
For production environments, use a Kubernetes Secret with &lt;code&gt;secretKeyRef&lt;/code&gt;, or an external secret manager such as HashiCorp Vault, Azure Key Vault, or the External Secrets Operator.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;The configuration uses port &lt;code&gt;9093&lt;/code&gt; for the Azure Event Hubs Kafka-compatible endpoint.
The &lt;code&gt;loki.source.azure_event_hubs&lt;/code&gt; component in Alloy requires the Kafka-compatible endpoint and doesn&amp;rsquo;t support AMQP for this integration.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;authentication&lt;/code&gt; block uses OAuth 2.0 with Azure Workload Identity through the federated credential you created earlier.
Kafka-compatible endpoints use SASL/OAUTHBEARER with Microsoft Entra ID tokens, so you don&amp;rsquo;t need an Event Hub connection string.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;serviceAccount:
  create: false
  name: alloy

controller:
  type: statefulset
  replicas: 1
  podLabels:
    azure.workload.identity/use: &amp;#34;true&amp;#34;

alloy:
  extraEnv:
    - name: &amp;#34;AZURE_CLIENT_ID&amp;#34;
      value: &amp;#34;&amp;lt;CLIENT_ID&amp;gt;&amp;#34;
    - name: &amp;#34;AZURE_TENANT_ID&amp;#34;
      value: &amp;#34;&amp;lt;TENANT_ID&amp;gt;&amp;#34;
  configMap:
    content: |
      loki.source.azure_event_hubs &amp;#34;azure&amp;#34; {
        fully_qualified_namespace = &amp;#34;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;.servicebus.windows.net:9093&amp;#34;
        event_hubs                = [&amp;#34;&amp;lt;EVENTHUB_NAME&amp;gt;&amp;#34;]

        authentication {
          mechanism = &amp;#34;oauth&amp;#34;
        }

        use_incoming_timestamp = true
        labels = {
          job = &amp;#34;integrations/azure_event_hubs&amp;#34;,
        }
        forward_to = [loki.write.grafana_cloud.receiver]
      }

      loki.write &amp;#34;grafana_cloud&amp;#34; {
        endpoint {
          url = &amp;#34;&amp;lt;GRAFANA_CLOUD_LOKI_URL&amp;gt;&amp;#34;
          basic_auth {
            username = &amp;#34;&amp;lt;GRAFANA_CLOUD_LOKI_USERNAME&amp;gt;&amp;#34;
            password = &amp;#34;&amp;lt;GRAFANA_CLOUD_API_KEY&amp;gt;&amp;#34;
          }
        }
      }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;CLIENT_ID&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your managed identity client ID&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;TENANT_ID&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Azure tenant ID&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Event Hub namespace name&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EVENTHUB_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Event Hub name&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_LOKI_URL&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud Loki endpoint, such as &lt;code&gt;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_LOKI_USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud Loki username&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_API_KEY&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud API key&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Alloy using Helm.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;helm install alloy grafana/alloy \
    --namespace alloy \
    -f values.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;verify-the-installation&#34;&gt;Verify the installation&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Check that the Alloy Pod is running.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;kubectl get pods -n alloy&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see output similar to:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;text&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-text&#34;&gt;NAME      READY   STATUS    RESTARTS   AGE
alloy-0   1/1     Running   0          1m&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check the Alloy logs for any errors.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;kubectl logs -n alloy -l app.kubernetes.io/name=alloy&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;collapse&#34; x-data=&#34;app_collapse()&#34;&gt;
  &lt;button class=&#34;collapse-trigger&#34; @click=&#34;toggle()&#34;&gt;
    &lt;span class=&#34;body-large&#34;&gt;Quick validation tips&lt;/span&gt;
    &lt;span class=&#34;collapse-trigger__icon&#34; :class=&#34;{ &#39;collapse-trigger__icon-open&#39; : open }&#34;&gt;
      
  &lt;svg width=&#34;27&#34; height=&#34;26&#34; viewBox=&#34;0 0 27 26&#34; fill=&#34;none&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;
&lt;path opacity=&#34;0.2&#34; d=&#34;M1.73047 12.8359C1.73047 19.4634 7.10305 24.8359 13.7305 24.8359C20.3579 24.8359 25.7305 19.4634 25.7305 12.8359C25.7305 6.20852 20.3579 0.835937 13.7305 0.835937C7.10305 0.835937 1.73047 6.20852 1.73047 12.8359Z&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M18.2344 12.8359L9.23438 12.8359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;path d=&#34;M13.7344 8.33594L13.7344 17.3359&#34; stroke=&#34;black&#34; stroke-width=&#34;1.5&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;/&gt;
&lt;/svg&gt;


    &lt;/span&gt;
  &lt;/button&gt;
  &lt;div class=&#34;collapse-content&#34; x-ref=&#34;content&#34; hidden=&#34;until-found&#34;&gt;
    &lt;div class=&#34;collapse-content__inner&#34; x-ref=&#34;content-inner&#34;&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Verify authentication and connection:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;kubectl logs -n alloy -l app.kubernetes.io/name=alloy | grep -E -i &amp;#34;authenticated|connected|sasl&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Push a test event to the Event Hub and confirm a matching log appears in Grafana Explore within approximately one minute.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If errors occur, verify the role assignment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;az role assignment list --assignee &amp;lt;PRINCIPAL_ID&amp;gt; --scope &amp;lt;SCOPE&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Grafana Cloud, navigate to &lt;strong&gt;Explore&lt;/strong&gt; and select your Loki data source to view the incoming logs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;optional-configure-alloy-to-extract-labels-from-azure-event-hubs&#34;&gt;Optional: Configure Alloy to extract labels from Azure Event Hubs&lt;/h2&gt;
&lt;p&gt;By default, the Alloy configuration doesn&amp;rsquo;t extract labels from the Event Hubs log lines.&lt;/p&gt;
&lt;p&gt;You can configure Alloy to use &lt;code&gt;loki.process&lt;/code&gt; to extract labels such as &lt;code&gt;resourceId&lt;/code&gt;, &lt;code&gt;category&lt;/code&gt;, and &lt;code&gt;resourceGroup&lt;/code&gt; from Azure resource logs.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;loki.process&lt;/code&gt; component uses three stages to transform the logs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;stage.json&lt;/code&gt;&lt;/strong&gt;: Parses the log line as JSON and extracts the &lt;code&gt;resourceId&lt;/code&gt; and &lt;code&gt;category&lt;/code&gt; fields.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;stage.regex&lt;/code&gt;&lt;/strong&gt;: Parses the &lt;code&gt;resourceId&lt;/code&gt; to extract resource details like &lt;code&gt;subscriptionId&lt;/code&gt;, &lt;code&gt;resourceGroup&lt;/code&gt;, and &lt;code&gt;resourceName&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;stage.labels&lt;/code&gt;&lt;/strong&gt;: Creates Loki labels from the extracted values for easier querying.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Update the &lt;code&gt;alloy.configMap.content&lt;/code&gt; section in your &lt;code&gt;values.yaml&lt;/code&gt; file with the following configuration.&lt;/p&gt;
&lt;p&gt;When set to &lt;code&gt;true&lt;/code&gt;, the &lt;code&gt;use_incoming_timestamp&lt;/code&gt; setting uses the event&amp;rsquo;s timestamp, such as Event Hubs &lt;code&gt;EnqueuedTimeUtc&lt;/code&gt; or a &lt;code&gt;timestamp&lt;/code&gt; field in the payload.
The default is &lt;code&gt;false&lt;/code&gt;, which uses Alloy ingestion time.
Keep the default if your events lack reliable timestamps.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;alloy:
  configMap:
    content: |
      loki.source.azure_event_hubs &amp;#34;azure&amp;#34; {
        fully_qualified_namespace = &amp;#34;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;.servicebus.windows.net:9093&amp;#34;
        event_hubs                = [&amp;#34;&amp;lt;EVENTHUB_NAME&amp;gt;&amp;#34;]

        authentication {
          mechanism = &amp;#34;oauth&amp;#34;
        }

        use_incoming_timestamp = true
        labels = {
          job = &amp;#34;integrations/azure_event_hubs&amp;#34;,
        }
        forward_to = [loki.process.azure_logs.receiver]
      }

      loki.process &amp;#34;azure_logs&amp;#34; {
        stage.json {
          expressions = {
            resourceId = &amp;#34;resourceId&amp;#34;,
            category   = &amp;#34;category&amp;#34;,
          }
        }

        stage.regex {
          expression = &amp;#34;(?i)/subscriptions/(?P&amp;lt;subscriptionId&amp;gt;[^/]&amp;#43;)/resourcegroups/(?P&amp;lt;resourceGroup&amp;gt;[^/]&amp;#43;)/providers/(?P&amp;lt;providerNamespace&amp;gt;[^/]&amp;#43;)/(?P&amp;lt;resourceType&amp;gt;[^/]&amp;#43;)/(?P&amp;lt;resourceName&amp;gt;[^/]&amp;#43;)&amp;#34;
          source     = &amp;#34;resourceId&amp;#34;
        }

        stage.labels {
          values = {
            category       = &amp;#34;&amp;#34;,
            resourceId     = &amp;#34;&amp;#34;,
            resourceGroup  = &amp;#34;&amp;#34;,
            service_name   = &amp;#34;resourceName&amp;#34;,
          }
        }

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

      loki.write &amp;#34;grafana_cloud&amp;#34; {
        endpoint {
          url = &amp;#34;&amp;lt;GRAFANA_CLOUD_LOKI_URL&amp;gt;&amp;#34;
          basic_auth {
            username = &amp;#34;&amp;lt;GRAFANA_CLOUD_LOKI_USERNAME&amp;gt;&amp;#34;
            password = &amp;#34;&amp;lt;GRAFANA_CLOUD_API_KEY&amp;gt;&amp;#34;
          }
        }
      }&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EVENTHUB_NAMESPACE&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Event Hub namespace name&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EVENTHUB_NAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Event Hub name&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_LOKI_URL&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud Loki endpoint, such as &lt;code&gt;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_LOKI_USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud Loki username&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;GRAFANA_CLOUD_API_KEY&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud API key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After updating the configuration, upgrade the Helm release:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;helm upgrade alloy grafana/alloy \
    --namespace alloy \
    -f values.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="collect-azure-event-hubs-logs-and-forward-them-to-loki">Collect Azure Event Hubs logs and forward them to Loki&lt;/h1>
&lt;p>You can configure Alloy to collect logs from Azure Event Hubs and forward them to Loki.
For more information about monitoring Azure resources in Grafana Cloud, refer to &lt;a href="/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/">Monitor Microsoft Azure&lt;/a>.&lt;/p></description></item><item><title>Collect Prometheus metrics</title><link>https://grafana.com/docs/alloy/v1.15/collect/prometheus-metrics/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/prometheus-metrics/</guid><content><![CDATA[&lt;h1 id=&#34;collect-prometheus-metrics&#34;&gt;Collect Prometheus metrics&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect &lt;a href=&#34;https://prometheus.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus&lt;/a&gt; metrics and forward them to any Prometheus-compatible database.&lt;/p&gt;
&lt;p&gt;This topic describes how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure metrics delivery.&lt;/li&gt;
&lt;li&gt;Collect metrics from Kubernetes Pods.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;components-used-in-this-topic&#34;&gt;Components used in this topic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;&lt;code&gt;discovery.kubernetes&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;&lt;code&gt;prometheus.remote_write&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that you have basic familiarity with instrumenting applications with Prometheus.&lt;/li&gt;
&lt;li&gt;Have a set of Prometheus exports or applications exposing Prometheus metrics that you want to collect metrics from.&lt;/li&gt;
&lt;li&gt;Identify where to write collected metrics.
Metrics can be written to Prometheus or Prometheus-compatible endpoints such as Grafana Mimir, Grafana Cloud, or Grafana Enterprise Metrics.&lt;/li&gt;
&lt;li&gt;Be familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;configure-metrics-delivery&#34;&gt;Configure metrics delivery&lt;/h2&gt;
&lt;p&gt;Before components can collect Prometheus metrics, you must have a component responsible for writing those metrics somewhere.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;&lt;code&gt;prometheus.remote_write&lt;/code&gt;&lt;/a&gt; component is responsible for delivering Prometheus metrics to one or more Prometheus-compatible endpoints.
After a &lt;code&gt;prometheus.remote_write&lt;/code&gt; component is defined, you can use other Alloy components to forward metrics to it.&lt;/p&gt;
&lt;p&gt;To configure a &lt;code&gt;prometheus.remote_write&lt;/code&gt; component for metrics delivery, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.remote_write&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.remote_write &amp;#34;&amp;lt;LABEL&amp;gt;&amp;#34; {
  endpoint {
    url = &amp;#34;&amp;lt;PROMETHEUS_URL&amp;gt;&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;prometheus.remote_write&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PROMETHEUS_URL&amp;gt;&lt;/code&gt;&lt;/em&gt; The full URL of the Prometheus-compatible endpoint where metrics are sent, such as &lt;code&gt;https://prometheus-us-central1.grafana.net/api/v1/write&lt;/code&gt; for Prometheus or &lt;code&gt;https://mimir-us-central1.grafana.net/api/v1/push/&lt;/code&gt; for Mimir. The endpoint URL depends on the database you use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your endpoint requires basic authentication, paste the following inside the &lt;code&gt;endpoint&lt;/code&gt; block.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;basic_auth {
  username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication password or API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you have more than one endpoint to write metrics to, repeat the &lt;code&gt;endpoint&lt;/code&gt; block for additional endpoints.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring &lt;code&gt;prometheus.remote_write&lt;/code&gt; with multiple endpoints and mixed usage of basic authentication, and a &lt;code&gt;prometheus.scrape&lt;/code&gt; component which forwards metrics to it.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://localhost:9009/api/prom/push&amp;#34;
  }

  endpoint {
    url = &amp;#34;https://prometheus-us-central1.grafana.net/api/prom/push&amp;#34;

    // Get basic authentication based on environment variables.
    basic_auth {
      username = sys.env(&amp;#34;&amp;lt;REMOTE_WRITE_USERNAME&amp;gt;&amp;#34;)
      password = sys.env(&amp;#34;&amp;lt;REMOTE_WRITE_PASSWORD&amp;gt;&amp;#34;)
    }
  }
}

prometheus.scrape &amp;#34;example&amp;#34; {
  // Collect metrics from the default listen address.
  targets = [{
    __address__ = &amp;#34;127.0.0.1:12345&amp;#34;,
  }]

  forward_to = [prometheus.remote_write.default.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on configuring metrics delivery, refer to &lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;prometheus.remote_write&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;collect-metrics-from-kubernetes-pods&#34;&gt;Collect metrics from Kubernetes Pods&lt;/h2&gt;
&lt;p&gt;Alloy can be configured to collect metrics from Kubernetes Pods by:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Discovering Kubernetes Pods to collect metrics from.&lt;/li&gt;
&lt;li&gt;Collecting metrics from those discovered Pods.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To collect metrics from Kubernetes Pods, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow &lt;a href=&#34;#configure-metrics-delivery&#34;&gt;Configure metrics delivery&lt;/a&gt; to ensure collected metrics can be written somewhere.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover Kubernetes Pods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;discovery.kubernetes&lt;/code&gt; component to your configuration file to discover every Pod in the cluster across all Namespaces.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;discovery.kubernetes &amp;#34;&amp;lt;DISCOVERY_LABEL&amp;gt;&amp;#34; {
  role = &amp;#34;pod&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DISCOVERY_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;pods&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;discovery.kubernetes&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This generates one Prometheus target for every exposed port on every discovered Pod.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To limit the Namespaces that Pods are discovered in, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;namespaces {
  own_namespace = true
  names         = [&amp;lt;NAMESPACE_NAMES&amp;gt;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;NAMESPACE_NAMES&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of strings representing Namespaces to search.
Each string must be wrapped in double quotes. For example, &lt;code&gt;&amp;quot;default&amp;quot;,&amp;quot;kube-system&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&amp;rsquo;t want to search for Pods in the Namespace Alloy is running in, set &lt;code&gt;own_namespace&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To use a field selector to limit the number of discovered Pods, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;selectors {
  role  = &amp;#34;pod&amp;#34;
  field = &amp;#34;&amp;lt;FIELD_SELECTOR&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;FIELD_SELECTOR&amp;gt;&lt;/code&gt;&lt;/em&gt;: The Kubernetes field selector to use, such as &lt;code&gt;metadata.name=my-service&lt;/code&gt;.
For more information on field selectors, refer to the Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Field Selectors&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create additional &lt;code&gt;selectors&lt;/code&gt; blocks for each field selector you want to apply.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To use a label selector to limit the number of discovered Pods, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;selectors {
  role  = &amp;#34;pod&amp;#34;
  label = &amp;#34;LABEL_SELECTOR&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LABEL_SELECTOR&amp;gt;&lt;/code&gt;&lt;/em&gt;: The Kubernetes label selector, such as &lt;code&gt;environment in (production, qa)&lt;/code&gt;.
For more information on label selectors, refer to the Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#set-based-requirement&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Labels and Selectors&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create additional &lt;code&gt;selectors&lt;/code&gt; blocks for each label selector you want to apply.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Collect metrics from discovered Pods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.scrape&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;&amp;lt;SCRAPE_LABEL&amp;gt;&amp;#34; {
  targets    = discovery.kubernetes.&amp;lt;DISCOVERY_LABEL&amp;gt;.targets
  forward_to = [prometheus.remote_write.&amp;lt;REMOTE_WRITE_LABEL&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SCRAPE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;pods&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;prometheus.scrape&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DISCOVERY_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;REMOTE_WRITE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for your &lt;code&gt;prometheus.remote_write&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring Alloy to collect metrics from running production Kubernetes Pods in the &lt;code&gt;default&lt;/code&gt; Namespace.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;discovery.kubernetes &amp;#34;pods&amp;#34; {
  role = &amp;#34;pod&amp;#34;

  namespaces {
    own_namespace = false

    names = [&amp;#34;default&amp;#34;]
  }

  selectors {
    role  = &amp;#34;pod&amp;#34;
    label = &amp;#34;environment in (production)&amp;#34;
  }
}

prometheus.scrape &amp;#34;pods&amp;#34; {
  targets    = discovery.kubernetes.pods.targets
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://localhost:9009/api/prom/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on configuring Kubernetes service delivery and collecting metrics, refer to &lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;&lt;code&gt;discovery.kubernetes&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;collect-metrics-from-kubernetes-services&#34;&gt;Collect metrics from Kubernetes Services&lt;/h2&gt;
&lt;p&gt;You can configure Alloy to collect metrics from Kubernetes Services by:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Discovering Kubernetes Services to collect metrics from.&lt;/li&gt;
&lt;li&gt;Collecting metrics from those discovered Services.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To collect metrics from Kubernetes Services, complete the following steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow &lt;a href=&#34;#configure-metrics-delivery&#34;&gt;Configure metrics delivery&lt;/a&gt; to ensure collected metrics can be written somewhere.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Discover Kubernetes Services:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;discovery.kubernetes&lt;/code&gt; component to your configuration file to discover every Services in the cluster across all Namespaces.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;discovery.kubernetes &amp;#34;&amp;lt;DISCOVERY_LABEL&amp;gt;&amp;#34; {
  role = &amp;#34;service&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DISCOVERY_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: A label for the component, such as &lt;code&gt;services&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;discovery.kubernetes&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This generates one Prometheus target for every exposed port on every discovered Service.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To limit the Namespaces that Services are discovered in, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;namespaces {
  own_namespace = true
  names         = [&amp;lt;NAMESPACE_NAMES&amp;gt;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;NAMESPACE_NAMES&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of strings representing Namespaces to search.
Each string must be wrapped in double quotes. For example, &lt;code&gt;&amp;quot;default&amp;quot;,&amp;quot;kube-system&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&amp;rsquo;t want to search for Services in the Namespace Alloy is running in, set &lt;code&gt;own_namespace&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To use a field selector to limit the number of discovered Services, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;selectors {
  role  = &amp;#34;service&amp;#34;
  field = &amp;#34;&amp;lt;FIELD_SELECTOR&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;FIELD_SELECTOR&amp;gt;&lt;/code&gt;&lt;/em&gt;: The Kubernetes field selector, such as &lt;code&gt;metadata.name=my-service&lt;/code&gt;.
For more information on field selectors, refer to the Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Field Selectors&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create additional &lt;code&gt;selectors&lt;/code&gt; blocks for each field selector you want to apply.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To use a label selector to limit the number of discovered Services, add the following block inside the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;selectors {
  role  = &amp;#34;service&amp;#34;
  label = &amp;#34;&amp;lt;LABEL_SELECTOR&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LABEL_SELECTOR&amp;gt;&lt;/code&gt;&lt;/em&gt;: The Kubernetes label selector, such as &lt;code&gt;environment in (production, qa)&lt;/code&gt;.
For more information on label selectors, refer to the Kubernetes documentation on &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#set-based-requirement&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Labels and Selectors&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Create additional &lt;code&gt;selectors&lt;/code&gt; blocks for each label selector you want to apply.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Collect metrics from discovered Services:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.scrape&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;&amp;lt;SCRAPE_LABEL&amp;gt;&amp;#34; {
  targets    = discovery.kubernetes.&amp;lt;DISCOVERY_LABEL&amp;gt;.targets
  forward_to = [prometheus.remote_write.&amp;lt;REMOTE_WRITE_LABEL&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;SCRAPE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;services&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;prometeus.scrape&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;DISCOVERY_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the &lt;code&gt;discovery.kubernetes&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;REMOTE_WRITE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for your &lt;code&gt;prometheus.remote_write&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring Alloy to collect metrics from running production Kubernetes Services in the &lt;code&gt;default&lt;/code&gt; Namespace.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;discovery.kubernetes &amp;#34;services&amp;#34; {
  role = &amp;#34;service&amp;#34;

  namespaces {
    own_namespace = false

    names = [&amp;#34;default&amp;#34;]
  }

  selectors {
    role  = &amp;#34;service&amp;#34;
    label = &amp;#34;environment in (production)&amp;#34;
  }
}

prometheus.scrape &amp;#34;services&amp;#34; {
  targets    = discovery.kubernetes.services.targets
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://localhost:9009/api/prom/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on configuring Kubernetes service delivery and collecting metrics, refer to &lt;a href=&#34;../../reference/components/discovery/discovery.kubernetes/&#34;&gt;&lt;code&gt;discovery.kubernetes&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;../../reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;collect-metrics-from-custom-targets&#34;&gt;Collect metrics from custom targets&lt;/h2&gt;
&lt;p&gt;You can configure Alloy to collect metrics from a custom set of targets without the need for service discovery.&lt;/p&gt;
&lt;p&gt;To collect metrics from a custom set of targets, complete the following steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow &lt;a href=&#34;#configure-metrics-delivery&#34;&gt;Configure metrics delivery&lt;/a&gt; to ensure collected metrics can be written somewhere.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;prometheus.scrape&lt;/code&gt; component to your configuration file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;&amp;lt;SCRAPE_LABEL&amp;gt;&amp;#34; {
  targets    = [&amp;lt;TARGET_LIST&amp;gt;]
  forward_to = [prometheus.remote_write.&amp;lt;REMOTE_WRITE_LABEL&amp;gt;.receiver]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;_&lt;code&gt;&amp;lt;SCRAPE_LABEL&amp;gt;&lt;/code&gt;: The label for the component, such as &lt;code&gt;custom_targets&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;prometheus.scrape&lt;/code&gt; components in the same configuration file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;&amp;lt;TARGET_LIST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of &lt;a href=&#34;../../get-started/configuration-syntax/expressions/types_and_values/#objects&#34;&gt;Objects&lt;/a&gt; denoting the Prometheus target.
Each object must conform to the following rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There must be an &lt;code&gt;__address__&lt;/code&gt; key denoting the &lt;code&gt;HOST:PORT&lt;/code&gt; of the target to collect metrics from.&lt;/li&gt;
&lt;li&gt;To explicitly specify which protocol to use, set the &lt;code&gt;__scheme__&lt;/code&gt; key to &lt;code&gt;&amp;quot;http&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;https&amp;quot;&lt;/code&gt;.
If the &lt;code&gt;__scheme__&lt;/code&gt; key isn&amp;rsquo;t provided, the protocol to use is inherited by the settings of the &lt;code&gt;prometheus.scrape&lt;/code&gt; component. The default is &lt;code&gt;&amp;quot;http&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To explicitly specify which HTTP path to collect metrics from, set the &lt;code&gt;__metrics_path__&lt;/code&gt; key to the HTTP path to use.
If the &lt;code&gt;__metrics_path__&lt;/code&gt; key isn&amp;rsquo;t provided, the path to use is inherited by the settings of the &lt;code&gt;prometheus.scrape&lt;/code&gt; component. The default is &lt;code&gt;&amp;quot;/metrics&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add additional keys as desired to inject extra labels to collected metrics.
Any label starting with two underscores (&lt;code&gt;__&lt;/code&gt;) is dropped prior to scraping.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;&amp;lt;REMOTE_WRITE_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for your &lt;code&gt;prometheus.remote_write&lt;/code&gt; component.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring &lt;code&gt;prometheus.scrape&lt;/code&gt; to collect metrics from a custom set of endpoints.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;custom_targets&amp;#34; {
  targets = [
    {
      __address__ = &amp;#34;prometheus:9090&amp;#34;,
    },
    {
      __address__ = &amp;#34;mimir:8080&amp;#34;,
      __scheme__  = &amp;#34;https&amp;#34;,
    },
    {
      __address__      = &amp;#34;custom-application:80&amp;#34;,
      __metrics_path__ = &amp;#34;/custom-metrics–path&amp;#34;,
    },
    {
      __address__ = &amp;#34;alloy:12345&amp;#34;,
      application = &amp;#34;alloy&amp;#34;,
      environment = &amp;#34;production&amp;#34;,
    },
  ]

  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://localhost:9009/api/prom/push&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="collect-prometheus-metrics">Collect Prometheus metrics&lt;/h1>
&lt;p>You can configure Alloy to collect &lt;a href="https://prometheus.io" target="_blank" rel="noopener noreferrer">Prometheus&lt;/a> metrics and forward them to any Prometheus-compatible database.&lt;/p>
&lt;p>This topic describes how to:&lt;/p>
&lt;ul>
&lt;li>Configure metrics delivery.&lt;/li>
&lt;li>Collect metrics from Kubernetes Pods.&lt;/li>
&lt;/ul>
&lt;h2 id="components-used-in-this-topic">Components used in this topic&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="../../reference/components/discovery/discovery.kubernetes/">&lt;code>discovery.kubernetes&lt;/code>&lt;/a>&lt;/li>
&lt;li>&lt;a href="../../reference/components/prometheus/prometheus.remote_write/">&lt;code>prometheus.remote_write&lt;/code>&lt;/a>&lt;/li>
&lt;li>&lt;a href="../../reference/components/prometheus/prometheus.scrape/">&lt;code>prometheus.scrape&lt;/code>&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="before-you-begin">Before you begin&lt;/h2>
&lt;ul>
&lt;li>Ensure that you have basic familiarity with instrumenting applications with Prometheus.&lt;/li>
&lt;li>Have a set of Prometheus exports or applications exposing Prometheus metrics that you want to collect metrics from.&lt;/li>
&lt;li>Identify where to write collected metrics.
Metrics can be written to Prometheus or Prometheus-compatible endpoints such as Grafana Mimir, Grafana Cloud, or Grafana Enterprise Metrics.&lt;/li>
&lt;li>Be familiar with the concept of &lt;a href="../../get-started/components/">Components&lt;/a> in Alloy.&lt;/li>
&lt;/ul>
&lt;h2 id="configure-metrics-delivery">Configure metrics delivery&lt;/h2>
&lt;p>Before components can collect Prometheus metrics, you must have a component responsible for writing those metrics somewhere.&lt;/p></description></item><item><title>Collect OpenTelemetry data and forward it to any OpenTelemetry-compatible endpoint</title><link>https://grafana.com/docs/alloy/v1.15/collect/opentelemetry-data/</link><pubDate>Mon, 13 Apr 2026 06:53:30 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/opentelemetry-data/</guid><content><![CDATA[&lt;h1 id=&#34;collect-opentelemetry-data-and-forward-it-to-any-opentelemetry-compatible-endpoint&#34;&gt;Collect OpenTelemetry data and forward it to any OpenTelemetry-compatible endpoint&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect &lt;a href=&#34;https://opentelemetry.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry&lt;/a&gt;-compatible data and forward it to any OpenTelemetry-compatible endpoint.&lt;/p&gt;
&lt;p&gt;This topic describes how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure OpenTelemetry data delivery.&lt;/li&gt;
&lt;li&gt;Configure batching.&lt;/li&gt;
&lt;li&gt;Receive OpenTelemetry data over OTLP.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;components-used-in-this-topic&#34;&gt;Components used in this topic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.auth.basic/&#34;&gt;&lt;code&gt;otelcol.auth.basic&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlphttp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlphttp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.processor.batch/&#34;&gt;&lt;code&gt;otelcol.processor.batch&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.receiver.otlp/&#34;&gt;&lt;code&gt;otelcol.receiver.otlp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that you have basic familiarity with instrumenting applications with OpenTelemetry.&lt;/li&gt;
&lt;li&gt;Have a set of OpenTelemetry applications ready to push telemetry data to Alloy.&lt;/li&gt;
&lt;li&gt;Identify where Alloy writes received telemetry data.&lt;/li&gt;
&lt;li&gt;Be familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;configure-an-opentelemetry-protocol-exporter&#34;&gt;Configure an OpenTelemetry Protocol exporter&lt;/h2&gt;
&lt;p&gt;Before components can receive OpenTelemetry data, you must have a component responsible for exporting the OpenTelemetry data.
An OpenTelemetry &lt;em&gt;exporter component&lt;/em&gt; is responsible for writing (exporting) OpenTelemetry data to an external system.&lt;/p&gt;
&lt;p&gt;In this task, you use the &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlp&lt;/code&gt;&lt;/a&gt; component to send OpenTelemetry data to a server using the OpenTelemetry Protocol (OTLP).
After an exporter component is defined, you can use other Alloy components to forward data to it.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-tip&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Tip&lt;/p&gt;&lt;p&gt;Refer to the list of available &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; for the full list of &lt;code&gt;otelcol.exporter&lt;/code&gt; components that you can use to export OpenTelemetry data.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To configure an &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component for exporting OpenTelemetry data using OTLP, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component to your configuration file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;&amp;lt;EXPORTER_LABEL&amp;gt;&amp;#34; {
  client {
    endpoint = &amp;#34;&amp;lt;HOST&amp;gt;:&amp;lt;PORT&amp;gt;&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EXPORTER_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt;: The hostname or IP address of the server to send OTLP requests to.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PORT&amp;gt;&lt;/code&gt;&lt;/em&gt;: The port of the server to send OTLP requests to.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your server requires basic authentication, complete the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.auth.basic&lt;/code&gt; component to your configuration file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.auth.basic &amp;#34;&amp;lt;BASIC_AUTH_LABEL&amp;gt;&amp;#34; {
  username = &amp;#34;&amp;lt;USERNAME&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;PASSWORD&amp;gt;&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;BASIC_AUTH_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;otelcol.auth.basic&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;USERNAME&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication username.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PASSWORD&amp;gt;&lt;/code&gt;&lt;/em&gt;: The basic authentication password or API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following line inside of the &lt;code&gt;client&lt;/code&gt; block of your &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;auth = otelcol.auth.basic.&amp;lt;BASIC_AUTH_LABEL&amp;gt;.handler&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;BASIC_AUTH_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the &lt;code&gt;otelcol.auth.basic&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you have more than one server to export metrics to, create an &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component for each additional server.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;&lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; sends data using OTLP over gRPC (HTTP/2).
To send to a server using HTTP/1.1, follow the preceding steps, but use the &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlphttp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlphttp&lt;/code&gt;&lt;/a&gt; component instead.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;The following example demonstrates configuring &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; with authentication and a component that forwards data to it:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;my-otlp-grpc-server:4317&amp;#34;
    auth     = otelcol.auth.basic.credentials.handler
  }
}

otelcol.auth.basic &amp;#34;credentials&amp;#34; {
  // Retrieve credentials using environment variables.

  username = sys.env(&amp;#34;BASIC_AUTH_USER&amp;#34;)
  password = sys.env(&amp;#34;API_KEY&amp;#34;)
}

otelcol.receiver.otlp &amp;#34;example&amp;#34; {
  grpc {
    endpoint = &amp;#34;127.0.0.1:4317&amp;#34;
  }

  http {
    endpoint = &amp;#34;127.0.0.1:4318&amp;#34;
  }

  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on writing OpenTelemetry data using the OpenTelemetry Protocol, refer to &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlp&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;configure-batching&#34;&gt;Configure batching&lt;/h2&gt;
&lt;p&gt;Production-ready Alloy configurations shouldn&amp;rsquo;t send OpenTelemetry data directly to an exporter for delivery.
Instead, data is usually sent to one or more &lt;em&gt;processor components&lt;/em&gt; that perform various transformations on the data.&lt;/p&gt;
&lt;p&gt;Ensuring data is batched is a production-readiness step to improve data compression and reduce the number of outgoing network requests to external systems.&lt;/p&gt;
&lt;p&gt;In this task, you configure an &lt;a href=&#34;../../reference/components/otelcol/otelcol.processor.batch/&#34;&gt;&lt;code&gt;otelcol.processor.batch&lt;/code&gt;&lt;/a&gt; component to batch data before sending it to the exporter.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Refer to the list of available &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; for the full list of &lt;code&gt;otelcol.processor&lt;/code&gt; components that you can use to process OpenTelemetry data.
You can chain processors by having one processor send data to another processor.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To configure an &lt;code&gt;otelcol.processor.batch&lt;/code&gt; component, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow &lt;a href=&#34;#configure-an-opentelemetry-protocol-exporter&#34;&gt;Configure an OpenTelemetry Protocol exporter&lt;/a&gt; to ensure received data can be written to an external system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.processor.batch&lt;/code&gt; component into your configuration file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.processor.batch &amp;#34;&amp;lt;PROCESSOR_LABEL&amp;gt;&amp;#34; {
  output {
    metrics = [otelcol.exporter.otlp.&amp;lt;EXPORTER_LABEL&amp;gt;.input]
    logs    = [otelcol.exporter.otlp.&amp;lt;EXPORTER_LABEL&amp;gt;.input]
    traces  = [otelcol.exporter.otlp.&amp;lt;EXPORTER_LABEL&amp;gt;.input]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;PROCESSOR_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;otelcol.processor.batch&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;EXPORTER_LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for your &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To disable one of the telemetry types, set the relevant type in the &lt;code&gt;output&lt;/code&gt; block to the empty list, such as &lt;code&gt;metrics = []&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To send batched data to another processor, replace the components in the &lt;code&gt;output&lt;/code&gt; list with the processor components to use.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring a sequence of &lt;code&gt;otelcol.processor&lt;/code&gt; components before being exported.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.processor.memory_limiter &amp;#34;default&amp;#34; {
  check_interval = &amp;#34;1s&amp;#34;
  limit          = &amp;#34;1GiB&amp;#34;

  output {
    metrics = [otelcol.processor.batch.default.input]
    logs    = [otelcol.processor.batch.default.input]
    traces  = [otelcol.processor.batch.default.input]
  }
}

otelcol.processor.batch &amp;#34;default&amp;#34; {
  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;my-otlp-grpc-server:4317&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on configuring OpenTelemetry data batching, refer to &lt;a href=&#34;../../reference/components/otelcol/otelcol.processor.batch/&#34;&gt;&lt;code&gt;otelcol.processor.batch&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;configure-an-opentelemetry-protocol-receiver&#34;&gt;Configure an OpenTelemetry Protocol receiver&lt;/h2&gt;
&lt;p&gt;You can configure Alloy to receive OpenTelemetry metrics, logs, and traces.
An OpenTelemetry &lt;em&gt;receiver&lt;/em&gt; component is responsible for receiving OpenTelemetry data from an external system.&lt;/p&gt;
&lt;p&gt;In this task, you use the &lt;a href=&#34;../../reference/components/otelcol/otelcol.receiver.otlp/&#34;&gt;&lt;code&gt;otelcol.receiver.otlp&lt;/code&gt;&lt;/a&gt; component to receive OpenTelemetry data over the network using the OpenTelemetry Protocol (OTLP).
You can configure a receiver component to forward received data to other Alloy components.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Refer to the list of available &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; for the full list of
&lt;code&gt;otelcol.receiver&lt;/code&gt; components that you can use to receive
OpenTelemetry-compatible data.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;To configure an &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; component for receiving OTLP data, complete the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Follow &lt;a href=&#34;#configure-an-opentelemetry-protocol-exporter&#34;&gt;Configure an OpenTelemetry Protocol exporter&lt;/a&gt; to ensure received data can be written to an external system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optional: Follow &lt;a href=&#34;#configure-batching&#34;&gt;Configure batching&lt;/a&gt; to improve compression and reduce the total amount of network requests.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; component to your configuration file.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.otlp &amp;#34;&amp;lt;LABEL&amp;gt;&amp;#34; {
  output {
    metrics = [&amp;lt;COMPONENT_INPUT_LIST&amp;gt;]
    logs    = [&amp;lt;COMPONENT_INPUT_LIST&amp;gt;]
    traces  = [&amp;lt;COMPONENT_INPUT_LIST&amp;gt;]
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;LABEL&amp;gt;&lt;/code&gt;&lt;/em&gt;: The label for the component, such as &lt;code&gt;default&lt;/code&gt;.
The label you use must be unique across all &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; components in the same configuration file.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;COMPONENT_INPUT_LIST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A comma-delimited list of component inputs to forward received data to.
For example, to send data to a batch processor component, use &lt;code&gt;otelcol.processor.batch.PROCESSOR_LABEL.input&lt;/code&gt;.
To send data directly to an exporter component, use &lt;code&gt;otelcol.exporter.otlp.EXPORTER_LABEL.input&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To allow applications to send OTLP data over gRPC on port &lt;code&gt;4317&lt;/code&gt;, add the following to your &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;grpc {
  endpoint = &amp;#34;&amp;lt;HOST&amp;gt;:4317&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt;: A host to listen to traffic on. Use a narrowly scoped listen address whenever possible.
To listen on all network interfaces, replace &lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt; with &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To allow applications to send OTLP data over HTTP/1.1 on port &lt;code&gt;4318&lt;/code&gt;, add the following to your &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;http {
  endpoint = &amp;#34;&amp;lt;HOST&amp;gt;:4318&amp;#34;
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt;: The host to listen to traffic on. Use a narrowly scoped listen address whenever possible.
To listen on all network interfaces, replace &lt;em&gt;&lt;code&gt;&amp;lt;HOST&amp;gt;&lt;/code&gt;&lt;/em&gt; with &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To disable one of the telemetry types, set the relevant type in the &lt;code&gt;output&lt;/code&gt; block to the empty list, such as &lt;code&gt;metrics = []&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following example demonstrates configuring &lt;code&gt;otelcol.receiver.otlp&lt;/code&gt; and sending it to an exporter:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.otlp &amp;#34;example&amp;#34; {
  grpc {
    endpoint = &amp;#34;127.0.0.1:4317&amp;#34;
  }

  http {
    endpoint = &amp;#34;127.0.0.1:4318&amp;#34;
  }

  output {
    metrics = [otelcol.processor.batch.example.input]
    logs    = [otelcol.processor.batch.example.input]
    traces  = [otelcol.processor.batch.example.input]
  }
}

otelcol.processor.batch &amp;#34;example&amp;#34; {
  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;my-otlp-grpc-server:4317&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For more information on receiving OpenTelemetry data using the OpenTelemetry Protocol, refer to &lt;a href=&#34;../../reference/components/otelcol/otelcol.receiver.otlp/&#34;&gt;&lt;code&gt;otelcol.receiver.otlp&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
]]></content><description>&lt;h1 id="collect-opentelemetry-data-and-forward-it-to-any-opentelemetry-compatible-endpoint">Collect OpenTelemetry data and forward it to any OpenTelemetry-compatible endpoint&lt;/h1>
&lt;p>You can configure Alloy to collect &lt;a href="https://opentelemetry.io" target="_blank" rel="noopener noreferrer">OpenTelemetry&lt;/a>-compatible data and forward it to any OpenTelemetry-compatible endpoint.&lt;/p></description></item><item><title>Collect OpenTelemetry data and forward to Grafana</title><link>https://grafana.com/docs/alloy/v1.15/collect/opentelemetry-to-lgtm-stack/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/opentelemetry-to-lgtm-stack/</guid><content><![CDATA[&lt;h1 id=&#34;collect-opentelemetry-data-and-forward-to-grafana&#34;&gt;Collect OpenTelemetry data and forward to Grafana&lt;/h1&gt;
&lt;p&gt;You can configure Alloy to collect &lt;a href=&#34;https://opentelemetry.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry&lt;/a&gt;-compatible data and forward it to the Grafana stack.&lt;/p&gt;
&lt;p&gt;This topic describes how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure Alloy to send your data to Loki.&lt;/li&gt;
&lt;li&gt;Configure Alloy to send your data to Tempo.&lt;/li&gt;
&lt;li&gt;Configure Alloy to send your data to Mimir or Prometheus Remote Write.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;components-used-in-this-topic&#34;&gt;Components used in this topic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.auth.basic/&#34;&gt;&lt;code&gt;otelcol.auth.basic&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.loki/&#34;&gt;&lt;code&gt;otelcol.exporter.loki&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.otlphttp/&#34;&gt;&lt;code&gt;otelcol.exporter.otlphttp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.prometheus/&#34;&gt;&lt;code&gt;otelcol.exporter.prometheus&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.processor.batch/&#34;&gt;&lt;code&gt;otelcol.processor.batch&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.processor.memory_limiter/&#34;&gt;&lt;code&gt;otelcol.processor.memory_limiter&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/otelcol/otelcol.receiver.otlp/&#34;&gt;&lt;code&gt;otelcol.receiver.otlp&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;&lt;code&gt;prometheus.remote_write&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that you have basic familiarity with instrumenting applications with OpenTelemetry.&lt;/li&gt;
&lt;li&gt;Have a set of OpenTelemetry applications ready to push telemetry data to Alloy.&lt;/li&gt;
&lt;li&gt;Identify where Alloy writes received telemetry data.&lt;/li&gt;
&lt;li&gt;Be familiar with the concept of &lt;a href=&#34;../../get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;li&gt;Complete the &lt;a href=&#34;../opentelemetry-data/&#34;&gt;Collect open telemetry data&lt;/a&gt; task.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-pipeline&#34;&gt;The pipeline&lt;/h2&gt;
&lt;p&gt;You can start with the Alloy configuration you created in the &lt;a href=&#34;../opentelemetry-data/&#34;&gt;Collect open telemetry data&lt;/a&gt; task.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.otlp &amp;#34;example&amp;#34; {
  grpc {
    endpoint = &amp;#34;127.0.0.1:4317&amp;#34;
  }

  http {
    endpoint = &amp;#34;127.0.0.1:4318&amp;#34;
  }

  output {
    metrics = [otelcol.processor.batch.example.input]
    logs    = [otelcol.processor.batch.example.input]
    traces  = [otelcol.processor.batch.example.input]
  }
}

otelcol.processor.batch &amp;#34;example&amp;#34; {
  output {
    metrics = [otelcol.exporter.otlp.default.input]
    logs    = [otelcol.exporter.otlp.default.input]
    traces  = [otelcol.exporter.otlp.default.input]
  }
}

otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;my-otlp-grpc-server:4317&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The pipeline looks like this:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;plaintext&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-plaintext&#34;&gt;Metrics, Logs, Traces: OTLP Receiver → Batch Processor → OTLP HTTP Exporter&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;grafana-cloud&#34;&gt;Grafana Cloud&lt;/h2&gt;
&lt;p&gt;Grafana Cloud provides OTLP Endpoints that you can use directly from within Alloy.&lt;/p&gt;
&lt;p&gt;You can find the OTLP connection details from the OpenTelemetry &lt;strong&gt;Details&lt;/strong&gt; page in the &lt;a href=&#34;/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack&#34;&gt;Grafana Cloud Portal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You must update the configuration file as follows:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.auth.basic &amp;#34;default&amp;#34; {
  username = &amp;#34;&amp;lt;ACCOUNT ID&amp;gt;&amp;#34;
  password = &amp;#34;&amp;lt;API TOKEN&amp;gt;&amp;#34;
}

otelcol.exporter.otlphttp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;&amp;lt;OTLP_ENDPOINT&amp;gt;&amp;#34;
    auth     = otelcol.auth.basic.default.handler
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Replace the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;ACCOUNT ID&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud account ID.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;API TOKEN&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your Grafana Cloud API token.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;&amp;lt;OTLP_ENDPOINT&amp;gt;&lt;/code&gt;&lt;/em&gt;: Your OTLP endpoint.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This configuration uses the credentials stored in &lt;code&gt;otelcol.auth.basic &amp;quot;default&amp;quot;&lt;/code&gt; to authenticate against the Grafana Cloud OTLP endpoints, and you should start to see your data arrive.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;For Grafana Cloud, use &lt;code&gt;otelcol.exporter.otlphttp&lt;/code&gt; which sends data over HTTP/HTTPS.
Use &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; for gRPC endpoints when working with other platforms.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;other-platforms-grafana-enterprise-and-grafana-open-source&#34;&gt;Other platforms: Grafana Enterprise and Grafana Open Source&lt;/h2&gt;
&lt;p&gt;You can implement the following pipelines to send your data to Loki, Tempo, and Mimir or Prometheus.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;plaintext&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-plaintext&#34;&gt;Metrics: OTLP Receiver → Batch Processor → Prometheus Exporter → Prometheus Remote Write
Logs: OTLP Receiver → Batch Processor → Loki Exporter → Loki Write  
Traces: OTLP Receiver → Batch Processor → OTLP Exporter (gRPC/HTTP)&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;grafana-loki&#34;&gt;Grafana Loki&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/oss/loki/&#34;&gt;Grafana Loki&lt;/a&gt; is a horizontally scalable, highly available, multi-tenant log aggregation system inspired by Prometheus.
Similar to Prometheus, to send from OTLP to Loki, you can configure pass-through from the &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.loki/&#34;&gt;&lt;code&gt;otelcol.exporter.loki&lt;/code&gt;&lt;/a&gt; component to &lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt; component.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.loki &amp;#34;default&amp;#34; {
  forward_to = [loki.write.default.receiver]
}

loki.write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://loki-endpoint:8080/loki/api/v1/push&amp;#34;
        }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To use Loki with basic-auth, which Grafana Cloud Logs requires, you must configure the &lt;a href=&#34;../../reference/components/loki/loki.write/&#34;&gt;&lt;code&gt;loki.write&lt;/code&gt;&lt;/a&gt; component.
You can get the Loki configuration from the Loki &lt;strong&gt;Details&lt;/strong&gt; page in the &lt;a href=&#34;/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack&#34;&gt;Grafana Cloud Portal&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.loki &amp;#34;grafana_cloud_logs&amp;#34; {
  forward_to = [loki.write.grafana_cloud_logs.receiver]
}

loki.write &amp;#34;grafana_cloud_logs&amp;#34; {
  endpoint {
    url = &amp;#34;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&amp;#34;

    basic_auth {
      username = &amp;#34;5252&amp;#34;
      password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;grafana-tempo&#34;&gt;Grafana Tempo&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;/oss/tempo/&#34;&gt;Grafana Tempo&lt;/a&gt; is an open source, scalable distributed tracing backend.
Tempo can ingest OTLP directly, and you can use the OTLP exporter to send the traces to Tempo.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;default&amp;#34; {
  client {
    endpoint = &amp;#34;tempo-server:4317&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To use Tempo with basic-auth, which Grafana Cloud Traces requires, you must use the &lt;a href=&#34;../../reference/components/otelcol/otelcol.auth.basic/&#34;&gt;otelcol.auth.basic&lt;/a&gt; component.
You can get the Tempo configuration from the Tempo &lt;strong&gt;Details&lt;/strong&gt; page in the &lt;a href=&#34;/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack&#34;&gt;Grafana Cloud Portal&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlphttp &amp;#34;grafana_cloud_traces&amp;#34; {
  client {
    endpoint = &amp;#34;https://tempo-us-central1.grafana.net:443&amp;#34;
    auth     = otelcol.auth.basic.grafana_cloud_traces.handler
  }
}

otelcol.auth.basic &amp;#34;grafana_cloud_traces&amp;#34; {
  username = &amp;#34;4094&amp;#34;
  password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;grafana-mimir-or-prometheus-remote-write&#34;&gt;Grafana Mimir or Prometheus Remote Write&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus Remote Write&lt;/a&gt; is a popular metrics transmission protocol supported by most metrics systems, including &lt;a href=&#34;/oss/mimir/&#34;&gt;Grafana Mimir&lt;/a&gt; and Grafana Cloud.
To send from OTLP to a Prometheus compatible &lt;code&gt;remote_write&lt;/code&gt; endpoint, you can configure pass-through from the &lt;a href=&#34;../../reference/components/otelcol/otelcol.exporter.prometheus/&#34;&gt;&lt;code&gt;otelcol.exporter.prometheus&lt;/code&gt;&lt;/a&gt; to the &lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;&lt;code&gt;prometheus.remote_write&lt;/code&gt;&lt;/a&gt; component.
The Prometheus remote write component in Alloy is a robust protocol implementation, including a Write Ahead Log (WAL) for resiliency.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.prometheus &amp;#34;default&amp;#34; {
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = &amp;#34;http://prometheus:9090/api/v1/write&amp;#34;
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To use Prometheus with basic-auth, which Grafana Cloud Metrics requires, you must configure the &lt;a href=&#34;../../reference/components/prometheus/prometheus.remote_write/&#34;&gt;&lt;code&gt;prometheus.remote_write&lt;/code&gt;&lt;/a&gt; component.
You can get the Prometheus configuration from the Prometheus &lt;strong&gt;Details&lt;/strong&gt; page in the &lt;a href=&#34;/docs/grafana-cloud/account-management/cloud-portal/#your-grafana-cloud-stack&#34;&gt;Grafana Cloud Portal&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.prometheus &amp;#34;grafana_cloud_metrics&amp;#34; {
        forward_to = [prometheus.remote_write.grafana_cloud_metrics.receiver]
    }

prometheus.remote_write &amp;#34;grafana_cloud_metrics&amp;#34; {
    endpoint {
        url = &amp;#34;https://prometheus-us-central1.grafana.net/api/prom/push&amp;#34;

        basic_auth {
            username = &amp;#34;12690&amp;#34;
            password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;put-it-all-together&#34;&gt;Put it all together&lt;/h3&gt;
&lt;p&gt;Instead of referencing &lt;code&gt;otelcol.exporter.otlp.default.input&lt;/code&gt; in the output of &lt;code&gt;otelcol.processor.batch&lt;/code&gt;, you need to reference the three exporters you set up.
For Grafana Cloud, use &lt;code&gt;otelcol.exporter.otlphttp&lt;/code&gt; for traces to send data over HTTPS.
The final configuration becomes:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.otlp &amp;#34;example&amp;#34; {
  grpc {
    endpoint = &amp;#34;127.0.0.1:4317&amp;#34;
  }

  http {
    endpoint = &amp;#34;127.0.0.1:4318&amp;#34;
  }

  output {
    metrics = [otelcol.processor.batch.example.input]
    logs    = [otelcol.processor.batch.example.input]
    traces  = [otelcol.processor.batch.example.input]
  }
}

otelcol.processor.batch &amp;#34;example&amp;#34; {
  output {
    metrics = [otelcol.exporter.prometheus.grafana_cloud_metrics.input]
    logs    = [otelcol.exporter.loki.grafana_cloud_logs.input]
    traces  = [otelcol.exporter.otlphttp.grafana_cloud_traces.input]
  }
}

otelcol.exporter.otlphttp &amp;#34;grafana_cloud_traces&amp;#34; {
  client {
    endpoint = &amp;#34;https://tempo-us-central1.grafana.net:443&amp;#34;
    auth     = otelcol.auth.basic.grafana_cloud_traces.handler
  }
}

otelcol.auth.basic &amp;#34;grafana_cloud_traces&amp;#34; {
  username = &amp;#34;4094&amp;#34;
  password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}

otelcol.exporter.prometheus &amp;#34;grafana_cloud_metrics&amp;#34; {
        forward_to = [prometheus.remote_write.grafana_cloud_metrics.receiver]
    }

prometheus.remote_write &amp;#34;grafana_cloud_metrics&amp;#34; {
    endpoint {
        url = &amp;#34;https://prometheus-us-central1.grafana.net/api/prom/push&amp;#34;

        basic_auth {
            username = &amp;#34;12690&amp;#34;
            password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
        }
    }
}

otelcol.exporter.loki &amp;#34;grafana_cloud_logs&amp;#34; {
  forward_to = [loki.write.grafana_cloud_logs.receiver]
}

loki.write &amp;#34;grafana_cloud_logs&amp;#34; {
  endpoint {
    url = &amp;#34;https://logs-prod-us-central1.grafana.net/loki/api/v1/push&amp;#34;

    basic_auth {
      username = &amp;#34;5252&amp;#34;
      password = sys.env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Running Alloy gives you the following:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;plaintext&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-plaintext&#34;&gt;./alloy run alloy-config.alloy
./alloy run alloy-config.alloy
ts=2023-05-09T09:37:15.300959Z level=info msg=&amp;#34;running usage stats reporter&amp;#34;
ts=2023-05-09T09:37:15.300958Z level=info msg=&amp;#34;now listening for http traffic&amp;#34; addr=127.0.0.1:12345
ts=2023-05-09T09:37:15.301104Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;starting complete graph evaluation&amp;#34;
ts=2023-05-09T09:37:15.301307Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=loki.write.grafana_cloud_logs duration=188.209µs
ts=2023-05-09T09:37:15.301334Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.exporter.loki.grafana_cloud_logs duration=18.791µs
ts=2023-05-09T09:37:15.303138Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg=&amp;#34;replaying WAL, this may take a while&amp;#34; dir=data-alloy/prometheus.remote_write.grafana_cloud_metrics/wal
ts=2023-05-09T09:37:15.303257Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg=&amp;#34;WAL segment loaded&amp;#34; segment=0 maxSegment=1
ts=2023-05-09T09:37:15.303302Z component=prometheus.remote_write.grafana_cloud_metrics level=info subcomponent=wal msg=&amp;#34;WAL segment loaded&amp;#34; segment=1 maxSegment=1
ts=2023-05-09T09:37:15.303507Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg=&amp;#34;Starting WAL watcher&amp;#34; queue=7f623a
ts=2023-05-09T09:37:15.303515Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg=&amp;#34;Starting scraped metadata watcher&amp;#34;
ts=2023-05-09T09:37:15.303522Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=prometheus.remote_write.grafana_cloud_metrics duration=2.181958ms
ts=2023-05-09T09:37:15.303557Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.exporter.prometheus.grafana_cloud_metrics duration=30.083µs
ts=2023-05-09T09:37:15.303611Z component=prometheus.remote_write.grafana_cloud_metrics subcomponent=rw level=info remote_name=7f623a url=https://prometheus-us-central1.grafana.net/api/prom/push msg=&amp;#34;Replaying WAL&amp;#34; queue=7f623a
ts=2023-05-09T09:37:15.303618Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.auth.basic.grafana_cloud_traces duration=52.5µs
ts=2023-05-09T09:37:15.303694Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.exporter.otlphttp.grafana_cloud_traces duration=70.375µs
ts=2023-05-09T09:37:15.303782Z component=otelcol.processor.memory_limiter.default level=info msg=&amp;#34;Memory limiter configured&amp;#34; limit_mib=150 spike_limit_mib=30 check_interval=1s
ts=2023-05-09T09:37:15.303802Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.processor.memory_limiter.default duration=100.334µs
ts=2023-05-09T09:37:15.303853Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.processor.batch.default duration=44.75µs
ts=2023-05-09T09:37:15.303948Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=otelcol.receiver.otlp.default duration=87.333µs
ts=2023-05-09T09:37:15.303968Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=tracing duration=10.792µs
ts=2023-05-09T09:37:15.303981Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished node evaluation&amp;#34; node_id=logging duration=9µs
ts=2023-05-09T09:37:15.303987Z level=info trace_id=6466516c9e1a556422df7a84c0ade6b0 msg=&amp;#34;finished complete graph evaluation&amp;#34; duration=2.960333ms
ts=2023-05-09T09:37:15.304Z level=info msg=&amp;#34;scheduling loaded components&amp;#34;
ts=2023-05-09T09:37:15.304109Z component=otelcol.receiver.otlp.default level=info msg=&amp;#34;Starting GRPC server&amp;#34; endpoint=0.0.0.0:4317
ts=2023-05-09T09:37:15.304234Z component=otelcol.receiver.otlp.default level=info msg=&amp;#34;Starting HTTP server&amp;#34; endpoint=0.0.0.0:4318&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can check the pipeline graphically by visiting &lt;a href=&#34;http://localhost:12345/graph&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;http://localhost:12345/graph&lt;/a&gt;&lt;/p&gt;
&lt;figure
    class=&#34;figure-wrapper figure-wrapper__lightbox w-100p &#34;
    style=&#34;max-width: 1876px;&#34;
    itemprop=&#34;associatedMedia&#34;
    itemscope=&#34;&#34;
    itemtype=&#34;http://schema.org/ImageObject&#34;
  &gt;&lt;a
        class=&#34;lightbox-link&#34;
        href=&#34;/media/docs/alloy/otlp-lgtm-graph.png&#34;
        itemprop=&#34;contentUrl&#34;
      &gt;&lt;div class=&#34;img-wrapper w-100p h-auto&#34;&gt;&lt;img
          class=&#34;lazyload &#34;
          data-src=&#34;/media/docs/alloy/otlp-lgtm-graph.png&#34;data-srcset=&#34;/media/docs/alloy/otlp-lgtm-graph.png?w=320 320w, /media/docs/alloy/otlp-lgtm-graph.png?w=550 550w, /media/docs/alloy/otlp-lgtm-graph.png?w=750 750w, /media/docs/alloy/otlp-lgtm-graph.png?w=900 900w, /media/docs/alloy/otlp-lgtm-graph.png?w=1040 1040w, /media/docs/alloy/otlp-lgtm-graph.png?w=1240 1240w, /media/docs/alloy/otlp-lgtm-graph.png?w=1920 1920w&#34;data-sizes=&#34;auto&#34;alt=&#34;Graphical representation of a healthy pipeline&#34;width=&#34;1876&#34;height=&#34;1302&#34;/&gt;
        &lt;noscript&gt;
          &lt;img
            src=&#34;/media/docs/alloy/otlp-lgtm-graph.png&#34;
            alt=&#34;Graphical representation of a healthy pipeline&#34;width=&#34;1876&#34;height=&#34;1302&#34;/&gt;
        &lt;/noscript&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;
]]></content><description>&lt;h1 id="collect-opentelemetry-data-and-forward-to-grafana">Collect OpenTelemetry data and forward to Grafana&lt;/h1>
&lt;p>You can configure Alloy to collect &lt;a href="https://opentelemetry.io" target="_blank" rel="noopener noreferrer">OpenTelemetry&lt;/a>-compatible data and forward it to the Grafana stack.&lt;/p>
&lt;p>This topic describes how to:&lt;/p></description></item><item><title>Collect Amazon Elastic Container Service or AWS Fargate OpenTelemetry data</title><link>https://grafana.com/docs/alloy/v1.15/collect/ecs-opentelemetry-data/</link><pubDate>Mon, 30 Mar 2026 15:47:22 +0000</pubDate><guid>https://grafana.com/docs/alloy/v1.15/collect/ecs-opentelemetry-data/</guid><content><![CDATA[&lt;h1 id=&#34;collect-amazon-elastic-container-service-or-aws-fargate-opentelemetry-data&#34;&gt;Collect Amazon Elastic Container Service or AWS Fargate OpenTelemetry data&lt;/h1&gt;
&lt;p&gt;You can configure Grafana Alloy or AWS ADOT to collect OpenTelemetry-compatible data from Amazon Elastic Container Service (ECS) or AWS Fargate and forward it to any OpenTelemetry-compatible endpoint.&lt;/p&gt;
&lt;p&gt;Metrics are available from various sources including ECS itself, the ECS instances when using EC2, X-Ray, and your own application.
You can also collect logs and traces from your applications instrumented for Prometheus or OTLP.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;#collect-task-and-container-metrics&#34;&gt;Collect task and container metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#collect-application-telemetry&#34;&gt;Collect application telemetry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#collect-ec2-instance-metrics&#34;&gt;Collect EC2 instance metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#collect-logs&#34;&gt;Collect application logs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that you have basic familiarity with instrumenting applications with OpenTelemetry.&lt;/li&gt;
&lt;li&gt;Have an available Amazon ECS or AWS Fargate deployment.&lt;/li&gt;
&lt;li&gt;Identify where Alloy writes received telemetry data.&lt;/li&gt;
&lt;li&gt;Familiarize yourself with the concept of 
    &lt;a href=&#34;/docs/alloy/v1.15/get-started/components/&#34;&gt;Components&lt;/a&gt; in Alloy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;collect-task-and-container-metrics&#34;&gt;Collect task and container metrics&lt;/h2&gt;
&lt;p&gt;In this configuration, you add an OpenTelemetry Collector to the task running your application, and it uses the ECS Metadata Endpoint to gather task and container metrics in your cluster.&lt;/p&gt;
&lt;p&gt;You can choose between two collector implementations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You can use ADOT, the AWS OpenTelemetry collector. ADOT has native support for scraping task and container metrics. ADOT comes with default configurations that you can select in the task definition.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use Alloy with either the 
    &lt;a href=&#34;/docs/alloy/v1.15/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics/&#34;&gt;&lt;code&gt;otelcol.receiver.awsecscontainermetrics&lt;/code&gt;&lt;/a&gt; component or the &lt;a href=&#34;https://github.com/prometheus-community/ecs_exporter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus ECS exporter&lt;/a&gt; sidecar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;configure-adot&#34;&gt;Configure ADOT&lt;/h3&gt;
&lt;p&gt;If you use ADOT as a collector, add a container to your task definition and use a custom configuration you define in your AWS Systems Manager Parameter Store.&lt;/p&gt;
&lt;p&gt;You can find sample OpenTelemetry configuration files in the &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/tree/main/config/ecs&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AWS Observability repository&lt;/a&gt;.
You can use these samples as a starting point and add the appropriate exporter configuration to send metrics to a Prometheus or OpenTelemetry endpoint.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/config/ecs/ecs-default-config.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;ecs-default-config&lt;/code&gt;&lt;/a&gt; to consume StatsD metrics, OTLP metrics and traces, and AWS X-Ray SDK traces.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/config/ecs/container-insights/otel-task-metrics-config.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;otel-task-metrics-config&lt;/code&gt;&lt;/a&gt; to consume StatsD, OTLP, AWS X-Ray, and Container Resource utilization metrics.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/357f9c7b8896dba6ee0e03b8efd7ca7117024d2e/config/ecs/ecs-amp-xray-prometheus.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;otel-prometheus&lt;/code&gt;&lt;/a&gt; to find out how to set the Prometheus remote write. The example uses AWS managed Prometheus.&lt;/p&gt;
&lt;p&gt;Complete the following steps to create a sample task. Refer to the &lt;a href=&#34;https://aws-otel.github.io/docs/setup/ecs&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ADOT doc&lt;/a&gt; for more information.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a Parameter Store entry to hold the collector configuration file.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open the AWS Console.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the AWS Console, choose &lt;strong&gt;Parameter Store&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose &lt;strong&gt;Create parameter&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a parameter with the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;collector-config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tier:&lt;/strong&gt; Standard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type:&lt;/strong&gt; String&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data type:&lt;/strong&gt; Text&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value:&lt;/strong&gt; Copy and paste your custom OpenTelemetry configuration file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/examples/ecs/aws-cloudwatch/ecs-fargate-sidecar.json&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ECS Fargate&lt;/a&gt; or &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/examples/ecs/aws-prometheus/ecs-ec2-task-def.json&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ECS EC2&lt;/a&gt; task definition template from GitHub.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the task definition template and add the following parameters.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;{{region}}&lt;/code&gt;&lt;/em&gt;: The region to send the data to.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;{{ecsTaskRoleArn}}&lt;/code&gt;&lt;/em&gt;: The AWSOTTaskRole ARN.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;code&gt;{{ecsTaskExecutionRoleArn}}&lt;/code&gt;&lt;/em&gt;: The AWSOTTaskExecutionRole ARN.&lt;/li&gt;
&lt;li&gt;Add an environment variable named &lt;code&gt;AOT_CONFIG_CONTENT&lt;/code&gt;. Select &lt;strong&gt;ValueFrom&lt;/strong&gt; to tell ECS to get the value from the Parameter Store, and set the value to &lt;code&gt;collector-config&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow the ECS Fargate setup instructions to &lt;a href=&#34;https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;create a task definition&lt;/a&gt; using the template.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;configure-alloy&#34;&gt;Configure Alloy&lt;/h3&gt;
&lt;p&gt;Alloy offers two approaches for collecting ECS task and container metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Native receiver:&lt;/strong&gt; Use the 
    &lt;a href=&#34;/docs/alloy/v1.15/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics/&#34;&gt;&lt;code&gt;otelcol.receiver.awsecscontainermetrics&lt;/code&gt;&lt;/a&gt; component to read the ECS Task Metadata Endpoint V4 directly. This approach is simpler but requires enabling experimental features.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prometheus exporter:&lt;/strong&gt; Use the &lt;a href=&#34;https://github.com/prometheus-community/ecs_exporter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus ECS exporter&lt;/a&gt; as a sidecar container and scrape metrics with &lt;code&gt;prometheus.scrape&lt;/code&gt;. This approach requires an additional container.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;native-receiver&#34;&gt;Native receiver&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;otelcol.receiver.awsecscontainermetrics&lt;/code&gt; component reads AWS ECS task- and container-level metadata, and resource usage metrics such as CPU, memory, network, and disk, and forwards them to other otelcol.* components.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The &lt;code&gt;otelcol.receiver.awsecscontainermetrics&lt;/code&gt; component is experimental. You must set the &lt;code&gt;--stability.level=experimental&lt;/code&gt; flag to use it. Refer to 
    &lt;a href=&#34;/docs/alloy/v1.15/reference/cli/run/#permitted-stability-levels&#34;&gt;Permitted stability levels&lt;/a&gt; for more information.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;Use the following as a starting point for your Alloy configuration:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.receiver.awsecscontainermetrics &amp;#34;default&amp;#34; {
  collection_interval = &amp;#34;60s&amp;#34;

  output {
    metrics = [otelcol.exporter.otlphttp.default.input]
  }
}

otelcol.exporter.otlphttp &amp;#34;default&amp;#34; {
  client {
    endpoint = sys.env(&amp;#34;OTLP_ENDPOINT&amp;#34;)

    auth = otelcol.auth.basic.default.handler
  }
}

otelcol.auth.basic &amp;#34;default&amp;#34; {
  client_auth {
    username = sys.env(&amp;#34;OTLP_USERNAME&amp;#34;)
    password = sys.env(&amp;#34;OTLP_PASSWORD&amp;#34;)
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This configuration collects ECS task and container metrics every 60 seconds and exports them to an OTLP endpoint.&lt;/p&gt;
&lt;h4 id=&#34;prometheus-exporter&#34;&gt;Prometheus exporter&lt;/h4&gt;
&lt;p&gt;You don&amp;rsquo;t need to enable experimental stability in Alloy to use the ECS exporter as a sidecar container.&lt;/p&gt;
&lt;p&gt;Use the following as a starting point for your Alloy configuration:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;prometheus.scrape &amp;#34;ecs&amp;#34; {
  targets    = [{&amp;#34;__address__&amp;#34; = &amp;#34;localhost:9779&amp;#34;}]
  forward_to = [prometheus.remote_write.default.receiver]
}

prometheus.remote_write &amp;#34;default&amp;#34; {
  endpoint {
    url = sys.env(&amp;#34;PROMETHEUS_REMOTE_WRITE_URL&amp;#34;)

    basic_auth {
      username = sys.env(&amp;#34;PROMETHEUS_USERNAME&amp;#34;)
      password = sys.env(&amp;#34;PROMETHEUS_PASSWORD&amp;#34;)
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This configuration scrapes metrics from the ECS exporter running on port 9779 and exports them to a Prometheus endpoint.&lt;/p&gt;
&lt;h4 id=&#34;deploy-the-task&#34;&gt;Deploy the task&lt;/h4&gt;
&lt;p&gt;Complete the following steps to create a sample task.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a Parameter Store entry to hold the collector configuration file.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open the AWS Console.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the AWS Console, choose &lt;strong&gt;Parameter Store&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose &lt;strong&gt;Create parameter&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a parameter with the following values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;collector-config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tier:&lt;/strong&gt; Standard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type:&lt;/strong&gt; String&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data type:&lt;/strong&gt; Text&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value:&lt;/strong&gt; Copy and paste your custom Alloy configuration file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/examples/ecs/aws-cloudwatch/ecs-fargate-sidecar.json&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ECS Fargate&lt;/a&gt; or &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/examples/ecs/aws-prometheus/ecs-ec2-task-def.json&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ECS EC2&lt;/a&gt; task definition template from GitHub.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the task definition template and add the following parameters.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;{{region}}&lt;/code&gt;&lt;/em&gt;: The region to send the data to.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;{{ecsTaskRoleArn}}&lt;/code&gt;&lt;/em&gt;: The AWSOTTaskRole ARN.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;{{ecsTaskExecutionRoleArn}}&lt;/code&gt;&lt;/em&gt;: The AWSOTTaskExecutionRole ARN.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set the container image to &lt;code&gt;grafana/alloy:&amp;lt;VERSION&amp;gt;&lt;/code&gt;, for example &lt;code&gt;grafana/alloy:latest&lt;/code&gt; or a specific version such as &lt;code&gt;grafana/alloy:v1.8.0&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a custom environment variable named &lt;code&gt;ALLOY_CONFIG_CONTENT&lt;/code&gt;. Select &lt;strong&gt;ValueFrom&lt;/strong&gt; to tell ECS to get the value from the Parameter Store, and set the value to &lt;code&gt;collector-config&lt;/code&gt;. Alloy doesn&amp;rsquo;t read this variable directly, but you use it with the command below to pass the configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add environment variables for your endpoint.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For the native receiver:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OTLP_ENDPOINT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OTLP_USERNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OTLP_PASSWORD&lt;/code&gt; - For increased security, create a password in AWS Secrets Manager and reference the ARN of the secret in the &lt;strong&gt;ValueFrom&lt;/strong&gt; field.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For the Prometheus exporter:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PROMETHEUS_REMOTE_WRITE_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROMETHEUS_USERNAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROMETHEUS_PASSWORD&lt;/code&gt; - For increased security, create a password in AWS Secrets Manager and reference the ARN of the secret in the &lt;strong&gt;ValueFrom&lt;/strong&gt; field.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the Docker configuration, change the &lt;strong&gt;Entrypoint&lt;/strong&gt; to &lt;code&gt;/bin/sh,-c&lt;/code&gt;. This allows the command to use shell features like redirection and chaining.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;{{command}}&lt;/code&gt;&lt;/em&gt;: For the native receiver, use &lt;code&gt;&amp;quot;printenv ALLOY_CONFIG_CONTENT &amp;gt; /tmp/config_file &amp;amp;&amp;amp; exec /bin/alloy run --stability.level=experimental --server.http.listen-addr=0.0.0.0:12345 /tmp/config_file&amp;quot;&lt;/code&gt;. The &lt;code&gt;--stability.level=experimental&lt;/code&gt; flag enables the use of the &lt;code&gt;otelcol.receiver.awsecscontainermetrics&lt;/code&gt; component.&lt;/p&gt;
&lt;p&gt;For the Prometheus exporter, use &lt;code&gt;&amp;quot;printenv ALLOY_CONFIG_CONTENT &amp;gt; /tmp/config_file &amp;amp;&amp;amp; exec /bin/alloy run --server.http.listen-addr=0.0.0.0:12345 /tmp/config_file&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Make sure you include the double quotes around the command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prometheus exporter only:&lt;/strong&gt; Add the Prometheus ECS exporter as a sidecar container:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add a container to the task.&lt;/li&gt;
&lt;li&gt;Set the container name to &lt;code&gt;ecs-exporter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the image to a pinned version of the exporter, for example &lt;code&gt;quay.io/prometheuscommunity/ecs-exporter:v0.1.1&lt;/code&gt;. Check the &lt;a href=&#34;https://github.com/prometheus-community/ecs_exporter/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;ecs_exporter&lt;/code&gt; releases&lt;/a&gt; for the latest stable version. You should avoid using the &lt;code&gt;latest&lt;/code&gt; tag in production.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;tcp/9779&lt;/code&gt; as a port mapping.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow the ECS Fargate setup instructions to &lt;a href=&#34;https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;create a task definition&lt;/a&gt; using the template.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;collect-ec2-instance-metrics&#34;&gt;Collect EC2 instance metrics&lt;/h2&gt;
&lt;p&gt;For ECS Clusters running on EC2, you can collect instance metrics by using AWS ADOT or Alloy in a separate ECS task deployed as a daemon.&lt;/p&gt;
&lt;h3 id=&#34;collect-metrics-with-alloy&#34;&gt;Collect metrics with Alloy&lt;/h3&gt;
&lt;p&gt;You can follow the steps described in &lt;a href=&#34;#configure-alloy&#34;&gt;Configure Alloy&lt;/a&gt; to create another task, with the following changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you&amp;rsquo;re using the &lt;code&gt;awsecscontainermetrics&lt;/code&gt; receiver, you don&amp;rsquo;t need to add the ecs-exporter sidecar for EC2 instance metrics.&lt;/li&gt;
&lt;li&gt;Run the task as a daemon so it automatically runs one instance per node in your cluster.&lt;/li&gt;
&lt;li&gt;Update your Alloy configuration to collect metrics from the instance.
The configuration varies depending on the type of EC2 node. Refer to the &lt;a href=&#34;/docs/alloy/latest/collect/&#34;&gt;&lt;code&gt;collect&lt;/code&gt;&lt;/a&gt; documentation for details.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;collect-metrics-with-adot&#34;&gt;Collect metrics with ADOT&lt;/h3&gt;
&lt;p&gt;The approach described in &lt;a href=&#34;https://aws-otel.github.io/docs/setup/ecs#3-setup-the-adot-collector-for-ecs-ec2-instance-metrics&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;the AWS OpenTelemetry documentation&lt;/a&gt; uses the &lt;code&gt;awscontainerinsightreceiver&lt;/code&gt; receiver from OpenTelemetry. ADOT includes this receiver.&lt;/p&gt;
&lt;p&gt;You need to use a custom configuration Parameter Store entry based on the &lt;a href=&#34;https://github.com/aws-observability/aws-otel-collector/blob/main/config/ecs/otel-instance-metrics-config.yaml&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;sample&lt;/a&gt; configuration file to route the telemetry to your final destination.&lt;/p&gt;
&lt;h2 id=&#34;collect-application-telemetry&#34;&gt;Collect application telemetry&lt;/h2&gt;
&lt;p&gt;To collect metrics and traces emitted by your application, use the OTLP endpoints exposed by the collector sidecar container regardless of the collector implementation.
Specify &lt;code&gt;localhost&lt;/code&gt; as the host name, which is the default for most instrumentation libraries and agents.&lt;/p&gt;
&lt;p&gt;For Prometheus endpoints, add a scrape job to the ADOT or Alloy configuration, and use &lt;code&gt;localhost&lt;/code&gt;, service port, and endpoint path.&lt;/p&gt;
&lt;h2 id=&#34;collect-logs&#34;&gt;Collect Logs&lt;/h2&gt;
&lt;p&gt;The easiest way to collect application logs in ECS is to use the &lt;a href=&#34;https://docs.aws.amazon.com/AmazonECS/latest/developerguide/firelens-taskdef.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;AWS FireLens log driver&lt;/a&gt;.
Depending on your use case, you can forward your logs to the collector container in your task using the &lt;a href=&#34;https://docs.fluentbit.io/manual/pipeline/outputs/opentelemetry&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Fluent Bit plugin for OpenTelemetry&lt;/a&gt; or using the Fluent Bit Loki plugin.
You can also send everything directly to your final destination.&lt;/p&gt;
]]></content><description>&lt;h1 id="collect-amazon-elastic-container-service-or-aws-fargate-opentelemetry-data">Collect Amazon Elastic Container Service or AWS Fargate OpenTelemetry data&lt;/h1>
&lt;p>You can configure Grafana Alloy or AWS ADOT to collect OpenTelemetry-compatible data from Amazon Elastic Container Service (ECS) or AWS Fargate and forward it to any OpenTelemetry-compatible endpoint.&lt;/p></description></item></channel></rss>