<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sampling on Grafana Labs</title><link>https://grafana.com/docs/opentelemetry/collector/sampling/</link><description>Recent content in Sampling on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/opentelemetry/collector/sampling/index.xml" rel="self" type="application/rss+xml"/><item><title>Head sampling</title><link>https://grafana.com/docs/opentelemetry/collector/sampling/head/</link><pubDate>Tue, 21 Jul 2026 10:50:09 +0000</pubDate><guid>https://grafana.com/docs/opentelemetry/collector/sampling/head/</guid><content><![CDATA[&lt;h1 id=&#34;head-sampling&#34;&gt;Head sampling&lt;/h1&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;With a head sampling strategy, you decide whether to sample a trace as early as possible, without needing to consider the entire trace. This approach is simple but effective.&lt;/p&gt;
&lt;p&gt;You can implement head sampling at the application level using SDKs, or at the collector level in Grafana Alloy or OpenTelemetry Collector as probabilistic sampling. This keeps configuration separate from your application.&lt;/p&gt;
&lt;p&gt;For Application Observability, perform probabilistic head sampling at the collector after metrics generation. This ensures all traces are available to generate accurate metrics.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Don&amp;rsquo;t use a sampling strategy at the application level.&lt;/li&gt;
&lt;li&gt;Use Grafana Alloy or OpenTelemetry Collector to collect traces from your application, generate metrics from traces, and apply sampling.&lt;/li&gt;
&lt;li&gt;Send all traces to the data collector to generate accurate metrics.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In Application Observability on Grafana Cloud:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Disable metrics generation in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;OTEL Collector &amp;gt;= 0.94, Grafana Alloy &amp;gt;= 1.0, Grafana Agent &amp;gt;= 0.40&lt;/strong&gt; span metrics source in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The collector receives all traces, generates metrics, and sends metrics to Grafana Cloud Prometheus. In parallel, the collector applies a probabilistic sampling strategy to the traces and sends sampled data to Grafana Cloud Tempo.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy configuration for head sampling, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector configuration for head sampling, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }
	// configures the default http/protobuf endpoint &amp;#34;0.0.0.0:4318&amp;#34;
	http { }

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

otelcol.processor.resourcedetection &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.resourcedetection/
	detectors = [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]

	system {
		hostname_sources = [&amp;#34;os&amp;#34;]

		resource_attributes {
			host.id   { enabled = true }
			host.name { enabled = true }
		}
	}

	output {
		metrics = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		logs    = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		traces  = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
	}
}

otelcol.processor.transform &amp;#34;add_resource_attributes_as_metric_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;datapoint&amp;#34;
		statements = [
			&amp;#34;set(attributes[\&amp;#34;deployment.environment\&amp;#34;], resource.attributes[\&amp;#34;deployment.environment\&amp;#34;])&amp;#34;,
			&amp;#34;set(attributes[\&amp;#34;service.version\&amp;#34;], resource.attributes[\&amp;#34;service.version\&amp;#34;])&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;calls|duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;drop_unneeded_resource_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	trace_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	metric_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	log_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	output {
		traces = [
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
			otelcol.processor.probabilistic_sampler.default.input,
		]
		metrics = [otelcol.processor.transform.add_resource_attributes_as_metric_attributes.input]
		logs    = [otelcol.processor.batch.default.input]
	}
}

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		logs    = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.probabilistic_sampler &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.probabilistic_sampler/
	// Examples: keep 10% of traces
	sampling_percentage = 10

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

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:
      http:
  hostmetrics:
    # Optional. Host Metrics Receiver added as an example of Infra Monitoring capabilities of the OpenTelemetry Collector
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver
    scrapers:
      load:
      memory:

processors:
  batch:
  # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  resourcedetection:
    # Enriches telemetry data with resource information from the host
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor
    detectors: [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]
    override: false
    system:
      resource_attributes:
        host.id:
          enabled: true
        host.name:
          enabled: true
  transform/add_resource_attributes_as_metric_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes[&amp;#34;deployment.environment&amp;#34;], resource.attributes[&amp;#34;deployment.environment&amp;#34;])
          - set(attributes[&amp;#34;service.version&amp;#34;], resource.attributes[&amp;#34;service.version&amp;#34;])
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;calls|duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  transform/drop_unneeded_resource_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    trace_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    metric_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    log_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
  probabilistic_sampler:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/probabilisticsamplerprocessor
    # Examples: keep 10% of traces
    sampling_percentage: 10

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions:
    [
      basicauth/grafana_cloud,
    ]
  pipelines:
    traces:
      receivers: [otlp]
      processors:
        [resourcedetection, transform/drop_unneeded_resource_attributes]
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          probabilistic_sampler,
          batch
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics:
      receivers: [otlp, hostmetrics]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          transform/add_resource_attributes_as_metric_attributes,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlphttp/grafana_cloud]

    logs:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt; is for customers who use Grafana Alloy or OpenTelemetry Collector with metric names that match those used by the Tempo metrics generator.&lt;/p&gt;
&lt;p&gt;If you chose the &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source you should use legacy configuration below.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy legacy configuration for head sampling, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector legacy configuration for head sampling, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }
	// configures the default http/protobuf endpoint &amp;#34;0.0.0.0:4318&amp;#34;
	http { }

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

otelcol.processor.resourcedetection &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.resourcedetection/
	detectors = [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]

	system {
		hostname_sources = [&amp;#34;os&amp;#34;]

		resource_attributes {
			host.id   { enabled = true }
			host.name { enabled = true }
		}
	}

	output {
		metrics = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		logs    = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		traces  = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
	}
}

otelcol.processor.transform &amp;#34;add_resource_attributes_as_metric_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;datapoint&amp;#34;
		statements = [
			&amp;#34;set(attributes[\&amp;#34;deployment.environment\&amp;#34;], resource.attributes[\&amp;#34;deployment.environment\&amp;#34;])&amp;#34;,
			&amp;#34;set(attributes[\&amp;#34;service.version\&amp;#34;], resource.attributes[\&amp;#34;service.version\&amp;#34;])&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	namespace = &amp;#34;traces.spanmetrics&amp;#34;

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.transform.use_grafana_metric_names.input]
	}
}

otelcol.processor.transform &amp;#34;use_grafana_metric_names&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;metric&amp;#34;
		statements = [
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.latency\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.duration\&amp;#34;&amp;#34;,
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.calls.total\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.calls\&amp;#34;&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;drop_unneeded_resource_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	trace_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	metric_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	log_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	output {
		traces = [
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
			otelcol.processor.probabilistic_sampler.default.input,
		]
		metrics = [otelcol.processor.transform.add_resource_attributes_as_metric_attributes.input]
		logs    = [otelcol.processor.batch.default.input]
	}
}

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		logs    = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.probabilistic_sampler &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.probabilistic_sampler/
	// Examples: keep 10% of traces
	sampling_percentage = 10

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

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:
      http:
  hostmetrics:
    # Optional. Host Metrics Receiver added as an example of Infra Monitoring capabilities of the OpenTelemetry Collector
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver
    scrapers:
      load:
      memory:

processors:
  batch:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  resourcedetection:
    # Enriches telemetry data with resource information from the host
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor
    detectors: [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]
    override: false
    system:
      resource_attributes:
        host.id:
          enabled: true
        host.name:
          enabled: true
  transform/add_resource_attributes_as_metric_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes[&amp;#34;deployment.environment&amp;#34;], resource.attributes[&amp;#34;deployment.environment&amp;#34;])
          - set(attributes[&amp;#34;service.version&amp;#34;], resource.attributes[&amp;#34;service.version&amp;#34;])
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  transform/drop_unneeded_resource_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    trace_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    metric_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    log_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
  transform/use_grafana_metric_names:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: metric
        statements:
          - set(name, &amp;#34;traces.spanmetrics.latency&amp;#34;) where name == &amp;#34;traces.spanmetrics.duration&amp;#34;
          - set(name, &amp;#34;traces.spanmetrics.calls.total&amp;#34;) where name == &amp;#34;traces.spanmetrics.calls&amp;#34;
  probabilistic_sampler:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/probabilisticsamplerprocessor
    # Examples: keep 10% of traces
    sampling_percentage: 10

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    namespace: traces.spanmetrics
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions:
    [
      basicauth/grafana_cloud,
    ]
  pipelines:
    traces:
      receivers: [otlp]
      processors:
        [resourcedetection, transform/drop_unneeded_resource_attributes]
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          probabilistic_sampler,
          batch
        ]
      exporters: [otlp/grafana_cloud]
    metrics:
      receivers: [otlp, hostmetrics]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          transform/add_resource_attributes_as_metric_attributes,
          batch,
        ]
      exporters: [otlp/grafana_cloud]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          transform/use_grafana_metric_names,
          batch,
        ]
      exporters: [otlp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlp/grafana_cloud]
    logs:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [otlp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;


]]></content><description>&lt;h1 id="head-sampling">Head sampling&lt;/h1>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>With a head sampling strategy, you decide whether to sample a trace as early as possible, without needing to consider the entire trace. This approach is simple but effective.&lt;/p></description></item><item><title>Tail sampling</title><link>https://grafana.com/docs/opentelemetry/collector/sampling/tail/</link><pubDate>Tue, 21 Jul 2026 10:50:09 +0000</pubDate><guid>https://grafana.com/docs/opentelemetry/collector/sampling/tail/</guid><content><![CDATA[&lt;h1 id=&#34;tail-sampling&#34;&gt;Tail sampling&lt;/h1&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;With a tail sampling strategy, you decide whether to sample a trace after considering all or most of its spans. For example, tail sampling works well when you want to sample only traces with errors or long request durations.&lt;/p&gt;
&lt;p&gt;Tail sampling is more complex to configure, implement, and maintain, but it is the recommended strategy for large systems with high telemetry volume.&lt;/p&gt;
&lt;p&gt;Keep these key points in mind when choosing tail sampling:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As your system grows and changes, adapt your tail sampling strategy to keep the volume of sampled data balanced.&lt;/li&gt;
&lt;li&gt;Components that implement tail sampling must be stateful. They need to hold data in memory for some time to make sampling decisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Application Observability, sample your data at the collector after metrics generation. This ensures all traces are available to generate accurate metrics. If you generate metrics from sampled traces, sampling affects their values.&lt;/p&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Do not use a sampling strategy at the application level.&lt;/li&gt;
&lt;li&gt;Use Grafana Alloy or OpenTelemetry Collector to collect traces from the application, generate metrics from traces, and apply sampling.&lt;/li&gt;
&lt;li&gt;Send all traces to the data collector to generate accurate metrics.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In Application Observability on Grafana Cloud:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Disable metrics generation in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;OTEL Collector &amp;gt;= 0.94, Grafana Alloy &amp;gt;= 1.0, Grafana Agent &amp;gt;= 0.40&lt;/strong&gt; span metrics source in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The collector receives all traces, generates metrics, and sends metrics to Grafana Cloud Prometheus. In parallel, the collector applies a tail sampling strategy to the traces and sends sampled data to Grafana Cloud Tempo.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy configuration for tail sampling, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector configuration for tail sampling, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }
	// configures the default http/protobuf endpoint &amp;#34;0.0.0.0:4318&amp;#34;
	http { }

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

otelcol.processor.transform &amp;#34;add_resource_attributes_as_metric_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;datapoint&amp;#34;
		statements = [
			&amp;#34;set(attributes[\&amp;#34;deployment.environment\&amp;#34;], resource.attributes[\&amp;#34;deployment.environment\&amp;#34;])&amp;#34;,
			&amp;#34;set(attributes[\&amp;#34;service.version\&amp;#34;], resource.attributes[\&amp;#34;service.version\&amp;#34;])&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;calls|duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;drop_unneeded_resource_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	trace_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	metric_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	log_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	output {
		traces = [
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
			otelcol.processor.tail_sampling.default.input,
		]
		metrics = [otelcol.processor.transform.add_resource_attributes_as_metric_attributes.input]
		logs    = [otelcol.processor.batch.default.input]
	}
}

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		logs    = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.tail_sampling &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.tail_sampling/
	// Examples: keep all traces that take more than 5000 ms
	policy {
		name    = &amp;#34;all_traces_above_5000ms&amp;#34;
		type    = &amp;#34;latency&amp;#34;
		latency = {
			threshold_ms = 5000,
		}
	}

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

otelcol.processor.resourcedetection &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.resourcedetection/
	detectors = [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]

	system {
		hostname_sources = [&amp;#34;os&amp;#34;]

		resource_attributes {
			host.id   { enabled = true }
			host.name { enabled = true }
		}
	}

	output {
		metrics = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		logs    = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		traces  = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
	}
}

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:
      http:
  hostmetrics:
    # Optional. Host Metrics Receiver added as an example of Infra Monitoring capabilities of the OpenTelemetry Collector
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver
    scrapers:
      load:
      memory:

processors:
  batch:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  resourcedetection:
    # Enriches telemetry data with resource information from the host
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor
    detectors: [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]
    override: false
    system:
      resource_attributes:
        host.id:
          enabled: true
        host.name:
          enabled: true
  transform/add_resource_attributes_as_metric_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes[&amp;#34;deployment.environment&amp;#34;], resource.attributes[&amp;#34;deployment.environment&amp;#34;])
          - set(attributes[&amp;#34;service.version&amp;#34;], resource.attributes[&amp;#34;service.version&amp;#34;])
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;calls|duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  transform/drop_unneeded_resource_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    trace_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    metric_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    log_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
  tail_sampling:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
    policies:
      # Examples: keep all traces that take more than 5000 ms
      [
        {
          name: all_traces_above_5000ms,
          type: latency,
          latency: { threshold_ms: 5000 },
        },
      ]

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions:
    [
      basicauth/grafana_cloud_traces,
      basicauth/grafana_cloud_metrics,
      basicauth/grafana_cloud_logs,
    ]
  pipelines:
    traces:
      receivers: [otlp]
      processors:
        [resourcedetection, transform/drop_unneeded_resource_attributes]
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          tail_sampling,
          batch
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics:
      receivers: [otlp, hostmetrics]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          transform/add_resource_attributes_as_metric_attributes,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlphttp/grafana_cloud]
    logs:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt; is for customers who use Grafana Alloy or OpenTelemetry Collector with metric names that match those used by the Tempo metrics generator.&lt;/p&gt;
&lt;p&gt;If you chose the &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source you should use legacy configuration below.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy legacy configuration for tail sampling, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector legacy configuration for tail sampling, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }
	// configures the default http/protobuf endpoint &amp;#34;0.0.0.0:4318&amp;#34;
	http { }

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

otelcol.processor.transform &amp;#34;add_resource_attributes_as_metric_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;datapoint&amp;#34;
		statements = [
			&amp;#34;set(attributes[\&amp;#34;deployment.environment\&amp;#34;], resource.attributes[\&amp;#34;deployment.environment\&amp;#34;])&amp;#34;,
			&amp;#34;set(attributes[\&amp;#34;service.version\&amp;#34;], resource.attributes[\&amp;#34;service.version\&amp;#34;])&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	namespace = &amp;#34;traces.spanmetrics&amp;#34;

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.transform &amp;#34;use_grafana_metric_names&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;metric&amp;#34;
		statements = [
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.latency\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.duration\&amp;#34;&amp;#34;,
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.calls.total\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.calls\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.transform.use_grafana_metric_names.input]
	}
}

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

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

otelcol.processor.transform &amp;#34;drop_unneeded_resource_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	trace_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	metric_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	log_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	output {
		traces = [
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
			otelcol.processor.tail_sampling.default.input,
		]
		metrics = [otelcol.processor.transform.add_resource_attributes_as_metric_attributes.input]
		logs    = [otelcol.processor.batch.default.input]
	}
}

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		logs    = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.tail_sampling &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.tail_sampling/
	// Examples: keep all traces that take more than 5000 ms
	policy {
		name    = &amp;#34;all_traces_above_5000ms&amp;#34;
		type    = &amp;#34;latency&amp;#34;
		latency = {
			threshold_ms = 5000,
		}
	}

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

otelcol.processor.resourcedetection &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.resourcedetection/
	detectors = [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]

	system {
		hostname_sources = [&amp;#34;os&amp;#34;]

		resource_attributes {
			host.id   { enabled = true }
			host.name { enabled = true }
		}
	}

	output {
		metrics = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		logs    = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		traces  = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
	}
}

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:
      http:
  hostmetrics:
    # Optional. Host Metrics Receiver added as an example of Infra Monitoring capabilities of the OpenTelemetry Collector
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver
    scrapers:
      load:
      memory:

processors:
  batch:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  resourcedetection:
    # Enriches telemetry data with resource information from the host
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor
    detectors: [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]
    override: false
    system:
      resource_attributes:
        host.id:
          enabled: true
        host.name:
          enabled: true
  transform/add_resource_attributes_as_metric_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes[&amp;#34;deployment.environment&amp;#34;], resource.attributes[&amp;#34;deployment.environment&amp;#34;])
          - set(attributes[&amp;#34;service.version&amp;#34;], resource.attributes[&amp;#34;service.version&amp;#34;])
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  transform/drop_unneeded_resource_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    trace_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    metric_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    log_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
  transform/use_grafana_metric_names:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: metric
        statements:
          - set(name, &amp;#34;traces.spanmetrics.latency&amp;#34;) where name == &amp;#34;traces.spanmetrics.duration&amp;#34;
          - set(name, &amp;#34;traces.spanmetrics.calls.total&amp;#34;) where name == &amp;#34;traces.spanmetrics.calls&amp;#34;
  tail_sampling:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
    policies:
      # Examples: keep all traces that take more than 5000 ms
      [
        {
          name: all_traces_above_5000ms,
          type: latency,
          latency: { threshold_ms: 5000 },
        },
      ]

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    namespace: traces.spanmetrics
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions:
    [
      basicauth/grafana_cloud,
    ]
  pipelines:
    traces:
      receivers: [otlp]
      processors:
        [resourcedetection, transform/drop_unneeded_resource_attributes]
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          tail_sampling,
          batch
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics:
      receivers: [otlp, hostmetrics]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes
          transform/add_resource_attributes_as_metric_attributes,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          transform/use_grafana_metric_names,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlphttp/grafana_cloud]
    logs:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;


]]></content><description>&lt;h1 id="tail-sampling">Tail sampling&lt;/h1>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>With a tail sampling strategy, you decide whether to sample a trace after considering all or most of its spans. For example, tail sampling works well when you want to sample only traces with errors or long request durations.&lt;/p></description></item><item><title>Scale Alloy tail sampling</title><link>https://grafana.com/docs/opentelemetry/collector/sampling/scale/</link><pubDate>Tue, 21 Jul 2026 10:50:09 +0000</pubDate><guid>https://grafana.com/docs/opentelemetry/collector/sampling/scale/</guid><content><![CDATA[&lt;h1 id=&#34;scale-alloy-tail-sampling&#34;&gt;Scale Alloy tail sampling&lt;/h1&gt;
&lt;p&gt;When the load on Grafana Alloy is low, process all necessary telemetry signals in a single process. For example, a single collector can handle all incoming metrics, logs, and traces.&lt;/p&gt;
&lt;p&gt;As telemetry volume increases, scale the data collector to handle the load.&lt;/p&gt;
&lt;p&gt;The following section guides you through our recommendations for scaling the data collector when sampling is enabled.&lt;/p&gt;
&lt;p&gt;For Application Observability, sample at the data collector after metrics generation so all traces are available to generate accurate metrics. The sampling strategy applies to traces, and only sampled traces are sent to the backend.&lt;/p&gt;
&lt;p&gt;This pipeline makes the data collector stateful, containing these stateful components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/&#34;&gt;otelcol.connector.spanmetrics&lt;/a&gt;, &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/&#34;&gt;otelcol.connector.servicegraph&lt;/a&gt;, &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.processor.tail_sampling/&#34;&gt;otelcol.processor.tail_sampling&lt;/a&gt; for Grafana Agent&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;spanmetricsconnector&lt;/a&gt;, &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;servicegraphconnector&lt;/a&gt;, &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;tailsamplingprocessor&lt;/a&gt; for OpenTelemetry collector&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In tracing, a stateful component aggregates certain spans to work correctly.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The span metrics connector requires all spans with &lt;code&gt;service.name&lt;/code&gt; to be processed by the same collector&lt;/li&gt;
&lt;li&gt;The service graph connector pairs each &amp;ldquo;client&amp;rdquo; span with a &amp;ldquo;server&amp;rdquo; span to calculate metrics such as span duration&lt;/li&gt;
&lt;li&gt;The tail sampling processor requires all spans with &lt;code&gt;traceID&lt;/code&gt; to be processed by the same collector&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To scale this pipeline, deploy two layers of collectors.
The first layer enriches data, exports application metrics and logs to backends, and load balances traces using a &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.exporter.loadbalancing/&#34;&gt;otelcol.exporter.loadbalancing&lt;/a&gt; for Grafana Agent and &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/loadbalancingexporter&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;loadbalancingexporter&lt;/a&gt; for OpenTelemetry collector.
The second layer performs metrics generation and sampling, then exports sampled traces and generated metrics.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/media/docs/grafana-cloud/application-observability/sampling-recommended-arch-alloy-otel-scaled-1.png&#34;
  alt=&#34;Sampling scaled architecture&#34; width=&#34;3644&#34;
     height=&#34;1908&#34;/&gt;&lt;/p&gt;
&lt;p&gt;To identify series generated by different collectors in the second layer, add an additional label, &lt;code&gt;collector_id&lt;/code&gt;.
Solve cardinality issues from &lt;code&gt;collector_id&lt;/code&gt; labels using &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/setup/scaling/adaptive-metrics/&#34;&gt;Adaptive Metrics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy configuration for the first layer, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector configuration for the first layer, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.&lt;/p&gt;



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }
	// configures the default http/protobuf endpoint &amp;#34;0.0.0.0:4318&amp;#34;
	http { }

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

otelcol.processor.transform &amp;#34;add_resource_attributes_as_metric_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;datapoint&amp;#34;
		statements = [
			&amp;#34;set(attributes[\&amp;#34;deployment.environment\&amp;#34;], resource.attributes[\&amp;#34;deployment.environment\&amp;#34;])&amp;#34;,
			&amp;#34;set(attributes[\&amp;#34;service.version\&amp;#34;], resource.attributes[\&amp;#34;service.version\&amp;#34;])&amp;#34;,
		]
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otelhttp.grafana_cloud.input]
		logs    = [otelcol.exporter.otelhttp.grafana_cloud.input]
		traces  = [otelcol.exporter.loadbalancing.default.input]
	}
}

otelcol.processor.resourcedetection &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.resourcedetection/
	detectors = [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]

	system {
		hostname_sources = [&amp;#34;os&amp;#34;]

		resource_attributes {
			host.id   { enabled = true }
			host.name { enabled = true }
		}
	}

	output {
		metrics = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		logs    = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
		traces  = [otelcol.processor.transform.drop_unneeded_resource_attributes.input]
	}
}

otelcol.processor.transform &amp;#34;drop_unneeded_resource_attributes&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	trace_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	metric_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

	log_statements {
		context    = &amp;#34;resource&amp;#34;
		statements = [
			&amp;#34;delete_key(attributes, \&amp;#34;k8s.pod.start_time\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;os.type\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.command_args\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.executable.path\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.pid\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.description\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.name\&amp;#34;)&amp;#34;,
			&amp;#34;delete_key(attributes, \&amp;#34;process.runtime.version\&amp;#34;)&amp;#34;,
		]
	}

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

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}

otelcol.exporter.loadbalancing &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.loadbalancing/
	resolver {
		static {
			hostnames = [&amp;#34;collector-1:4317&amp;#34;, &amp;#34;collector-2:4317&amp;#34;, &amp;#34;collector-3:4317&amp;#34;]
		}
	}

	protocol {
		otlp {
			client { }
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:
      http:
  hostmetrics:
    # Optional. Host Metrics Receiver added as an example of Infra Monitoring capabilities of the OpenTelemetry Collector
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver
    scrapers:
      load:
      memory:

processors:
  batch:
  # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  resourcedetection:
    # Enriches telemetry data with resource information from the host
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor
    detectors: [&amp;#34;env&amp;#34;, &amp;#34;system&amp;#34;]
    override: false
    system:
      resource_attributes:
        host.id:
          enabled: true
        host.name:
          enabled: true
  transform/drop_unneeded_resource_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    trace_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    metric_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
    log_statements:
      - context: resource
        statements:
          - delete_key(attributes, &amp;#34;k8s.pod.start_time&amp;#34;)
          - delete_key(attributes, &amp;#34;os.description&amp;#34;)
          - delete_key(attributes, &amp;#34;os.type&amp;#34;)
          - delete_key(attributes, &amp;#34;process.command_args&amp;#34;)
          - delete_key(attributes, &amp;#34;process.executable.path&amp;#34;)
          - delete_key(attributes, &amp;#34;process.pid&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.description&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.name&amp;#34;)
          - delete_key(attributes, &amp;#34;process.runtime.version&amp;#34;)
  transform/add_resource_attributes_as_metric_attributes:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: datapoint
        statements:
          - set(attributes[&amp;#34;deployment.environment&amp;#34;], resource.attributes[&amp;#34;deployment.environment&amp;#34;])
          - set(attributes[&amp;#34;service.version&amp;#34;], resource.attributes[&amp;#34;service.version&amp;#34;])
connectors:
exporters:
  loadbalancing:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/loadbalancingexporter
    protocol:
      otlp:
    resolver:
      static:
        hostnames:
          - collector-1:4317
          - collector-2:4317
          - collector-3:4317
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions: [basicauth/grafana_cloud]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [loadbalancing]
    metrics:
      receivers: [otlp, hostmetrics]
      processors:
        [
          resourcedetection,
          transform/drop_unneeded_resource_attributes,
          transform/add_resource_attributes_as_metric_attributes,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    logs:
      receivers: [otlp]
      processors: [resourcedetection, transform/drop_unneeded_resource_attributes, batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;


&lt;p&gt;The first layer collector is stateless. Scaling stateless collector is easy, as an off-the-shelf layer 4 load-balancer would be sufficient.&lt;/p&gt;
&lt;p&gt;The collector has three resolvers for the load-balancing exporter &lt;code&gt;static&lt;/code&gt;, &lt;code&gt;dns&lt;/code&gt;, and &lt;code&gt;k8s&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;static&lt;/strong&gt;: A static list of backends is provided in the configuration. This is suitable when the backends are static and scaling isn’t expected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dns&lt;/strong&gt;: A hostname is provided as a parameter which the resolver periodically queries to discover IPs and update the load-balancer ring. When multiple instances are used, there is a chance they can momentarily have a different view of the system while they sync after a refresh. This can result in some spans for the same trace ID being sent to multiple hosts. Determine if this acceptable for the system, and use a longer refresh interval to reduce the effect of being out of sync.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubernetes&lt;/strong&gt;: A resolver that implements a watcher using Kubernetes APIs to get notifications when the list of pods backing a service is changed. This should reduce the amount of time when cluster views differ between nodes, effectively being a better solution than the DNS resolver when Kubernetes is used.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To view the Grafana Alloy configuration for the second layer, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector configuration for the second layer, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }

	output {
		traces = [
			otelcol.processor.tail_sampling.default.input,
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
		]
	}
}

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;calls|duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

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

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.tail_sampling &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.tail_sampling/
	// Examples: keep all traces that take more than 5000 ms
	policy {
		name    = &amp;#34;all_traces_above_5000ms&amp;#34;
		type    = &amp;#34;latency&amp;#34;
		latency = {
			threshold_ms = 5000,
		}
	}

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

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:

processors:
  batch:
  # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;calls|duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  tail_sampling:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
    policies:
      # Examples: keep all traces that take more than 5000 ms
      [
        {
          name: all_traces_above_5000ms,
          type: latency,
          latency: { threshold_ms: 5000 },
        },
      ]

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud
    add_metric_suffixes: false

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions: [basicauth/grafana_cloud]
  pipelines:
    traces:
      receivers: [otlp]
      processors: []
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors: [tail_sampling, batch]
      exporters: [otlphttp/grafana_cloud]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;

&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source in the &lt;a href=&#34;/docs/grafana-cloud/monitor-applications/application-observability/manual/configure/&#34;&gt;configuration&lt;/a&gt; is for customers who use Grafana Alloy or OpenTelemetry Collector with metric names that match those used by the Tempo metrics generator.&lt;/p&gt;
&lt;p&gt;If you chose the &lt;strong&gt;Legacy&lt;/strong&gt; option for span metrics source you should use legacy configuration below.&lt;/p&gt;
&lt;p&gt;To view the Grafana Alloy legacy configuration for the second layer, select the &lt;strong&gt;river&lt;/strong&gt; tab below. To view the OpenTelemetry Collector legacy configuration for the second layer, select the &lt;strong&gt;yaml&lt;/strong&gt; tab below.



  

  






  

  



  &lt;div class=&#34;code&#34; x-data=&#34;app_code([&amp;#34;alloy&amp;#34;,&amp;#34;yaml&amp;#34;], false)&#34; x-init=&#34;init()&#34; data-codetoggle=&#34;true&#34;&gt;
    &lt;div class=&#34;toggle-toolbar &#34;&gt;
      &lt;div&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;alloy&#39; }&#34; @click=&#34;$store.code.language = &#39;alloy&#39;&#34;&gt;
              &lt;span&gt;Alloy&lt;/span&gt;
            &lt;/button&gt;&lt;button class=&#34;toggle-toolbar__item&#34; :class=&#34;{ &#39;toggle-toolbar__item-active&#39;: active === &#39;yaml&#39; }&#34; @click=&#34;$store.code.language = &#39;yaml&#39;&#34;&gt;
              &lt;span&gt;YAML&lt;/span&gt;
            &lt;/button&gt;&lt;/div&gt;
      &lt;div class=&#34;d-flex&#34;&gt;&lt;span class=&#34;code-clipboard&#34; x-ref=&#34;tooltip&#34;&gt;
          &lt;button @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&gt;
      &lt;div class=&#34;toggle-toolbar__border&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div class=&#34;code-rendered&#34; &gt;
      &lt;!-- prettier-ignore-start --&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;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.receiver.otlp/

	// configures the default grpc endpoint &amp;#34;0.0.0.0:4317&amp;#34;
	grpc { }

	output {
		traces = [
			otelcol.processor.tail_sampling.default.input,
			otelcol.connector.servicegraph.default.input,
			otelcol.connector.spanmetrics.default.input,
		]
	}
}

otelcol.processor.transform &amp;#34;add_source&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;scope&amp;#34;
		statements = [
			&amp;#34;set(resource.attributes[\&amp;#34;source\&amp;#34;], \&amp;#34;spanmetrics\&amp;#34;) where name == \&amp;#34;spanmetricsconnector\&amp;#34;&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.filter.drop_unneeded_span_metrics.input]
	}
}

otelcol.connector.spanmetrics &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.spanmetrics/

	dimension {
		name = &amp;#34;service.namespace&amp;#34;
	}

	dimension {
		name = &amp;#34;service.version&amp;#34;
	}

	dimension {
		name = &amp;#34;deployment.environment&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.cluster.name&amp;#34;
	}

	dimension {
		name = &amp;#34;k8s.namespace.name&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.region&amp;#34;
	}

	dimension {
		name = &amp;#34;cloud.availability_zone&amp;#34;
	}

	histogram {
		explicit {
			buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]
		}
		unit = &amp;#34;s&amp;#34;
	}

	namespace = &amp;#34;traces.spanmetrics&amp;#34;

	output {
		metrics = [otelcol.processor.transform.add_source.input]
	}
}

otelcol.processor.transform &amp;#34;use_grafana_metric_names&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.transform/
	error_mode = &amp;#34;ignore&amp;#34;

	metric_statements {
		context    = &amp;#34;metric&amp;#34;
		statements = [
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.latency\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.duration\&amp;#34;&amp;#34;,
			&amp;#34;set(name, \&amp;#34;traces.spanmetrics.calls.total\&amp;#34;) where name == \&amp;#34;traces.spanmetrics.calls\&amp;#34;&amp;#34;,
		]
	}

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

otelcol.processor.filter &amp;#34;drop_unneeded_span_metrics&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.filter/
	error_mode = &amp;#34;ignore&amp;#34;

	metrics {
		datapoint = [
			&amp;#34;IsMatch(metric.name, \&amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration\&amp;#34;) and IsMatch(attributes[\&amp;#34;span.kind\&amp;#34;], \&amp;#34;SPAN_KIND_INTERNAL\&amp;#34;)&amp;#34;,
		]
	}

	output {
		metrics = [otelcol.processor.transform.use_grafana_metric_names.input]
	}
}

otelcol.connector.servicegraph &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.connector.servicegraph/
	dimensions = [
		&amp;#34;service.namespace&amp;#34;,
		&amp;#34;service.version&amp;#34;,
		&amp;#34;deployment.environment&amp;#34;,
		&amp;#34;k8s.cluster.name&amp;#34;,
		&amp;#34;k8s.namespace.name&amp;#34;,
		&amp;#34;cloud.region&amp;#34;,
		&amp;#34;cloud.availability_zone&amp;#34;,
	]
	latency_histogram_buckets = [&amp;#34;0s&amp;#34;, &amp;#34;0.005s&amp;#34;, &amp;#34;0.01s&amp;#34;, &amp;#34;0.025s&amp;#34;, &amp;#34;0.05s&amp;#34;, &amp;#34;0.075s&amp;#34;, &amp;#34;0.1s&amp;#34;, &amp;#34;0.25s&amp;#34;, &amp;#34;0.5s&amp;#34;, &amp;#34;0.75s&amp;#34;, &amp;#34;1s&amp;#34;, &amp;#34;2.5s&amp;#34;, &amp;#34;5s&amp;#34;, &amp;#34;7.5s&amp;#34;, &amp;#34;10s&amp;#34;]

	store {
		ttl = &amp;#34;2s&amp;#34;
	}

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

otelcol.processor.batch &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.batch/
	output {
		metrics = [otelcol.exporter.otlphttp.grafana_cloud.input]
		traces  = [otelcol.exporter.otlphttp.grafana_cloud.input]
	}
}

otelcol.processor.tail_sampling &amp;#34;default&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.processor.tail_sampling/
	// Examples: keep all traces that take more than 5000 ms
	policy {
		name    = &amp;#34;all_traces_above_5000ms&amp;#34;
		type    = &amp;#34;latency&amp;#34;
		latency = {
			threshold_ms = 5000,
		}
	}

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

otelcol.exporter.otlphttp &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.exporter.otlphttp/
	client {
		endpoint = env(&amp;#34;GRAFANA_CLOUD_OTLP_ENDPOINT&amp;#34;)
		auth     = otelcol.auth.basic.grafana_cloud.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud&amp;#34; {
	// https://grafana.com/docs/alloy/latest/reference/components/otelcol.auth.basic/
	username = env(&amp;#34;GRAFANA_CLOUD_INSTANCE_ID&amp;#34;)
	password = env(&amp;#34;GRAFANA_CLOUD_API_KEY&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&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;# Tested with OpenTelemetry Collector Contrib v0.94.0
receivers:
  otlp:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver/otlpreceiver
    protocols:
      grpc:

processors:
  batch:
  # https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
  transform/add_source:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: scope
        statements:
          - set(resource.attributes[&amp;#34;source&amp;#34;], &amp;#34;spanmetrics&amp;#34;) where name == &amp;#34;spanmetricsconnector&amp;#34;
  filter/drop_unneeded_span_metrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor
    error_mode: ignore
    metrics:
      datapoint:
        - &amp;#39;IsMatch(metric.name, &amp;#34;traces.spanmetrics.calls|traces.spanmetrics.duration&amp;#34;) and IsMatch(attributes[&amp;#34;span.kind&amp;#34;], &amp;#34;SPAN_KIND_INTERNAL&amp;#34;)&amp;#39;
  transform/use_grafana_metric_names:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor
    error_mode: ignore
    metric_statements:
      - context: metric
        statements:
          - set(name, &amp;#34;traces.spanmetrics.latency&amp;#34;) where name == &amp;#34;traces.spanmetrics.duration&amp;#34;
          - set(name, &amp;#34;traces.spanmetrics.calls.total&amp;#34;) where name == &amp;#34;traces.spanmetrics.calls&amp;#34;
  tail_sampling:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor
    policies:
      # Examples: keep all traces that take more than 5000 ms
      [
        {
          name: all_traces_above_5000ms,
          type: latency,
          latency: { threshold_ms: 5000 },
        },
      ]

connectors:
  servicegraph:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector
    dimensions:
      - service.namespace
      - service.version
      - deployment.environment
      - k8s.cluster.name
      - k8s.namespace.name
      - cloud.region
      - cloud.availability_zone

  spanmetrics:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector
    namespace: traces.spanmetrics
    histogram:
      unit: s
    dimensions:
      - name: service.namespace
      - name: service.version
      - name: deployment.environment
      - name: k8s.cluster.name
      - name: k8s.namespace.name
      - name: cloud.region
      - name: cloud.availability_zone

exporters:
  otlphttp/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/otlphttpexporter
    endpoint: &amp;#34;${env:GRAFANA_CLOUD_OTLP_ENDPOINT}&amp;#34;
    auth:
      authenticator: basicauth/grafana_cloud

extensions:
  basicauth/grafana_cloud:
    # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/basicauthextension
    client_auth:
      username: &amp;#34;${env:GRAFANA_CLOUD_INSTANCE_ID}&amp;#34;
      password: &amp;#34;${env:GRAFANA_CLOUD_API_KEY}&amp;#34;

service:
  extensions: [basicauth/grafana_cloud]
  pipelines:
    traces:
      receivers: [otlp]
      processors: []
      exporters: [servicegraph, spanmetrics]
    traces/grafana_cloud_traces:
      receivers: [otlp]
      processors: [tail_sampling, batch]
      exporters: [otlphttp/grafana_cloud_traces]
    metrics/spanmetrics:
      receivers: [spanmetrics]
      processors:
        [
          filter/drop_unneeded_span_metrics,
          transform/add_source,
          transform/use_grafana_metric_names,
          batch,
        ]
      exporters: [otlphttp/grafana_cloud]
    metrics/servicegraph:
      receivers: [servicegraph]
      processors: [batch]
      exporters: [otlphttp/grafana_cloud]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;!-- prettier-ignore-end --&gt;

    &lt;/div&gt;
  &lt;/div&gt;

&lt;/p&gt;
]]></content><description>&lt;h1 id="scale-alloy-tail-sampling">Scale Alloy tail sampling&lt;/h1>
&lt;p>When the load on Grafana Alloy is low, process all necessary telemetry signals in a single process. For example, a single collector can handle all incoming metrics, logs, and traces.&lt;/p></description></item></channel></rss>