Repository: grafana/alloy

Issue:
Trace Context lost in faro receiver
### Component(s)

faro.receiver

### What's wrong?

While adding UserInteraction tracing instrumentation to our web application, we noticed an issue with exception logs. The trace is generated correctly, but when an exception occurs within that trace, the corresponding log entry does not include the span_id or trace_id.

After some investigation, we confirmed that the Faro Web SDK is correctly sending these IDs, but they appear to be lost somewhere in the collector.

Looking into the Faro receiver implementation, I found that inside the transformException method, the trace context (as defined [here](https://github.com/grafana/alloy/blob/main/internal/component/faro/receiver/internal/payload/payload.go#L55)) seems to not be preserved when the exception is transformed with proper source-mapped stack traces.

[source](https://github.com/grafana/alloy/blob/main/internal/component/faro/receiver/sourcemaps.go#L371)

```
func transformException(log log.Logger, store sourceMapsStore, ex *payload.Exception, release string) *payload.Exception {
	if ex.Stacktrace == nil {
		return ex
	}

	[ …. ]

	return &payload.Exception{
		Type:       ex.Type,
		Value:      ex.Value,
		Stacktrace: &payload.Stacktrace{Frames: frames},
		Timestamp:  ex.Timestamp,
		Context:    ex.Context,
	}
}
```


The log provided is exported via `loki.echo.debug` component, right after `faro.receiver` consumes it and transforms it.

### Steps to reproduce

Steps to Reproduce
1. Add UserInteraction tracing instrumentation to a web app.
2. Trigger an exception within a traced operation (“click”).
3. Check the resulting log entry — notice that it lacks trace_id and span_id.

### System information

_No response_

### Software version

Grafana Alloy 1.9.1

### Configuration

```text
faro.receiver "frontend" {
    server {
        listen_address       = sys.env("POD_IP")
        listen_port          = "12347"
        cors_allowed_origins = ["*"]
        api_key              = [sensitive]
    }

    sourcemaps {
        download = false

        location {
            path                 = "/sourcemaps"
            minified_path_prefix = [sensitive]
        }
    }

    output {
        logs   = [loki.echo.debug.receiver]
    }
}

loki.echo "debug" {}
```

### Logs

```text
timestamp=\"2025-10-14 08:04:29.472 +0000 UTC\" kind=exception type=Error value=\"Method not implemented.\" stacktrace=[sensitive] sdk_version=1.19.0 app_name=web-application user_id=ccd595f5-d1eb-4296-b467-403602038a41 user_attr_role=[sensitive] session_id=DitzWvG5GQ page_url=[sensitive] browser_name=Brave browser_version=140.0.0.0 browser_os=\"Mac OS 10.15.7\" browser_mobile=false browser_userAgent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36\" browser_language=en-US browser_viewportWidth=2560 browser_viewportHeight=600 view_name=choose-product
```

### Tip

<sub>React with 👍 if this issue is important to you.</sub>

Hints from issue comments:
@duartesaraiva98: I made a (draft) PR which adds some unit tests that prove the TraceContext is lost on transformation when a stack trace is defined. (The written test fails)

https://github.com/grafana/alloy/pull/4664@mar4uk: Thank you for creating a draft PR with test! The fix should be pretty simple, just adding the missing `Trace:  ex.Trace` to the returned object in the `transformException` function.
@duartesaraiva98 Would you like to go ahead and add it to your draft PR?@duartesaraiva98: @mar4uk thanks for the response!

Yes, I will gladly add this to my PR in a few hours when i get home 🙂

Solution patch:
diff --git a/.github/ISSUE_TEMPLATE/blank.yaml b/.github/ISSUE_TEMPLATE/blank.yaml
index 501eac02a..ac94c14fc 100644
--- a/.github/ISSUE_TEMPLATE/blank.yaml
+++ b/.github/ISSUE_TEMPLATE/blank.yaml
@@ -119,6 +119,7 @@ body:
       - otelcol.processor.tail_sampling
       - otelcol.processor.transform
       - otelcol.receiver.awscloudwatch
+      - otelcol.receiver.awsecscontainermetrics
       - otelcol.receiver.datadog
       - otelcol.receiver.faro
       - otelcol.receiver.file_stats
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index a196c5fbb..68ad3e917 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -119,6 +119,7 @@ body:
       - otelcol.processor.tail_sampling
       - otelcol.processor.transform
       - otelcol.receiver.awscloudwatch
+      - otelcol.receiver.awsecscontainermetrics
       - otelcol.receiver.datadog
       - otelcol.receiver.faro
       - otelcol.receiver.file_stats
diff --git a/.github/ISSUE_TEMPLATE/docs.yaml b/.github/ISSUE_TEMPLATE/docs.yaml
index 67f284c17..06a863de8 100644
--- a/.github/ISSUE_TEMPLATE/docs.yaml
+++ b/.github/ISSUE_TEMPLATE/docs.yaml
@@ -122,6 +122,7 @@ body:
       - otelcol.processor.tail_sampling
       - otelcol.processor.transform
       - otelcol.receiver.awscloudwatch
+      - otelcol.receiver.awsecscontainermetrics
       - otelcol.receiver.datadog
       - otelcol.receiver.faro
       - otelcol.receiver.file_stats
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
index 53bb33ff5..ad094a30c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -119,6 +119,7 @@ body:
       - otelcol.processor.tail_sampling
       - otelcol.processor.transform
       - otelcol.receiver.awscloudwatch
+      - otelcol.receiver.awsecscontainermetrics
       - otelcol.receiver.datadog
       - otelcol.receiver.faro
       - otelcol.receiver.file_stats
diff --git a/.github/ISSUE_TEMPLATE/proposal.yaml b/.github/ISSUE_TEMPLATE/proposal.yaml
index 4703b0637..d8c8661ae 100644
--- a/.github/ISSUE_TEMPLATE/proposal.yaml
+++ b/.github/ISSUE_TEMPLATE/proposal.yaml
@@ -119,6 +119,7 @@ body:
       - otelcol.processor.tail_sampling
       - otelcol.processor.transform
       - otelcol.receiver.awscloudwatch
+      - otelcol.receiver.awsecscontainermetrics
       - otelcol.receiver.datadog
       - otelcol.receiver.faro
       - otelcol.receiver.file_stats
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1cb5080e..96e533303 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -53,6 +53,7 @@ Main (unreleased)
 
 - Support delimiters in `stage.luhn`. (@dehaansa)
 
+- pyroscope.java: update async-profiler to 4.2 (@korniltsev-grafanista)
 - Improve debug info output from exported receivers (loki, prometheus and pyroscope). (@kalleep)
 
 - `prometheus.exporter.unix`: Add an `arp` config block to configure the ARP collector. (@ptodev)
@@ -67,6 +68,8 @@ Main (unreleased)
 
 - Only log EOF errors for syslog port investigations in `loki.source.syslog` as Debug, not Warn. (@dehaansa)
 
+- Fix issues with "unknown series ref when trying to add exemplar" from `prometheus.remote_write` by allowing series ref links to be updated if they change. (@kgeckhart)
+
 v1.11.3
 -----------------
 
@@ -92,6 +95,10 @@ v1.11.3
 
 - Augment prometheus.scrape 'scheme' argument strengthening link to protocol. (@lewismc)
 
+- Fix `loki.source.podlogs` component to register the Kubernetes field index for `spec.nodeName` when node filtering is enabled, preventing "Index with name field:spec.nodeName does not exist" errors. (@QuentinBisson)
+
+- Stop `faro.receiver` losing trace context when exception has stack trace. (@duartesaraiva98)
+
 v1.11.2
 -----------------
 
@@ -159,6 +166,8 @@ v1.11.0
 - Add the `otelcol.receiver.fluentforward` receiver to receive logs via Fluent Forward Protocol. (@rucciva)
 - Add the `prometheus.enrich` component to enrich metrics using labels from `discovery.*` components. (@ArkovKonstantin)
 
+- Add the `otelcol.receiver.awsecscontainermetrics` receiver (from upstream OTEL contrib) to read AWS ECS task- and container-level resource usage metrics. (@gregbrowndev)
+
 - Add `node_filter` configuration block to `loki.source.podlogs` component to enable node-based filtering for pod discovery. When enabled, only pods running on the specified node will be discovered and monitored, significantly reducing API server load and network traffic in DaemonSet deployments. (@QuentinBisson)
 
 - (_Experimental_) Additions to experimental `database_observability.mysql` component:
diff --git a/docs/sources/reference/compatibility/_index.md b/docs/sources/reference/compatibility/_index.md
index c74c2032b..a17ca7ca0 100644
--- a/docs/sources/reference/compatibility/_index.md
+++ b/docs/sources/reference/compatibility/_index.md
@@ -382,6 +382,7 @@ The following components, grouped by namespace, _consume_ OpenTelemetry `otelcol
 - [otelcol.processor.tail_sampling](../components/otelcol/otelcol.processor.tail_sampling)
 - [otelcol.processor.transform](../components/otelcol/otelcol.processor.transform)
 - [otelcol.receiver.awscloudwatch](../components/otelcol/otelcol.receiver.awscloudwatch)
+- [otelcol.receiver.awsecscontainermetrics](../components/otelcol/otelcol.receiver.awsecscontainermetrics)
 - [otelcol.receiver.datadog](../components/otelcol/otelcol.receiver.datadog)
 - [otelcol.receiver.faro](../components/otelcol/otelcol.receiver.faro)
 - [otelcol.receiver.file_stats](../components/otelcol/otelcol.receiver.file_stats)
diff --git a/docs/sources/reference/components/database_observability/database_observability.mysql.md b/docs/sources/reference/components/database_observability/database_observability.mysql.md
index 0bac3379b..553d1fdf2 100644
--- a/docs/sources/reference/components/database_observability/database_observability.mysql.md
+++ b/docs/sources/reference/components/database_observability/database_observability.mysql.md
@@ -130,7 +130,7 @@ The `aws` block supplies the [ARN](https://docs.aws.amazon.com/IAM/latest/UserGu
 
 | Name                             | Type       | Description                                                                    | Default | Required |
 |----------------------------------|------------|--------------------------------------------------------------------------------|---------|----------|
-| `collect_interval`               | `duration` | How frequently to collect information from database.                           | `"1m"`  | no       |
+| `collect_interval`               | `duration` | How frequently to collect information from database.                           | `"10s"` | no       |
 | `disable_query_redaction`        | `bool`     | Collect unredacted SQL query text including parameters.                        | `false` | no       |
 | `auto_enable_setup_consumers`    | `boolean`  | Whether to enable some specific `performance_schema.setup_consumers` settings. | `false` | no       |
 | `setup_consumers_check_interval` | `duration` | How frequently to check if `setup_consumers` are correctly enabled.            | `"1h"`  | no       |
diff --git a/docs/sources/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics.md b/docs/sources/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics.md
new file mode 100644
index 000000000..53a1fe686
--- /dev/null
+++ b/docs/sources/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics.md
@@ -0,0 +1,144 @@
+---
+canonical: https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.receiver.awsecscontainermetrics/
+description: Learn about otelcol.receiver.awsecscontainermetrics
+labels:
+  stage: experimental
+  products:
+    - oss
+  tags:
+    - text: Community
+      tooltip: This component is developed, maintained, and supported by the Alloy user community.
+title: otelcol.receiver.awsecscontainermetrics
+---
+
+# `otelcol.receiver.awsecscontainermetrics`
+
+{{< docs/shared lookup="stability/community.md" source="alloy" version="<ALLOY_VERSION>" >}}  
+
+{{< docs/shared lookup="stability/experimental.md" source="alloy" version="<ALLOY_VERSION>" >}}  
+
+`otelcol.receiver.awsecscontainermetrics` reads AWS ECS task- and container-level metadata, and resource usage metrics such as CPU, memory, network, and disk, and forwards them to other `otelcol.*` components.  
+
+{{< admonition type="note" >}}
+`otelcol.receiver.awsecscontainermetrics` is a wrapper over the upstream OpenTelemetry Collector [`awsecscontainermetrics`][] receiver.
+Bug reports or feature requests will be redirected to the upstream repository, if necessary.
+
+[`awsecscontainermetrics`]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/{{< param "OTEL_VERSION" >}}/receiver/awsecscontainermetricsreceiver
+{{< /admonition >}}
+
+This receiver supports ECS Fargate and ECS on EC2. It uses [ECS Task Metadata Endpoint V4](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v4.html) which is automatically available within the task's containers. Therefore, you should run the {{< param "PRODUCT_NAME" >}} collector using this receiver as a sidecar within the task you want to monitor. Refer to the upstream  [`awsecscontainermetrics`][] receiver documentation for more details.
+
+You can specify multiple `otelcol.receiver.awsecscontainermetrics` components by giving them different labels.
+
+[`awsecscontainermetrics`]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/{{< param "OTEL_VERSION" >}}/receiver/awsecscontainermetricsreceiver
+
+## Usage
+
+```alloy
+otelcol.receiver.awsecscontainermetrics "<LABEL>" {
+  output {
+    metrics = [...]
+  }
+}
+```
+
+## Arguments
+
+You can use the following arguments with `otelcol.receiver.awsecscontainermetrics`:
+
+| Name            | Type                       | Description                                                              | Default | Required |
+|-----------------|----------------------------|--------------------------------------------------------------------------|---------|----------|
+| `collection_interval`        | `duration`                   | How frequently to collect and emit metrics.                                         |    "20s"     | no      |
+
+## Blocks
+
+You can use the following blocks with `otelcol.receiver.awsecscontainermetrics`:
+
+| Block                            | Description                                                                | Required |
+|----------------------------------|----------------------------------------------------------------------------|----------|
+| [`output`][output]               | Configures where to send received telemetry data.                          | yes      |
+| [`debug_metrics`][debug_metrics] | Configures the metrics that this component generates to monitor its state. | no       |
+
+[debug_metrics]: #debug_metrics
+[output]: #output
+
+### `output`
+
+{{< badge text="Required" >}}
+
+{{< docs/shared lookup="reference/components/output-block.md" source="alloy" version="<ALLOY_VERSION>" >}}
+
+### `debug_metrics`
+
+{{< docs/shared lookup="reference/components/otelcol-debug-metrics-block.md" source="alloy" version="<ALLOY_VERSION>" >}}
+
+## Exported fields
+
+`otelcol.receiver.awsecscontainermetrics` doesn't export any fields.
+
+## Component health
+
+`otelcol.receiver.awsecscontainermetrics` is only reported as unhealthy if given an invalid configuration.
+
+## Debug information
+
+`otelcol.receiver.awsecscontainermetrics` doesn't expose any component-specific debug information.
+
+## Example
+
+The following example collects eight task-level metrics from the 52 metrics available in an ECS task and forwards them to a filter processor.  
+
+```alloy
+otelcol.receiver.awsecscontainermetrics "default" {
+  collection_interval = "60s"
+
+  output {
+    metrics = [otelcol.processor.filter.default.input]
+  }
+}
+
+otelcol.processor.filter "default" {
+  error_mode = "ignore"
+
+  metrics {
+    metric = [
+      string.join([
+        `metric.name != "ecs.task.memory.reserved"`,
+        `metric.name != "ecs.task.memory.utilized"`,
+        `metric.name != "ecs.task.cpu.reserved"`,
+        `metric.name != "ecs.task.cpu.utilized"`,
+        `metric.name != "ecs.task.network.rate.rx"`,
+        `metric.name != "ecs.task.network.rate.tx"`,
+        `metric.name != "ecs.task.storage.read_bytes"`,
+        `metric.name != "ecs.task.storage.write_bytes"`,
+      ], " and "),
+    ]
+  }
+
+  output {
+    metrics = [otelcol.exporter.otlp.default.input]
+  }
+}
+
+otelcol.exporter.otlp "default" {
+  client {
+    endpoint = env("<OTLP_ENDPOINT>")
+  }
+}
+```
+
+<!-- START GENERATED COMPATIBLE COMPONENTS -->
+
+## Compatible components
+
+`otelcol.receiver.awsecscontainermetrics` can accept arguments from the following components:
+
+- Components that export [OpenTelemetry `otelcol.Consumer`](../../../compatibility/#opentelemetry-otelcolconsumer-exporters)
+
+
+{{< admonition type="note" >}}
+Connecting some components may not be sensible or components may require further configuration to make the connection work correctly.
+Refer to the linked documentation for more details.
+{{< /admonition >}}
+
+<!-- END GENERATED COMPATIBLE COMPONENTS -->
diff --git a/docs/sources/reference/components/prometheus/prometheus.exporter.cloudwatch.md b/docs/sources/reference/components/prometheus/prometheus.exporter.cloudwatch.md
index e7c361c9c..88f1b4b2b 100644
--- a/docs/sources/reference/components/prometheus/prometheus.exporter.cloudwatch.md
+++ b/docs/sources/reference/components/prometheus/prometheus.exporter.cloudwatch.md
@@ -424,7 +424,6 @@ When you configure a discovery job, make sure the `type` field of each `discover
 * Namespace: `AWS/Cognito`
 * Namespace: `AWS/DataSync`
 * Namespace: `AWS/DDoSProtection`
-* Namespace: `AWS/DirectoryService`
 * Namespace: `AWS/DMS`
 * Namespace: `AWS/DocDB`
 * Namespace: `AWS/DX`
@@ -466,9 +465,9 @@ When you configure a discovery job, make sure the `type` field of each `discover
 * Namespace: `AWS/MWAA`
 * Namespace: `AWS/NATGateway`
 * Namespace: `AWS/Neptune`
+* Namespace: `AWS/Network Manager`
 * Namespace: `AWS/NetworkELB`
 * Namespace: `AWS/NetworkFirewall`
-* Namespace: `AWS/Network Manager`
 * Namespace: `AWS/PrivateLinkEndpoints`
 * Namespace: `AWS/PrivateLinkServices`
 * Namespace: `AWS/Prometheus`
@@ -476,7 +475,6 @@ When you configure a discovery job, make sure the `type` field of each `discover
 * Namespace: `AWS/QuickSight`
 * Namespace: `AWS/RDS`
 * Namespace: `AWS/Redshift`
-* Namespace: `AWS/Redshift-Serverless`
 * Namespace: `AWS/Route53`
 * Namespace: `AWS/Route53Resolver`
 * Namespace: `AWS/RUM`
@@ -505,6 +503,7 @@ When you configure a discovery job, make sure the `type` field of each `discover
 
 {{< /column-list >}}
 
+
 <!-- START GENERATED COMPATIBLE COMPONENTS -->
 
 ## Compatible components
diff --git a/go.mod b/go.mod
index a712d9088..5fd864bb9 100644
--- a/go.mod
+++ b/go.mod
@@ -155,6 +155,7 @@ require (
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.134.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.134.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscloudwatchreceiver v0.134.0
+	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver v0.134.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/datadogreceiver v0.134.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/faroreceiver v0.134.0
 	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.134.0
@@ -1067,7 +1068,7 @@ replace (
 
 	// TODO(marctc, mattdurham): Replace node_export with custom fork for multi usage. https://github.com/prometheus/node_exporter/pull/2812
 	// this commit is on the refactor_collectors branch in the grafana fork.
-	github.com/prometheus/node_exporter => github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024133138-bfa3c0a61c7a //refactor_collectors
+	github.com/prometheus/node_exporter => github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024135609-318b01780c89 //refactor_collectors
 )
 
 replace github.com/github/smimesign => github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3
diff --git a/go.sum b/go.sum
index 96d1c3fac..b8781d2d8 100644
--- a/go.sum
+++ b/go.sum
@@ -1186,8 +1186,8 @@ github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe h1:yIXAAbLswn
 github.com/grafana/memberlist v0.3.1-0.20220714140823-09ffed8adbbe/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
 github.com/grafana/mysqld_exporter v0.17.2-0.20250226152553-be612e3fdedd h1:FW1Km8Z1mE8r/WLBAbX3LYv14DEZehdZTWOfF4qsqOY=
 github.com/grafana/mysqld_exporter v0.17.2-0.20250226152553-be612e3fdedd/go.mod h1:iEFA+REkm+0WRvVxy0cA1bBhJlFcQB998yymb45TqMU=
-github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024133138-bfa3c0a61c7a h1:lm2JF7rk5KAeSufsk5bVkqKGDdYMtEhePUmwwLbHLtY=
-github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024133138-bfa3c0a61c7a/go.mod h1:BUJCdmzfsndvLKeFuONqMPsEA0fkeVuAyt8II4Lk0Dg=
+github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024135609-318b01780c89 h1:Ab3Z4AXC1Hffr4NbeYq0vTQhJbiGTTO2xd0ZV0kC1v8=
+github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20251024135609-318b01780c89/go.mod h1:BUJCdmzfsndvLKeFuONqMPsEA0fkeVuAyt8II4Lk0Dg=
 github.com/grafana/opentelemetry-collector/featuregate v0.0.0-20240325174506-2fd1623b2ca0 h1:i/Ne0XwoRokYj52ZcSmnvuyID3h/uA91n0Ycg/grHU8=
 github.com/grafana/opentelemetry-collector/featuregate v0.0.0-20240325174506-2fd1623b2ca0/go.mod h1:mm8+xyQfgDmqhyegZRNIQmoKsNnDTwWKFLsdMoXAb7A=
 github.com/grafana/opentelemetry-ebpf-instrumentation v1.3.2 h1:mg90SB3x+FADo1eBA+x111TiaoHG8nPsebA16CCspxg=
@@ -1212,8 +1212,6 @@ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrR
 github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
 github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3 h1:UPkAxuhlAcRmJT3/qd34OMTl+ZU7BLLfOO2+NXBlJpY=
 github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3/go.mod h1:iZiiwNT4HbtGRVqCQu7uJPEZCuEE5sfSSttcnePkDl4=
-github.com/grafana/snowflake-prometheus-exporter v0.0.0-20251016132346-6d442402afb2 h1:Adchz4O0C13520kAihpBrmheVOfuZK9/e+6R+Hhovf8=
-github.com/grafana/snowflake-prometheus-exporter v0.0.0-20251016132346-6d442402afb2/go.mod h1:TLf/gsyKggD6qiTXOC9dlTDFR0c3v6r/0Ufs6s9+xBc=
 github.com/grafana/snowflake-prometheus-exporter v0.0.0-20251023151319-9baba332b98a h1:G2OWgH6RoA9u9yqqXgQtn9kHJwDNxdgKSWMU5ymmeJQ=
 github.com/grafana/snowflake-prometheus-exporter v0.0.0-20251023151319-9baba332b98a/go.mod h1:TLf/gsyKggD6qiTXOC9dlTDFR0c3v6r/0Ufs6s9+xBc=
 github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 h1:bjh0PVYSVVFxzINqPFYJmAmJNrWPgnVjuSdYJGHmtFU=
@@ -1927,6 +1925,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformpro
 github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.134.0/go.mod h1:7MO+zGYumZSBDa963QgxEnP5WwyRuwvlts4EGKki1l0=
 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscloudwatchreceiver v0.134.0 h1:pCuO5Q95uy/adfDB3uW6Jru7Wd9i37/l9DtG1G0S2Ek=
 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awscloudwatchreceiver v0.134.0/go.mod h1:B2A6+/+hiHqnRosscKXeupWmRdYxayXjB+Muu7EMqRw=
+github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver v0.134.0 h1:e2OWWuo7c83jTDjOPq2Wj2jLFNuzAIuuGheQksS9mdc=
+github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver v0.134.0/go.mod h1:4j8SsaglqpF/F875+s+21S4+bvK7F2kcTZGeW5L8tq4=
 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/datadogreceiver v0.134.0 h1:+fmQLSvtARPeqAmKZb+ph6KZnZQwgtcZ8vkK735ZYEc=
 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/datadogreceiver v0.134.0/go.mod h1:OVi4ezn2HvWvvQsfrQZ4xGhSaEGJg2R+x18jrJysg8E=
 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/dockerstatsreceiver v0.134.0 h1:De16DTKSyXcHNGfGtyBZrqzVrAF0Gyt+X+mUdZhMhII=
diff --git a/internal/component/all/all.go b/internal/component/all/all.go
index b66fa68f1..cf47003b2 100644
--- a/internal/component/all/all.go
+++ b/internal/component/all/all.go
@@ -102,6 +102,7 @@ import (
 	_ "github.com/grafana/alloy/internal/component/otelcol/processor/tail_sampling"          // Import otelcol.processor.tail_sampling
 	_ "github.com/grafana/alloy/internal/component/otelcol/processor/transform"              // Import otelcol.processor.transform
 	_ "github.com/grafana/alloy/internal/component/otelcol/receiver/awscloudwatch"           // Import otelcol.receiver.awscloudwatch
+	_ "github.com/grafana/alloy/internal/component/otelcol/receiver/awsecscontainermetrics"  // Import otelcol.receiver.awsecscontainermetrics
 	_ "github.com/grafana/alloy/internal/component/otelcol/receiver/datadog"                 // Import otelcol.receiver.datadog
 	_ "github.com/grafana/alloy/internal/component/otelcol/receiver/faro"                    // Import otelcol.receiver.faro
 	_ "github.com/grafana/alloy/internal/component/otelcol/receiver/file_stats"              // Import otelcol.receiver.file_stats
diff --git a/internal/component/database_observability/README.md b/internal/component/database_observability/README.md
index bac226d92..e37713882 100644
--- a/internal/component/database_observability/README.md
+++ b/internal/component/database_observability/README.md
@@ -369,7 +369,7 @@ discovery.relabel "database_observability_mysql_example_db_2" {
 }
 
 prometheus.scrape "database_observability_mysql_example_db_2" {
-  targets    = discovery.relabel.database_observability_mysql_example_db_2.targets
+  targets    = discovery.relabel.database_observability_mysql_example_db_2.output
   job_name   = "integrations/db-o11y"
   forward_to = [prometheus.remote_write.metrics_service.receiver]
 }
diff --git a/internal/component/database_observability/mysql/component.go b/internal/component/database_observability/mysql/component.go
index fe4514cda..44a5606a5 100644
--- a/internal/component/database_observability/mysql/component.go
+++ b/internal/component/database_observability/mysql/component.go
@@ -143,7 +143,7 @@ var DefaultArguments = Arguments{
 	},
 
 	QuerySamplesArguments: QuerySamplesArguments{
-		CollectInterval:             1 * time.Minute,
+		CollectInterval:             10 * time.Second,
 		DisableQueryRedaction:       false,
 		AutoEnableSetupConsumers:    false,
 		SetupConsumersCheckInterval: 1 * time.Hour,
diff --git a/internal/component/faro/receiver/sourcemaps.go b/internal/component/faro/receiver/sourcemaps.go
index 48533a8a3..0041e4520 100644
--- a/internal/component/faro/receiver/sourcemaps.go
+++ b/internal/component/faro/receiver/sourcemaps.go
@@ -369,6 +369,7 @@ func transformException(log log.Logger, store sourceMapsStore, ex *payload.Excep
 		Stacktrace: &payload.Stacktrace{Frames: frames},
 		Timestamp:  ex.Timestamp,
 		Context:    ex.Context,
+		Trace:      ex.Trace,
 	}
 }
 
diff --git a/internal/component/loki/source/podlogs/controller.go b/internal/component/loki/source/podlogs/controller.go
index 41a91b5fe..9b7b18989 100644
--- a/internal/component/loki/source/podlogs/controller.go
+++ b/internal/component/loki/source/podlogs/controller.go
@@ -170,6 +170,17 @@ func (ctrl *controller) configureInformers(ctx context.Context, informers cache.
 	informerCtx, cancel := context.WithTimeout(ctx, informerSyncTimeout)
 	defer cancel()
 
+	// Register field index for spec.nodeName only if node filtering is enabled
+	if ctrl.reconciler.nodeFilterEnabled && ctrl.reconciler.getNodeFilterName() != "" {
+		if err := informers.IndexField(informerCtx, &corev1.Pod{}, "spec.nodeName", func(obj client.Object) []string {
+			pod := obj.(*corev1.Pod)
+			return []string{pod.Spec.NodeName}
+		}); err != nil {
+			return fmt.Errorf("failed to register field index for spec.nodeName: %w", err)
+		}
+		level.Debug(ctrl.log).Log("msg", "registered field index for spec.nodeName")
+	}
+
 	for _, ty := range types {
 		informer, err := informers.GetInformer(informerCtx, ty)
 		if err != nil {
diff --git a/internal/component/otelcol/exporter/prometheus/internal/convert/convert.go b/internal/component/otelcol/exporter/prometheus/internal/convert/convert.go
index 01d3f8cf2..32f82438e 100644
--- a/internal/component/otelcol/exporter/prometheus/internal/convert/convert.go
+++ b/internal/component/otelcol/exporter/prometheus/internal/convert/convert.go
@@ -463,7 +463,7 @@ func (conv *Converter) consumeSum(app storage.Appender, memResource *memorySerie
 		if convType == model.MetricTypeCounter {
 			for i := 0; i < dp.Exemplars().Len(); i++ {
 				if err := conv.writeExemplar(app, memSeries, dp.Exemplars().At(i)); err != nil {
-					level.Error(conv.log).Log("msg", "failed to write exemplar for metric sample", metricName, "err", err)
+					level.Error(conv.log).Log("msg", "failed to write exemplar for metric sample", "metric_name", metricName, "err", err)
 				}
 			}
 		}
diff --git a/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics.go b/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics.go
new file mode 100644
index 000000000..b57f4f3cf
--- /dev/null
+++ b/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics.go
@@ -0,0 +1,76 @@
+// Package awsecscontainermetrics provides an otelcol.receiver.awsecscontainermetrics component.
+package awsecscontainermetrics
+
+import (
+	"time"
+
+	"github.com/grafana/alloy/internal/component"
+	"github.com/grafana/alloy/internal/component/otelcol"
+	otelcolCfg "github.com/grafana/alloy/internal/component/otelcol/config"
+	"github.com/grafana/alloy/internal/component/otelcol/receiver"
+	"github.com/grafana/alloy/internal/featuregate"
+	"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver"
+	otelcomponent "go.opentelemetry.io/collector/component"
+	"go.opentelemetry.io/collector/pipeline"
+)
+
+func init() {
+	component.Register(component.Registration{
+		Name:      "otelcol.receiver.awsecscontainermetrics",
+		Stability: featuregate.StabilityExperimental,
+		Args:      Arguments{},
+
+		Build: func(opts component.Options, args component.Arguments) (component.Component, error) {
+			fact := awsecscontainermetricsreceiver.NewFactory()
+			return receiver.New(opts, fact, args.(Arguments))
+		},
+	})
+}
+
+// Arguments configures the otelcol.receiver.awsecscontainermetricsreceiver component.
+type Arguments struct {
+	CollectionInterval time.Duration `alloy:"collection_interval,attr,optional"`
+
+	DebugMetrics otelcolCfg.DebugMetricsArguments `alloy:"debug_metrics,block,optional"`
+
+	// Output configures where to send received data. Required.
+	Output *otelcol.ConsumerArguments `alloy:"output,block"`
+}
+
+var _ receiver.Arguments = Arguments{}
+
+// SetToDefault implements syntax.Defaulter.
+func (args *Arguments) SetToDefault() {
+	cfg := awsecscontainermetricsreceiver.NewFactory().CreateDefaultConfig().(*awsecscontainermetricsreceiver.Config)
+	*args = Arguments{
+		CollectionInterval: cfg.CollectionInterval,
+	}
+	args.DebugMetrics.SetToDefault()
+}
+
+// Convert implements receiver.Arguments.
+func (args Arguments) Convert() (otelcomponent.Config, error) {
+	return &awsecscontainermetricsreceiver.Config{
+		CollectionInterval: args.CollectionInterval,
+	}, nil
+}
+
+// Extensions implements receiver.Arguments.
+func (args Arguments) Extensions() map[otelcomponent.ID]otelcomponent.Component {
+	return nil
+}
+
+// Exporters implements receiver.Arguments.
+func (args Arguments) Exporters() map[pipeline.Signal]map[otelcomponent.ID]otelcomponent.Component {
+	return nil
+}
+
+// NextConsumers implements receiver.Arguments.
+func (args Arguments) NextConsumers() *otelcol.ConsumerArguments {
+	return args.Output
+}
+
+// DebugMetricsConfig implements receiver.Arguments.
+func (args Arguments) DebugMetricsConfig() otelcolCfg.DebugMetricsArguments {
+	return args.DebugMetrics
+}
diff --git a/internal/component/prometheus/remotewrite/remote_write.go b/internal/component/prometheus/remotewrite/remote_write.go
index 3e3997a72..089140597 100644
--- a/internal/component/prometheus/remotewrite/remote_write.go
+++ b/internal/component/prometheus/remotewrite/remote_write.go
@@ -125,6 +125,31 @@ func New(o component.Options, args Arguments) (*Component, error) {
 		debugDataPublisher: debugDataPublisher.(livedebugging.DebugDataPublisher),
 	}
 	componentID := livedebugging.ComponentID(res.opts.ID)
+
+	handleLocalLink := func(globalRef uint64, l labels.Labels, cachedLocalRef uint64, newLocalRef uint64) {
+		// We had a local ref that was still valid nothing to do
+		if cachedLocalRef != 0 && cachedLocalRef == newLocalRef {
+			return
+		}
+
+		// There are some unique scenarios that can have an append end with no error but the returned localRef is zero (duplicate exemplars).
+		// We don't want to update a valid link to an invalid link
+		if cachedLocalRef != 0 && newLocalRef == 0 {
+			return
+		}
+
+		// This should never happen in a proper appender chain. Since we cannot enforce it, we are extra defensive.
+		if globalRef == 0 {
+			globalRef = ls.GetOrAddGlobalRefID(l)
+		}
+
+		if cachedLocalRef == 0 {
+			ls.AddLocalLink(res.opts.ID, globalRef, newLocalRef)
+		} else {
+			ls.ReplaceLocalLink(res.opts.ID, globalRef, cachedLocalRef, newLocalRef)
+		}
+	}
+
 	res.receiver = prometheus.NewInterceptor(
 		res.storage,
 		ls,
@@ -140,11 +165,12 @@ func New(o component.Options, args Arguments) (*Component, error) {
 				return 0, fmt.Errorf("%s has exited", o.ID)
 			}
 
-			localID := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
-			newRef, nextErr := next.Append(storage.SeriesRef(localID), l, t, v)
-			if localID == 0 {
-				ls.GetOrAddLink(res.opts.ID, uint64(newRef), l)
+			localRef := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
+			newLocalRef, nextErr := next.Append(storage.SeriesRef(localRef), l, t, v)
+			if nextErr == nil {
+				handleLocalLink(uint64(globalRef), l, localRef, uint64(newLocalRef))
 			}
+
 			res.debugDataPublisher.PublishIfActive(livedebugging.NewData(
 				componentID,
 				livedebugging.PrometheusMetric,
@@ -160,11 +186,12 @@ func New(o component.Options, args Arguments) (*Component, error) {
 				return 0, fmt.Errorf("%s has exited", o.ID)
 			}
 
-			localID := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
-			newRef, nextErr := next.AppendHistogram(storage.SeriesRef(localID), l, t, h, fh)
-			if localID == 0 {
-				ls.GetOrAddLink(res.opts.ID, uint64(newRef), l)
+			localRef := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
+			newLocalRef, nextErr := next.AppendHistogram(storage.SeriesRef(localRef), l, t, h, fh)
+			if nextErr == nil {
+				handleLocalLink(uint64(globalRef), l, localRef, uint64(newLocalRef))
 			}
+
 			res.debugDataPublisher.PublishIfActive(livedebugging.NewData(
 				componentID,
 				livedebugging.PrometheusMetric,
@@ -188,11 +215,12 @@ func New(o component.Options, args Arguments) (*Component, error) {
 				return 0, fmt.Errorf("%s has exited", o.ID)
 			}
 
-			localID := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
-			newRef, nextErr := next.UpdateMetadata(storage.SeriesRef(localID), l, m)
-			if localID == 0 {
-				ls.GetOrAddLink(res.opts.ID, uint64(newRef), l)
+			localRef := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
+			newLocalRef, nextErr := next.UpdateMetadata(storage.SeriesRef(localRef), l, m)
+			if nextErr == nil {
+				handleLocalLink(uint64(globalRef), l, localRef, uint64(newLocalRef))
 			}
+
 			res.debugDataPublisher.PublishIfActive(livedebugging.NewData(
 				componentID,
 				livedebugging.PrometheusMetric,
@@ -208,11 +236,12 @@ func New(o component.Options, args Arguments) (*Component, error) {
 				return 0, fmt.Errorf("%s has exited", o.ID)
 			}
 
-			localID := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
-			newRef, nextErr := next.AppendExemplar(storage.SeriesRef(localID), l, e)
-			if localID == 0 {
-				ls.GetOrAddLink(res.opts.ID, uint64(newRef), l)
+			localRef := ls.GetLocalRefID(res.opts.ID, uint64(globalRef))
+			newLocalRef, nextErr := next.AppendExemplar(storage.SeriesRef(localRef), l, e)
+			if nextErr == nil {
+				handleLocalLink(uint64(globalRef), l, localRef, uint64(newLocalRef))
 			}
+
 			res.debugDataPublisher.PublishIfActive(livedebugging.NewData(
 				componentID,
 				livedebugging.PrometheusMetric,
diff --git a/internal/component/pyroscope/java/asprof/asprof.go b/internal/component/pyroscope/java/asprof/asprof.go
index d5a813fb6..87c3bdaa1 100644
--- a/internal/component/pyroscope/java/asprof/asprof.go
+++ b/internal/component/pyroscope/java/asprof/asprof.go
@@ -83,7 +83,7 @@ func ExtractDistribution(a Archive, tmpDir, distName string) (Distribution, erro
 
 	var launcher, lib []byte
 	err := readArchive(a.data, a.format, func(name string, fi fs.FileInfo, data []byte) error {
-		if strings.Contains(name, "asprof") {
+		if strings.HasSuffix(name, "/asprof") {
 			launcher = data
 		}
 		if strings.Contains(name, "libasyncProfiler") {
diff --git a/internal/component/pyroscope/java/asprof/asprof_darwin.go b/internal/component/pyroscope/java/asprof/asprof_darwin.go
index e123e18e2..ba2c296da 100644
--- a/internal/component/pyroscope/java/asprof/asprof_darwin.go
+++ b/internal/component/pyroscope/java/asprof/asprof_darwin.go
@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 )
 
-//go:embed async-profiler-4.0-87b7b42-macos.zip
+//go:embed async-profiler-4.2-macos.zip
 var embeddedArchiveData []byte
 
 // bin/asprof
diff --git a/internal/component/pyroscope/java/asprof/asprof_linux_amd64.go b/internal/component/pyroscope/java/asprof/asprof_linux_amd64.go
index 319a02c5f..cc9526c86 100644
--- a/internal/component/pyroscope/java/asprof/asprof_linux_amd64.go
+++ b/internal/component/pyroscope/java/asprof/asprof_linux_amd64.go
@@ -6,7 +6,7 @@ import (
 	_ "embed"
 )
 
-//go:embed async-profiler-4.0-87b7b42-linux-x64.tar.gz
+//go:embed async-profiler-4.2-linux-x64.tar.gz
 var embeddedArchiveData []byte
 
 // bin/asprof
diff --git a/internal/component/pyroscope/java/asprof/asprof_linux_arm64.go b/internal/component/pyroscope/java/asprof/asprof_linux_arm64.go
index 8c8d8916f..6ec2820a7 100644
--- a/internal/component/pyroscope/java/asprof/asprof_linux_arm64.go
+++ b/internal/component/pyroscope/java/asprof/asprof_linux_arm64.go
@@ -6,7 +6,7 @@ import (
 	_ "embed"
 )
 
-//go:embed async-profiler-4.0-87b7b42-linux-arm64.tar.gz
+//go:embed async-profiler-4.2-linux-arm64.tar.gz
 var embeddedArchiveData []byte
 
 // bin/asprof
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-arm64.tar.gz b/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-arm64.tar.gz
deleted file mode 100644
index dfc20c155..000000000
Binary files a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-arm64.tar.gz and /dev/null differ
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-x64.tar.gz b/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-x64.tar.gz
deleted file mode 100644
index 7a673f19a..000000000
Binary files a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-linux-x64.tar.gz and /dev/null differ
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-macos.zip b/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-macos.zip
deleted file mode 100644
index f991ac860..000000000
Binary files a/internal/component/pyroscope/java/asprof/async-profiler-4.0-87b7b42-macos.zip and /dev/null differ
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-arm64.tar.gz b/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-arm64.tar.gz
new file mode 100644
index 000000000..cab3048c8
Binary files /dev/null and b/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-arm64.tar.gz differ
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-x64.tar.gz b/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-x64.tar.gz
new file mode 100644
index 000000000..0019e5814
Binary files /dev/null and b/internal/component/pyroscope/java/asprof/async-profiler-4.2-linux-x64.tar.gz differ
diff --git a/internal/component/pyroscope/java/asprof/async-profiler-4.2-macos.zip b/internal/component/pyroscope/java/asprof/async-profiler-4.2-macos.zip
new file mode 100644
index 000000000..707452128
Binary files /dev/null and b/internal/component/pyroscope/java/asprof/async-profiler-4.2-macos.zip differ
diff --git a/internal/converter/internal/otelcolconvert/converter_awsecscontainermetricsreceiver.go b/internal/converter/internal/otelcolconvert/converter_awsecscontainermetricsreceiver.go
new file mode 100644
index 000000000..e467f6c22
--- /dev/null
+++ b/internal/converter/internal/otelcolconvert/converter_awsecscontainermetricsreceiver.go
@@ -0,0 +1,57 @@
+package otelcolconvert
+
+import (
+	"fmt"
+
+	"github.com/grafana/alloy/internal/component/otelcol"
+	"github.com/grafana/alloy/internal/component/otelcol/receiver/awsecscontainermetrics"
+	"github.com/grafana/alloy/internal/converter/diag"
+	"github.com/grafana/alloy/internal/converter/internal/common"
+	"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver"
+	"go.opentelemetry.io/collector/component"
+	"go.opentelemetry.io/collector/component/componentstatus"
+	"go.opentelemetry.io/collector/pipeline"
+)
+
+func init() {
+	converters = append(converters, awsEcsContainerMetricsReceiverConverter{})
+}
+
+type awsEcsContainerMetricsReceiverConverter struct{}
+
+func (awsEcsContainerMetricsReceiverConverter) Factory() component.Factory {
+	return awsecscontainermetricsreceiver.NewFactory()
+}
+
+func (awsEcsContainerMetricsReceiverConverter) InputComponentName() string {
+	return "otelcol.receiver.awsecscontainermetrics"
+}
+
+func (awsEcsContainerMetricsReceiverConverter) ConvertAndAppend(state *State, id componentstatus.InstanceID, cfg component.Config) diag.Diagnostics {
+	var diags diag.Diagnostics
+
+	label := state.AlloyComponentLabel()
+
+	args := toAwsEcsContainerMetricsReceiver(state, id, cfg.(*awsecscontainermetricsreceiver.Config))
+	block := common.NewBlockWithOverride([]string{"otelcol", "receiver", "awsecscontainermetrics"}, label, args)
+
+	diags.Add(
+		diag.SeverityLevelInfo,
+		fmt.Sprintf("Converted %s into %s", StringifyInstanceID(id), StringifyBlock(block)),
+	)
+
+	state.Body().AppendBlock(block)
+	return diags
+}
+
+func toAwsEcsContainerMetricsReceiver(state *State, id componentstatus.InstanceID, cfg *awsecscontainermetricsreceiver.Config) *awsecscontainermetrics.Arguments {
+	nextMetrics := state.Next(id, pipeline.SignalMetrics)
+
+	return &awsecscontainermetrics.Arguments{
+		CollectionInterval: cfg.CollectionInterval,
+		DebugMetrics:       common.DefaultValue[awsecscontainermetrics.Arguments]().DebugMetrics,
+		Output: &otelcol.ConsumerArguments{
+			Metrics: ToTokenizedConsumers(nextMetrics),
+		},
+	}
+}
diff --git a/internal/service/labelstore/data.go b/internal/service/labelstore/data.go
index 21739d8f1..5e8ca95fc 100644
--- a/internal/service/labelstore/data.go
+++ b/internal/service/labelstore/data.go
@@ -3,15 +3,12 @@ package labelstore
 import "github.com/prometheus/prometheus/model/labels"
 
 type LabelStore interface {
-	// GetOrAddLink returns the global id for the values, if none found one will be created based on the lbls.
-	GetOrAddLink(componentID string, localRefID uint64, lbls labels.Labels) uint64
+	// AddLocalLink adds a mapping from local to global id for the given component.
+	AddLocalLink(componentID string, globalRefID uint64, localRefID uint64)
 
 	// GetOrAddGlobalRefID finds or adds a global id for the given label map.
 	GetOrAddGlobalRefID(l labels.Labels) uint64
 
-	// GetGlobalRefID returns the global id for a component and the local id. Returns 0 if nothing found.
-	GetGlobalRefID(componentID string, localRefID uint64) uint64
-
 	// GetLocalRefID gets the mapping from global to local id specific to a component. Returns 0 if nothing found.
 	GetLocalRefID(componentID string, globalRefID uint64) uint64
 
@@ -21,6 +18,9 @@ type LabelStore interface {
 
 	// CheckAndRemoveStaleMarkers identifies any series with a stale marker and removes those entries from the LabelStore.
 	CheckAndRemoveStaleMarkers()
+
+	// ReplaceLocalLink updates an existing local to global mapping for a component.
+	ReplaceLocalLink(componentID string, globalRefID uint64, cachedLocalRef uint64, newLocalRef uint64)
 }
 
 type StalenessTracker struct {
diff --git a/internal/service/labelstore/service.go b/internal/service/labelstore/service.go
index c7eaa5dc1..3a786388c 100644
--- a/internal/service/labelstore/service.go
+++ b/internal/service/labelstore/service.go
@@ -6,12 +6,13 @@ import (
 	"time"
 
 	"github.com/go-kit/log"
-	"github.com/grafana/alloy/internal/featuregate"
-	"github.com/grafana/alloy/internal/runtime/logging/level"
-	alloy_service "github.com/grafana/alloy/internal/service"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/prometheus/model/labels"
 	"github.com/prometheus/prometheus/model/value"
+
+	"github.com/grafana/alloy/internal/featuregate"
+	"github.com/grafana/alloy/internal/runtime/logging/level"
+	alloy_service "github.com/grafana/alloy/internal/service"
 )
 
 const ServiceName = "labelstore"
@@ -122,11 +123,15 @@ func (s *Service) Data() any {
 	return s
 }
 
-// GetOrAddLink is called by a remote_write endpoint component to add mapping and get back the global id.
-func (s *Service) GetOrAddLink(componentID string, localRefID uint64, lbls labels.Labels) uint64 {
+// AddLocalLink is called by a remote_write endpoint component to add mapping from local ref and global ref
+func (s *Service) AddLocalLink(componentID string, globalRefID uint64, localRefID uint64) {
 	s.mut.Lock()
 	defer s.mut.Unlock()
 
+	s.addLocalLink(componentID, globalRefID, localRefID)
+}
+
+func (s *Service) addLocalLink(componentID string, globalRefID uint64, localRefID uint64) {
 	// If the mapping doesn't exist then we need to create it
 	m, found := s.mappings[componentID]
 	if !found {
@@ -138,19 +143,27 @@ func (s *Service) GetOrAddLink(componentID string, localRefID uint64, lbls label
 		s.mappings[componentID] = m
 	}
 
-	labelHash := lbls.Hash()
-	globalID, found := s.labelsHashToGlobal[labelHash]
-	if found {
-		m.localToGlobal[localRefID] = globalID
-		m.globalToLocal[globalID] = localRefID
-		return globalID
+	m.localToGlobal[localRefID] = globalRefID
+	m.globalToLocal[globalRefID] = localRefID
+}
+
+// ReplaceLocalLink updates an existing local to global mapping for a component.
+func (s *Service) ReplaceLocalLink(componentID string, globalRefID uint64, cachedLocalRef uint64, newLocalRef uint64) {
+	s.mut.Lock()
+	defer s.mut.Unlock()
+
+	m, found := s.mappings[componentID]
+	// If we don't have a mapping yet there's nothing to replace
+	if !found {
+		s.addLocalLink(componentID, globalRefID, newLocalRef)
+		return
 	}
-	// We have a value we have never seen before so increment the globalrefid and assign
-	s.globalRefID++
-	s.labelsHashToGlobal[labelHash] = s.globalRefID
-	m.localToGlobal[localRefID] = s.globalRefID
-	m.globalToLocal[s.globalRefID] = localRefID
-	return s.globalRefID
+
+	// Delete the old mapping
+	delete(m.localToGlobal, cachedLocalRef)
+	// Add the new mapping
+	m.localToGlobal[newLocalRef] = globalRefID
+	m.globalToLocal[globalRefID] = newLocalRef
 }
 
 // GetOrAddGlobalRefID is used to create a global refid for a labelset
@@ -173,19 +186,6 @@ func (s *Service) GetOrAddGlobalRefID(l labels.Labels) uint64 {
 	return s.globalRefID
 }
 
-// GetGlobalRefID returns the global refid for a component local combo, or 0 if not found
-func (s *Service) GetGlobalRefID(componentID string, localRefID uint64) uint64 {
-	s.mut.Lock()
-	defer s.mut.Unlock()
-
-	m, found := s.mappings[componentID]
-	if !found {
-		return 0
-	}
-	global := m.localToGlobal[localRefID]
-	return global
-}
-
 // GetLocalRefID returns the local refid for a component global combo, or 0 if not found
 func (s *Service) GetLocalRefID(componentID string, globalRefID uint64) uint64 {
 	s.mut.Lock()



Test patch:
diff --git a/internal/component/faro/receiver/sourcemaps_test.go b/internal/component/faro/receiver/sourcemaps_test.go
index c4ed78f03..50fc15455 100644
--- a/internal/component/faro/receiver/sourcemaps_test.go
+++ b/internal/component/faro/receiver/sourcemaps_test.go
@@ -16,6 +16,33 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
+func Test_traceContextKeptWhenStacktraceDefined(t *testing.T) {
+	input := &payload.Exception{
+		Stacktrace: &payload.Stacktrace{},
+		Trace: payload.TraceContext{
+			TraceID: "0000000000000",
+			SpanID:  "000000",
+		},
+	}
+
+	expect := input
+	actual := transformException(nil, nil, input, "123")
+	require.Equal(t, expect, actual)
+}
+
+func Test_traceContextKeptWhenStacktraceNotDefined(t *testing.T) {
+	input := &payload.Exception{
+		Trace: payload.TraceContext{
+			TraceID: "0000000000000",
+			SpanID:  "000000",
+		},
+	}
+
+	expect := input
+	actual := transformException(nil, nil, input, "123")
+	require.Equal(t, expect, actual)
+}
+
 func Test_sourceMapsStoreImpl_DownloadSuccess(t *testing.T) {
 	var (
 		logger = alloyutil.TestLogger(t)
diff --git a/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics_test.go b/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics_test.go
new file mode 100644
index 000000000..11c3a95de
--- /dev/null
+++ b/internal/component/otelcol/receiver/awsecscontainermetrics/awsecscontainermetrics_test.go
@@ -0,0 +1,54 @@
+package awsecscontainermetrics_test
+
+import (
+	"testing"
+	"time"
+
+	"github.com/grafana/alloy/internal/component/otelcol/receiver/awsecscontainermetrics"
+	"github.com/grafana/alloy/syntax"
+	"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/awsecscontainermetricsreceiver"
+	"github.com/stretchr/testify/require"
+)
+
+func TestArguments_UnmarshalAlloy(t *testing.T) {
+	tests := []struct {
+		testName string
+		cfg      string
+		expected awsecscontainermetricsreceiver.Config
+	}{
+		{
+			testName: "default configuration",
+			cfg: `
+				output {}
+			`,
+			expected: awsecscontainermetricsreceiver.Config{
+				CollectionInterval: 20 * time.Second,
+			},
+		},
+		{
+			testName: "configuration with collection interval",
+			cfg: `
+				collection_interval = "60s"
+				output {}
+			`,
+			expected: awsecscontainermetricsreceiver.Config{
+				CollectionInterval: 60 * time.Second,
+			},
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.testName, func(t *testing.T) {
+			var args awsecscontainermetrics.Arguments
+			err := syntax.Unmarshal([]byte(tc.cfg), &args)
+			require.NoError(t, err)
+
+			actualPtr, err := args.Convert()
+			require.NoError(t, err)
+
+			actual := actualPtr.(*awsecscontainermetricsreceiver.Config)
+
+			require.Equal(t, tc.expected, *actual)
+		})
+	}
+}
diff --git a/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.alloy b/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.alloy
new file mode 100644
index 000000000..8469a694c
--- /dev/null
+++ b/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.alloy
@@ -0,0 +1,25 @@
+otelcol.receiver.awsecscontainermetrics "default" {
+	collection_interval = "30s"
+
+	output {
+		metrics = [otelcol.processor.filter.default.input]
+	}
+}
+
+otelcol.processor.filter "default" {
+	error_mode = "ignore"
+
+	metrics {
+		metric = ["metric.name != \"ecs.task.memory.reserved\" and metric.name != \"ecs.task.memory.utilized\""]
+	}
+
+	output {
+		metrics = [otelcol.exporter.otlp.default.input]
+	}
+}
+
+otelcol.exporter.otlp "default" {
+	client {
+		endpoint = "database:4317"
+	}
+}
diff --git a/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.yaml b/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.yaml
new file mode 100644
index 000000000..18a85898b
--- /dev/null
+++ b/internal/converter/internal/otelcolconvert/testdata/awsecscontainermetrics.yaml
@@ -0,0 +1,21 @@
+receivers:
+    awsecscontainermetrics:
+      collection_interval: 30s
+
+processors:
+  filter:
+    error_mode: ignore
+    metrics:
+      metric:
+          - 'metric.name != "ecs.task.memory.reserved" and metric.name != "ecs.task.memory.utilized"'
+
+exporters:
+  otlp:
+    endpoint: database:4317
+
+service:
+  pipelines:
+    metrics:
+      receivers: [awsecscontainermetrics]
+      processors: [filter]
+      exporters: [otlp]
\ No newline at end of file
diff --git a/internal/service/labelstore/service_test.go b/internal/service/labelstore/service_test.go
index 7ea0bf748..8d357122a 100644
--- a/internal/service/labelstore/service_test.go
+++ b/internal/service/labelstore/service_test.go
@@ -54,13 +54,14 @@ func TestAddingLocalMapping(t *testing.T) {
 	})
 
 	globalID := mapping.GetOrAddGlobalRefID(l)
-	shouldBeSameGlobalID := mapping.GetOrAddLink("1", 1, l)
-	require.True(t, globalID == shouldBeSameGlobalID)
+	mapping.AddLocalLink("1", globalID, 1)
+	mapping.GetLocalRefID("1", globalID)
+	require.Equal(t, uint64(1), mapping.GetLocalRefID("1", globalID))
 	require.Len(t, mapping.labelsHashToGlobal, 1)
 	require.Len(t, mapping.mappings, 1)
 	require.True(t, mapping.mappings["1"].RemoteWriteID == "1")
-	require.True(t, mapping.mappings["1"].globalToLocal[shouldBeSameGlobalID] == 1)
-	require.True(t, mapping.mappings["1"].localToGlobal[1] == shouldBeSameGlobalID)
+	require.True(t, mapping.mappings["1"].globalToLocal[globalID] == 1)
+	require.True(t, mapping.mappings["1"].localToGlobal[1] == globalID)
 }
 
 func TestAddingLocalMappings(t *testing.T) {
@@ -72,23 +73,24 @@ func TestAddingLocalMappings(t *testing.T) {
 	})
 
 	globalID := mapping.GetOrAddGlobalRefID(l)
-	shouldBeSameGlobalID := mapping.GetOrAddLink("1", 1, l)
-	shouldBeSameGlobalID2 := mapping.GetOrAddLink("2", 1, l)
-	require.True(t, globalID == shouldBeSameGlobalID)
-	require.True(t, globalID == shouldBeSameGlobalID2)
+	localRefID := uint64(1)
+	mapping.AddLocalLink("1", globalID, localRefID)
+	mapping.AddLocalLink("2", globalID, localRefID)
+	require.Equal(t, localRefID, mapping.GetLocalRefID("1", globalID))
+	require.Equal(t, localRefID, mapping.GetLocalRefID("2", globalID))
 	require.Len(t, mapping.labelsHashToGlobal, 1)
 	require.Len(t, mapping.mappings, 2)
 
 	require.True(t, mapping.mappings["1"].RemoteWriteID == "1")
-	require.True(t, mapping.mappings["1"].globalToLocal[shouldBeSameGlobalID] == 1)
-	require.True(t, mapping.mappings["1"].localToGlobal[1] == shouldBeSameGlobalID)
+	require.True(t, mapping.mappings["1"].globalToLocal[globalID] == localRefID)
+	require.True(t, mapping.mappings["1"].localToGlobal[localRefID] == globalID)
 
 	require.True(t, mapping.mappings["2"].RemoteWriteID == "2")
-	require.True(t, mapping.mappings["2"].globalToLocal[shouldBeSameGlobalID2] == 1)
-	require.True(t, mapping.mappings["2"].localToGlobal[1] == shouldBeSameGlobalID2)
+	require.True(t, mapping.mappings["2"].globalToLocal[globalID] == localRefID)
+	require.True(t, mapping.mappings["2"].localToGlobal[localRefID] == globalID)
 }
 
-func TestAddingLocalMappingsWithoutCreatingGlobalUpfront(t *testing.T) {
+func TestReplaceLocalMappings(t *testing.T) {
 	mapping := New(log.NewNopLogger(), prometheus.DefaultRegisterer)
 	l := labels.Labels{}
 	l = append(l, labels.Label{
@@ -96,19 +98,45 @@ func TestAddingLocalMappingsWithoutCreatingGlobalUpfront(t *testing.T) {
 		Value: "test",
 	})
 
-	shouldBeSameGlobalID := mapping.GetOrAddLink("1", 1, l)
-	shouldBeSameGlobalID2 := mapping.GetOrAddLink("2", 1, l)
-	require.True(t, shouldBeSameGlobalID2 == shouldBeSameGlobalID)
+	globalID := mapping.GetOrAddGlobalRefID(l)
+	localRefID := uint64(1)
+	mapping.AddLocalLink("1", globalID, localRefID)
+	mapping.AddLocalLink("2", globalID, localRefID)
+	require.Equal(t, localRefID, mapping.GetLocalRefID("1", globalID))
+	require.Equal(t, localRefID, mapping.GetLocalRefID("2", globalID))
+
+	localRefID = uint64(2)
+	mapping.ReplaceLocalLink("1", globalID, 1, localRefID)
+	mapping.ReplaceLocalLink("2", globalID, 1, localRefID)
 	require.Len(t, mapping.labelsHashToGlobal, 1)
 	require.Len(t, mapping.mappings, 2)
 
 	require.True(t, mapping.mappings["1"].RemoteWriteID == "1")
-	require.True(t, mapping.mappings["1"].globalToLocal[shouldBeSameGlobalID] == 1)
-	require.True(t, mapping.mappings["1"].localToGlobal[1] == shouldBeSameGlobalID)
+	require.True(t, mapping.mappings["1"].globalToLocal[globalID] == localRefID)
+	require.Len(t, mapping.mappings["1"].localToGlobal, 1)
+	require.True(t, mapping.mappings["1"].localToGlobal[localRefID] == globalID)
 
 	require.True(t, mapping.mappings["2"].RemoteWriteID == "2")
-	require.True(t, mapping.mappings["2"].globalToLocal[shouldBeSameGlobalID2] == 1)
-	require.True(t, mapping.mappings["2"].localToGlobal[1] == shouldBeSameGlobalID2)
+	require.True(t, mapping.mappings["2"].globalToLocal[globalID] == localRefID)
+	require.Len(t, mapping.mappings["2"].localToGlobal, 1)
+	require.True(t, mapping.mappings["2"].localToGlobal[localRefID] == globalID)
+}
+
+func TestReplaceWithoutAddingLocalMapping(t *testing.T) {
+	mapping := New(log.NewNopLogger(), prometheus.DefaultRegisterer)
+	l := labels.Labels{}
+	l = append(l, labels.Label{
+		Name:  "__name__",
+		Value: "test",
+	})
+
+	globalID := mapping.GetOrAddGlobalRefID(l)
+	localRefID := uint64(2)
+	mapping.ReplaceLocalLink("1", globalID, 1, localRefID)
+	mapping.ReplaceLocalLink("2", globalID, 1, localRefID)
+
+	require.Equal(t, localRefID, mapping.GetLocalRefID("1", globalID))
+	require.Equal(t, localRefID, mapping.GetLocalRefID("2", globalID))
 }
 
 func TestStaleness(t *testing.T) {
@@ -123,9 +151,10 @@ func TestStaleness(t *testing.T) {
 		Name:  "__name__",
 		Value: "test2",
 	})
-
-	global1 := mapping.GetOrAddLink("1", 1, l)
-	_ = mapping.GetOrAddLink("2", 1, l2)
+	global1 := mapping.GetOrAddGlobalRefID(l)
+	global2 := mapping.GetOrAddGlobalRefID(l2)
+	mapping.AddLocalLink("1", global1, 1)
+	mapping.AddLocalLink("2", global2, 1)
 	mapping.TrackStaleness([]StalenessTracker{
 		{
 			GlobalRefID: global1,
@@ -150,7 +179,8 @@ func TestRemovingStaleness(t *testing.T) {
 		Value: "test",
 	})
 
-	global1 := mapping.GetOrAddLink("1", 1, l)
+	global1 := mapping.GetOrAddGlobalRefID(l)
+	mapping.AddLocalLink("1", global1, 1)
 	mapping.TrackStaleness([]StalenessTracker{
 		{
 			GlobalRefID: global1,