The SDK’s `Decision` and `Partial` APIs do not expose a way for callers to supply custom `Metrics`, enable `Instrument`ation, or attach a `Profiler`. The underlying `rego` package already supports these options, but the SDK currently ignores them, making it impossible to collect fine-grained performance data or profiling information when using the SDK to evaluate or partially evaluate policies.

We need to extend `DecisionOptions` and `PartialOptions` so that callers can optionally provide a `metrics.Metrics` instance, a `topdown.QueryTracer` to act as a profiler, and a boolean `Instrument` flag to enable instrumentation. The existing tracing option already accepts a query tracer; the profiler is a separate tracer that should be passed alongside it and handled equivalently.

Requirements and invariants:

- If a caller provides no `Metrics`, the SDK must continue to create and use its own internal metrics object (preserving backward compatibility), and those internal metrics must still be recorded in decision logs as they are today.
- If the caller provides a `Metrics` instance, that same instance must be used for all preparation and evaluation work triggered by that call, so the caller can inspect `m.All()` after the call and find all relevant timers, counters, and histograms.
- The `Instrument` flag and profiler tracer must be passed through to the rego evaluation and partial evaluation paths, mirroring how the existing `Tracer` is already forwarded.
- Query caching must still work correctly: when the SDK caches a prepared query and reuses it for a subsequent call, the second call’s metrics should *not* include preparation timers (e.g., `timer_rego_query_parse_ns`) because preparation was already performed during the first call. This should hold regardless of whether the caller supplies metrics or the SDK creates them internally.
- The changes should apply symmetrically to both `Decision` and `Partial`. For partial evaluation, partial-specific timers (e.g., `timer_partial`, `histogram_partial`) must appear in the supplied metrics when instrumentation is enabled.

The end state should enable code like:

```go
m := metrics.New()
p := profiler.New()
result, err := opa.Decision(ctx, sdk.DecisionOptions{
    Metrics:    m,
    Profiler:   p,
    Instrument: true,
})
// m.All() now contains full performance counters
// p.ReportTopNResults(...) yields profiling data
```

No other public API surface should change, and existing users who omit these new options must see no difference in behavior or performance.

sdk: Allow use of metrics, profilers, and instrumentation (#5459)


**Title:** OPA test runner incorrectly deduplicates test rule names across packages

**Description**

When running OPA tests that span multiple packages, the test runner currently treats test rule names as globally unique. If two different packages each contain a test rule with the same name (for example, both `data.foo` and `data.bar` have a rule named `test_duplicate`), the runner renames one of them (e.g., to `test_duplicate#01`). This changes the reported test name and can cause the test to fail or produce unexpected errors.

**Expected behavior**

The test runner should only disambiguate duplicate test rule names *within the same package*. If two packages independently define a test rule with an identical name, both rules should keep their original name without suffixed disambiguation. Only when a single package contains more than one test rule with the same name should suffixes (like `#01`, `#02`) be added.

**Steps to reproduce**

1. Create two policy files belonging to different packages.
2. In each package, define a test rule with the same name, e.g., `test_duplicate`.
3. Run the OPA test runner against both files.
4. Observe that the second package’s test rule is renamed (e.g., `test_duplicate#01`) and the test outcome may not match expectations.

**Acceptance criteria**

- When two test rules with identical names exist in **different** packages, both are treated as independent and neither is renamed.
- When two test rules with identical names exist in the **same** package, one is renamed with a numeric suffix to avoid ambiguity (e.g., `test_duplicate#01`, `test_duplicate#02`).
- Existing tests that rely on intra-package renaming continue to pass.
- No regressions in the test runner’s ability to locate and execute test rules that match the `test_` prefix.


**Title:** `opa build`: Add `--prune-unused` flag to skip transitive dependents of entrypoints for `wasm`/`plan` targets

**Problem:**
When building a bundle for `wasm` or `plan` targets (`opa build -t wasm -e entrypoint`), the compiler currently discovers all transitive dependents of the specified entrypoints and compiles them as well. This preserves semantic equivalence with the `rego` evaluator (needed when `with` statements are used), but it can be undesirable in several scenarios:

* The user wants a minimal bundle containing only the explicitly requested entrypoints.
* The automatically discovered dependents include functions that are not needed and, because functions cannot be entrypoints, the inclusion may cause build failures or unintended side-effects.
* For `plan` targets (an intermediate representation), the user may want to inspect only the compiled form of the exact entrypoints without any additional rules/functions.

There is currently no way to opt out of this dependent collection; the compiler always extends the entrypoint set.

**Request:**
Add a new boolean flag `--prune-unused` to the `opa build` command.

* When `--prune-unused` is set, the compiler must **not** add transitive dependents of the supplied entrypoints for `wasm` and `plan` targets. Only the explicitly listed entrypoints (and their data dependencies, if any) should be compiled into the resulting bundle.
* The flag must have **no effect** on `rego` bundles, which do not perform this dependent-collection step.
* The default behaviour (without the flag) must remain exactly as today: all transitive dependents are included to maintain semantic equivalence.

**Acceptance criteria (behavioural):**

1. `opa build -t wasm -e data.p.r --prune-unused` applied to a Rego module that defines `data.p.r` and an auxiliary function `data.p.f` that `r` calls, produces a bundle that contains only the compiled entrypoint `data.p.r`. The function `data.p.f` should be absent from the compiled output.
2. The same invocation without `--prune-unused` continues to include `data.p.f` as before.
3. The flag works identically for `-t plan`.
4. For `-t rego`, the flag is accepted but changes no behaviour (bundles remain byte-identical to builds without the flag).
5. No errors are introduced in existing workflows that do not use the new flag.

**Implementation notes:**
The CLI should parse the new flag and pass it through to the compiler. The compiler already has internal logic that gathers transitive dependents; the flag should conditionally disable that step for the `wasm` and `plan` targets. The flag should be named consistently across CLI and internal API (e.g., “prune unused”) to avoid confusion.

cmd/build+compile: allow opt-out of dependents gathering (#5038)


**Desired Behavior**
Decision log events emitted by the decision logger plugin must include error information whenever the corresponding server-side decision encountered an error. Today, even when a policy evaluation or query fails (e.g., divide-by-zero, type error, compilation error), the logged `EventV1` structure serializes with no `error` field, making it impossible to diagnose failures from the decision log alone.

**Acceptance Criteria / Observable Invariants**

1. **Error field in JSON output**
   When a decision error occurs, the serialized decision log event must contain an `"error"` field. When no error occurred, the field must be absent (using JSON `omitempty` semantics).

2. **Content of the error field**
   The `error` field must carry the exact error value from the server’s decision information (`Info.Error`), preserving its type. Both simple Go errors (e.g., `errors.New("some error")`) and structured aggregate errors (e.g., `ast.Errors` containing multiple `*ast.Error` values) must be faithfully reproduced, because downstream consumers may depend on the error structure for analysis.

3. **Extraction point**
   The decision logger plugin’s internal logic that maps a server decision into an `EventV1` must copy the error when it is non‑nil, in the same fashion as it already copies the result and metrics. This ensures that error propagation is consistent with how other decision metadata is handled.

4. **No regression for successful decisions**
   For decisions that complete without error, event output must remain unchanged (no spurious `error` fields, no change to existing keys).

**Scope / Non‑obvious Constraints**

- The decision log `EventV1` struct (defined for the logging plugin) must gain an `Error` field with the appropriate JSON tag so that serialization works automatically.
- The decision logger’s `Log` method must conditionally set this new field from the incoming `server.Info` when `Info.Error != nil`, and leave it zero otherwise.
- The fix should work with any `Logger` backend that conforms to the existing `Logger` interface, since the interface consumes `EventV1` values; no changes to the interface signature are required.
- Because errors may be aggregates (`ast.Errors`), the error must not be flattened into a string or lost when multiple errors are present; the whole value must be stored.

**Motivation**
Currently, operators and tooling that consume decision log events have no way to see evaluation errors in the log, even though the HTTP API returns error details. This gap prevents reliable auditing and debugging of failed policy decisions through the existing decision log pipeline.

Update decision log event to include error


**Title:** REST API returns 404 instead of 405 for known resources with unsupported HTTP methods

**Background**
The OPA server exposes a versioned REST API (`/v0/data`, `/v1/data`, `/v1/policies`, `/v1/query`) with well-defined allowed methods per endpoint. For example:

- `v0` data: `POST` only
- `v1` data: `GET`, `PUT`, `PATCH`, `POST`
- `v1` policies: `GET`, `PUT`, `DELETE`
- `v1` query: `GET`, `POST`

When a client sends a request to one of these known resource paths using a method that the API does not support (e.g. `GET /v0/data/foo`), the server currently responds `404 Not Found`. A `405 Method Not Allowed` response would be more accurate and useful, because the resource exists—the client simply used the wrong HTTP verb.

**Expected behavior**
For any request path that maps to a defined REST resource but with an HTTP method that has no registered handler, the server must respond with status `405` (no body required). The existing handlers for allowed methods must continue to work unchanged.

**Non-obvious constraints / edge cases**

- The routing framework (gorilla/mux) returns `404` when no route matches the method for a registered path pattern. We need to add explicit catch‑all handlers that produce `405` and are evaluated only when no more‑specific method handler matches.

- The catch‑all handlers must be registered **after** all concrete method handlers to avoid shadowing them.

- The precise set of forbidden methods differs per resource group. For example, `HEAD`, `CONNECT`, `DELETE`, `OPTIONS`, `TRACE` are never supported for data endpoints, but `v1/data` already has handlers for `GET`, `PUT`, `PATCH`, `POST`. The catch‑alls must be the complement of the allowed methods, including any method that would otherwise hit the default `404`.

- The special path `/v1/data/system/diagnostics` is a concrete `GET` endpoint. It must not be caught by a generic `/v1/data/{path:.+}` catch‑all. Ensure the ordering ensures diagnostics works correctly.

- The version prefixes (`/v0/…`, `/v1/…`) are part of the path; the catch‑alls should use the full path pattern, e.g. `/v0/data`, `/v0/data/{path:.*}`, `/v1/data`, `/v1/data/{path:.*}`, `/v1/policies`, `/v1/policies/{path:.*}`, `/v1/query`, `/v1/query/{path:.*}`.

- The response should be a simple status line with no body; a helper that writes only the status code would be sufficient.

Catch all REST handlers for forbidden methods


**Title:** Deprecate `SpanID.HexString` / `TraceID.HexString` and introduce `String()` methods

**Description:**

**Problem:**
The current `SpanID.HexString()` and `TraceID.HexString()` methods return an empty string when the ID is empty (all-zero bytes). This behavior is not defined in the OpenTelemetry specification and contradicts W3C recommendations for trace/span ID representation. We should discourage internal and external callers from depending on this particular representation, as it may change in the future.

**Impact:**
These methods are widely used in display/logging code (e.g., “Trace ID: %s”, `id.HexString()`) and in tests that verify the hex form of IDs. Removing or changing them without an alternative would disrupt those call sites and make common logging patterns awkward.

**Expected Behavior / Request:**
1. **Deprecate `HexString()`** on both `SpanID` and `TraceID` with a deprecation message advising callers to use `hex.EncodeToString(id[:])` when a canonical string identifier is needed.
2. **Add `String()` methods** that implement `fmt.Stringer`. The `String()` implementation should behave identically to `HexString()` (return empty string for empty IDs), but its documentation must make clear that it is *only for display/logging convenience* and is **not** a reliable way to obtain a string identifier.
3. **Update all internal callers** in the repository to stop calling `HexString()`:
   - Where a spec‑conformant, stable string identifier is required (for example, in assertions within tests), use `hex.EncodeToString` explicitly.
   - Where the ID is only used for display/logging (e.g., the logging exporter’s text marshalers), rely on the new `String()` method. This may require adjusting helper functions such as `logEntry` / `logAttr` so that they accept `interface{}` values, allowing the `%s` verb to handle both plain strings and `Stringer` implementations. The IDs can then be passed directly (e.g., `buf.logEntry("Trace ID: %s", traceID)`).

The goal is to provide a convenient logging path while nudging developers away from a behavior that is not specification‑backed.

**Additional notes:**
- The change affects the `pdata/pcommon` package (`SpanID`, `TraceID`) and any code that constructs log‑structured output using these types (notably the `otlptext` family of log/trace marshalers in `exporter/loggingexporter`).
- The `HexString` methods should remain for now but emit a deprecation warning; no removal is planned in this step.

[pdata] Deprecate HexString func on SpanID and TraceID (#6530)


**Title:** Log exporters are not started or shutdown, and are missing from the exporter map

**Description:**
The service’s lifecycle does not correctly start or stop log exporters. When the service starts, trace and metric exporters are initialized via `builtExporter.Start`, but the log exporter component is silently skipped. Similarly, `builtExporter.Shutdown` only tears down trace and metric exporters, leaving log exporters unstopped. This can cause log exporter connections to remain unopened (or, on shutdown, to leak resources).

Additionally, `Exporters.ToMapByDataType` returns maps only for traces and metrics; log exporters are entirely omitted. Any code consuming this map (for example, to expose exporters via the component host) therefore never sees log exporters.

The root cause appears to be that `builtExporter` stores exporters per signal type but the lifecycle methods only iterate over the trace and metric fields, while the log field is ignored. Similar gaps exist in the way the exporter map is populated.

**Expected behavior:**
- All exporter types configured for a pipeline (traces, metrics, logs) are started when the service starts.
- All exporters are shutdown when the service stops.
- `Exporters.ToMapByDataType` includes a map for log exporters alongside traces and metrics.
- Corresponding tests that check start/shutdown behaviour should cover log exporters as well, so the fix is verified.

**Notes:**
- The implementation should handle the case where an exporter supports multiple data types and ensure each one is started/stopped exactly once.
- No change is required to the creation of individual log exporters; focus on the lifecycle wiring and exporter-map construction in the `service/builder` package.

Ensure that all exporters are started/shutdown (#1943)


In the Jaeger-to-traces translation path, and in one helper test, we are using `Append` to insert pre‑constructed pdata elements into slices when those elements could instead be built directly in the target slot. This causes unnecessary copies and intermediate allocations. Update the relevant code to avoid such copies while keeping the translation output identical.

**Acceptance criteria / behavioral changes**
1. **Jaeger batch translation** (`translator/trace/jaeger/jaegerproto_to_traces.go`)
   - When aggregating spans by instrumentation library, the intermediate data structure should no longer contain fully‑constructed `InstrumentationLibrarySpans` objects. Instead, store only the `SpanSlice` for each library.
   - In the final step that populates the destination resource spans, create each `InstrumentationLibrarySpans` via `AppendEmpty`, set its library name/version (if present) directly on the returned object, and move the collected span slice into it using `MoveAndAppendTo`.
   - The net result must be **semantically identical** to the previous code: every span appears under the correct library, library name/version is preserved, and no spans are duplicated or lost.

2. **`AttributeValueToString` test helper** (`translator/internaldata/resource_to_oc_test.go`)
   - The code that adds an empty `AttributeValueArray` element into an array should be changed to avoid a separate `NewAttributeValueArray` allocation and subsequent `Append`. Instead, call `AppendEmpty` on the target array and then directly copy the empty array value into that slot.
   - The assertion on the final string representation must continue to pass unchanged.

**Safety / non‑obvious constraints**
- Do **not** change any other translation logic, field mappings, or the structure of the generated traces.
- Ensure that when library information is empty, no library object is created (or it remains untouched), matching the current behavior.
- The change must not introduce panics due to nil slices; the new `AppendEmpty`/`MoveAndAppendTo` calls must handle the case where a library entry has zero spans gracefully.

Remove some usage of Append where easy to avoid (#3027)


**Feature request: Consolidate collection interval to the scraper controller level and batch scrapers**

Currently the `receiverhelper` package allows each scraper added to a scraper controller to specify its own collection interval (via `ScraperSettings` and the `CollectionInterval` method on `BaseScraper`). The controller then creates a separate goroutine and a separate `time.Ticker` for every scraper, running each scraper’s scrape independently and forwarding the results to the next consumer as individual `Metrics` payloads.

This has several downsides:

1. **Unbounded goroutine/ticker growth** – every scraper adds a long-lived goroutine and ticker regardless of whether they share the same interval.
2. **No batching** – scrapers that logically belong together (e.g. all scrapers from a host metrics receiver) cannot be combined into a single `Metrics` object before being consumed, because each runs in isolation.
3. **Inconsistent API surface** – the scraper controller has a `WithDefaultCollectionInterval` option and a `defaultCollectionInterval` field, but those are overridden by each scraper’s own interval if set. This makes it unclear who owns the real scheduling interval.

We should change the scraper controller so that:

- The collection interval is a **single controller-level setting**, not a per-scraper setting.
- The controller runs **one ticker (or single ticker channel)** and, on every tick, scrapes **all associated scrapers** and merges their results into one `Metrics` payload that is passed to the next consumer.
- The `collection_interval` configuration is defined on a new `ScraperControllerSettings` struct (embedding `ReceiverSettings`) that replaces the old `configmodels.Receiver` parameter in `NewScraperControllerReceiver`. A default of one minute should be supplied.
- Invalid (zero or negative) collection intervals are rejected at construction time.
- All per-scraper interval APIs (`ScraperSettings`, the `CollectionInterval` method on `BaseScraper`, the `CollectionInterval` method on `multiMetricScraper`, and the `WithDefaultCollectionInterval` controller option) are removed to avoid confusion.
- `AddMetricsScraper` should accumulate `MetricsScraper`s into a single `multiMetricScraper` that batches them at scrape time (already partially implemented), and that combined scraper should be treated as one `ResourceMetricsScraper` among the controller’s list of `ResourceMetricsScraper`s.
- `AddResourceMetricsScraper` should directly append the scraper to the controller’s list.
- A new `WithTickerChannel` option (test-only) should allow tests to inject an external ticker channel so that test logic can control exactly when a scrape occurs, without depending on real time.
- The internal scrape method (`scrapeMetricsAndReport`) should iterate all `ResourceMetricsScraper`s, collect their `ResourceMetricsSlice`, and move them into a shared `Metrics` object before forwarding—this way all scraped data from one tick is sent as a single unit.

The intended behavior change is that callers who previously relied on per-scraper intervals (e.g. setting a custom `collection_interval` inside a scraper config block) will now need to set the interval at the receiver level instead. This simplifies the codebase and enables efficient batching of scraper work.

Remove ability to configure collection interval per scraper (#1947)


Simplify queue consumption in `exporterhelper/internal`. The `Queue` interface currently exposes `Poll() (QueueRequest[T], bool)`, which returns a wrapper that carries the item, its context, and a possible `OnProcessingFinished` callback. This wrapper is unnecessary for the memory queue and adds memory overhead even when the callback is never set.

Replace `Poll` with a `Consume(func(context.Context, T)) bool` method. The method blocks until an item is available or the queue is stopped, then calls the provided function with the item and context. The persistent queue must still perform its post-processing cleanup (dispatching-finish and client unref) after the consumer function returns, but that cleanup must be handled internally inside `Consume`—the caller should no longer see or invoke a cleanup callback.

Delete the `QueueRequest` type and the `newQueueRequest` helper. Update the bounded memory and persistent queue implementations, and the `QueueConsumers` caller, to use the new interface. Preserve all existing behavior, including error handling in the persistent queue's storage operations. The change should reduce memory usage in the bounded queue while keeping the persistent queue's cleanup semantics intact.

[chore] [exporterhelper] Simplify queue consumption logic (#8982)


In the `obsreporttest` package, the `Check*` functions (`CheckExporterTraces`, `CheckExporterMetrics`, `CheckExporterLogs`, `CheckProcessorTraces`, `CheckProcessorMetrics`, `CheckProcessorLogs`, `CheckReceiverTraces`, `CheckReceiverLogs`, `CheckReceiverMetrics`) each require a `component.ID` argument, even though the `TestTelemetry` instance already knows its own ID. Remove the `component.ID` parameter from these calls by turning them into methods on `TestTelemetry` that use the internal `id` field. Keep the old package-level functions as deprecated wrappers so existing external users don't break immediately, and add deprecation doc comments pointing to the new methods. Update all internal callers across the repository to use the new method form.

Deprecate obsreporttest.Check* in favor of TestTelemetry.Check (#6678)


**Request: Refactor configuration lifecycle into a reusable ConfigProvider**

The collector currently creates a new configuration watcher on every reload, which introduces several problems:

1. The previous retrieval session is not explicitly closed before a new one is started, causing resource leaks.
2. The watcher’s shutdown logic is only invoked on final collector shutdown, never during reloads.
3. The lifecycle of the underlying `ConfigMapProvider` is not tied to the watcher; it is never shut down.

We need a dedicated `ConfigProvider` abstraction within the `service` package that embodies the full lifecycle of configuration retrieval and watching, replacing the existing per-reload `configWatcher`.

**Behavioral requirements:**

- **Single instance per Collector:** The `ConfigProvider` must be created once during `Collector` construction (not inside the configuration setup path). The same instance must be reused across all reload cycles.
- **Session lifecycle on retrieval:** Every call to retrieve a new configuration (`Get`) must first close the previously retrieved session (if any). This guarantees no outstanding sessions accumulate.
- **Ignore session-closed events:** When the underlying retrieval fires an error equal to `configsource.ErrSessionClosed`, the `ConfigProvider` must not forward that error on its watch channel. Doing so would trigger a spurious config reload.
- **Watch channel contract:** The `ConfigProvider` must expose a dedicated watch channel. The `Collector`’s reload loop should receive from this channel to wait for configuration changes, rather than directly accessing an internal field.
- **Full shutdown:** When the `ConfigProvider` is shut down, it must:
  - Close the watch channel (so any goroutine reading from it can exit cleanly).
  - Close the current retrieved session (if any).
  - Shut down the underlying `ConfigMapProvider`.
- **Removal of old watcher:** The `configWatcher` type and its associated tests should be removed once the `ConfigProvider` is in place.
- **Collector integration:** The `Collector`’s `setupConfigurationComponents` should call the provider’s `Get` method to obtain the configuration, and the main reload loop should rely on the watch channel and the persistent provider instance, without manually shutting down configuration resources on every reload.

Rename config watcher to config provider in service, clean api (#4569)


**Title:** Log sampling counters should be shared globally, not allocated per-component logger

**Description:**
When internal log sampling is enabled (`service::telemetry::logs::sampling`), the collector allocates a large amount of memory that scales with the number of configured pipeline components (receivers, processors, exporters). Each component gets its own `zap` logger with component-identifying attributes, and apparently each such logger creates an independent set of sampling counters. This is unexpected because sampling is intended to apply to the *aggregate* log output, not per-component, and the large counter arrays (reportedly around 500 KB each) quickly add up to hundreds of megabytes in realistic configurations.

A partial mitigation landed in v0.126.0 for the case where logs are only written to stdout, but the same memory issue persists when logs are also exported via OTLP (`service::telemetry::logs::processors`). The fix should ensure that **one** set of sampler counters is shared across all loggers (console, OTLP, and all component-scoped loggers), regardless of the number of components or the configured log processors.

**Expected behavior:**
- Only one allocation of sampling counters (the internal `zap` sampler state) exists in the collector process, even when many components are present and OTLP log export is active.
- Sampling behavior is globally uniform: the first N messages are allowed, then every M thereafter, where N and M come from the user’s sampling config; this should not reset per component.
- The change must preserve the existing ability to inject component attributes into log entries without causing duplicate counter allocations.

**Impact:**
Collectors with hundreds of pipeline components (as reported in #13014) become memory-constrained when log sampling is turned on, making the sampling feature unusable at scale. This hurts observability of the collector itself, which is critical for production deployments.

[service] Share log sampler core allocations with reflect magic (#13107)


```
pdata model: Value.Type() does not panic on zero-initialized Value, contradicting its own documentation

The doc comment for `Value.Type()` explicitly states:
  "Calling this function on zero-initialized Value will cause a panic."
However, the current implementation returns `ValueTypeEmpty` when the underlying value is nil, instead of panicking.
This means zero-initialized Value silently passes through type checks, violating the documented contract and potentially hiding bugs.

Expected behavior:
- Calling `Type()` on a zero-initialized Value (not constructed via the NewXxxValue constructors) MUST panic.
```


When generating component config schema JSON via `mdatagen`, certain alias references in `$defs` produce empty `{}` objects instead of the expected full definition. This occurs, for example, when a definition in `$defs` has a `$ref` pointing to a local file (like `./internal/controller.controller_config`) and the root schema already contains a `$defs` entry with the same name—the resolver returns the root entry as-is without further resolution, yielding an empty schema object.

Fix the alias resolution logic in the schema generation code (`internal/schemagen`) so that:

1. Local file references always load the referenced schema from the file, even when a root `$defs` entry with the same definition name exists.
2. Self-referencing definitions do not resolve to themselves (no identity loop that bypasses resolution).
3. External references are never shadowed by root `$defs` entries that happen to use the same definition name.
4. Internal alias chains (one def referencing another def within the same `$defs`) resolve through the full chain correctly.

[chore][cmd/mdatagen] Fix config schema alias resolution (#15299)


We need to align JSON float64 parsing with the way we already handle other numeric types.

**Background**
Our internal OTLP JSON unmarshaler (used for metrics and attribute values) already accepts both raw numbers and string-encoded numbers for int32, uint32, int64, and uint64 fields—this is implemented through the `ReadInt32`/`ReadUint32`/… helpers in `pdata/internal/json`. Float64 fields, however, are still read with a plain `iter.ReadFloat64()` call in every location, which only accepts JSON numbers. That causes unnecessary parse failures when a producer sends double values as strings, which is a valid pattern under protobuf JSON mapping conventions (e.g., to avoid losing precision in some environments).

**Request**
Make float64 JSON parsing consistent with the integer paths: everywhere we currently read a float64 value during JSON unmarshalling (metric data points, exemplars, attribute `doubleValue`/`double_value`), accept both a bare JSON number and a JSON string that contains a valid float literal.

**Behavioural contract**
- When the next JSON token is a number, parse it as a float64 (current behaviour is retained here).
- When it is a string, parse its content as a float64 using the same logic as `strconv.ParseFloat(…, 64)`; if parsing fails, report a clear error through the iterator.
- Any other JSON value type (`true`, `null`, object, array) must be reported as an error — do not silently return a zero value.
- The fix must cover every existing call site that currently calls `iter.ReadFloat64()` directly in the OTLP JSON unmarshaler. Follow the existing pattern of the integer helpers: introduce a shared helper, and update every call site to use it.

**Deliverable**
A patch that ensures float64 fields accept both number and string representations, with correct error handling for malformed strings and unexpected types, matching the behaviour already established by `ReadInt32`, `ReadUint32`, `ReadInt64`, and `ReadUint64`.


Title: `CorrectnessTestValidator` should use `pdata` API instead of internal protobuf types, and handle Jaeger incompatibilities

**Description**
The trace correctness validator in the testbed (`CorrectnessTestValidator`) currently accesses internal protobuf types (`otlptrace.Span`, `otlpcommon.KeyValue`, etc.) to compare sent and received spans. This breaks the abstraction layer: the validator should work through the public `pdata` wrappers (`pdata.Span`, `pdata.AttributeMap`, `pdata.SpanLink`, etc.) so that it remains decoupled from internal proto representation changes and matches how all other components interact with telemetry data.

Additionally, the `DataProvider` interface exposes a `GetGeneratedSpan` method that returns a raw protobuf `*otlptrace.Span`. This encourages the validator to operate on internal types and should be removed. For correctness tests that use golden data, the validator can instead build a `pdata`-based lookup map from the traces that were already generated by the provider.

There is also a known problem with Jaeger: it does not faithfully preserve span link attributes and `tracestate`. Therefore, tests that involve a Jaeger sender or receiver produce false mismatches in those fields. The validator should be aware of the protocol in use and, when either the sender or receiver is `"jaeger"`, skip comparison of link attributes and link trace state.

**Expected behavior**
- All span field comparisons (trace ID, span ID, parent span ID, name, kind, timestamps, attributes, events, links, status, etc.) use the public `pdata` accessor methods.
- The `DataProvider` interface no longer includes `GetGeneratedSpan`.
- The `CorrectnessTestValidator` constructor accepts sender and receiver protocol names (e.g., `"otlp"`, `"jaeger"`, `"zipkin"`) and stores a flag to disable link attribute/tracestate checks when either protocol is `"jaeger"`.
- The validator correctly identifies sent spans by iterating over the `pdata.Traces` structures (for golden data tests) instead of relying on a provider method that leaks internal types.
- Event and link comparison helpers work on `pdata.SpanEventSlice` and `pdata.SpanLinkSlice`, using `pdata.AttributeMap.ForEach` and `pdata.AttributeValue.Equal` for attribute comparisons.

**Impact**
Fixes spurious test failures caused by proto-level comparison and Jaeger limitations, and makes the testbed consistent with the rest of the collector by using the public `pdata` APIs.

Change testbed validator to use pdata (#2561)


**Title:** Refactor exporterhelper internal senders to use standard component lifecycle

**Request:**
The `requestSender` interface in `exporterhelper` defines ad‑hoc `start`/`shutdown` signatures that are not the standard `component.Component` methods. This prevents composition with component helpers and forces unnecessary `CreateSettings` passing at startup.

Refactor `requestSender` to embed `component.Component`. Remove the custom `start`/`shutdown` methods and have all senders implement the standard `Start(ctx, host)` / `Shutdown(ctx)` instead. The `baseRequestSender` can bring in `component.StartFunc` / `component.ShutdownFunc` so zero‑value bases get no‑op implementations without extra code.

The `queueSender` receives `exporter.CreateSettings` through `QueueSettings` during start; eliminate that indirection. Pass `exporter.CreateSettings` at construction time (e.g., to `newQueueSender`), store the logger and meter on the struct, and use them directly from `Start` (for metric registration) and `Shutdown`. Remove the `exporter.CreateSettings` field from `internal.QueueSettings`.

The persistent‑queue path similarly should accept `exporter.CreateSettings` at construction (`NewPersistentQueue`) and use the stored ID and logger for the storage connection, rather than fetching them from `QueueSettings.CreateSettings`.

In `baseExporter`:

- `Start` must call `be.queueSender.Start(ctx, host)` (no extra `set` argument).
- `Shutdown` must call the standard component methods in the correct order: retry sender first (so it pushes any pending requests back to the queue), then queue sender, then the wrapped exporter’s shutdown. Use `multierr.Combine` directly instead of the old append pattern.

Rename `retrySender.shutdown` to `Shutdown` (exported) so it matches the interface.

All behavior must remain identical; this is purely an interface‑cleanup to align the sender chain with the component model.

**Notes:** No new configuration or user‑facing change. Ensure all tests compile and pass with the adjusted constructor signatures and removed `CreateSettings` from `QueueSettings`.

Use standard component Start/Shutdown func in exporterhelper (#8861)


The collector does not properly handle the lifecycle of `ParserProvider` implementations that support watching for configuration updates or require explicit cleanup. The base `ParserProvider` interface in `service/parserprovider` only exposes a `Get` method; there is no way for the application to know that a provider is watchable or needs to be closed.

This causes two concrete problems:

1. **Missing watch integration**: When a `ParserProvider` is backed by a config source manager (e.g., `configsource.Manager`) that implements a `WatchForUpdate` mechanism, the collector never starts a watch loop. As a result, dynamic configuration changes are never detected, and the service never reloads automatically. The replaceable backends already provide `WatchForUpdate()` that blocks until a change occurs or the session is intentionally ended, but the application ignores it.

2. **Resource leaks on reload and shutdown**: The `reloadService` path (formerly `updateService`) tears down the running service and creates a new one from the latest configuration, but the old `ParserProvider` is never given a chance to release resources (e.g., close sessions, cancel subscriptions). Similarly, during application shutdown, no `Close`-like method is invoked on the provider. This can leak network connections, background goroutines, or other resources held by the config provider.

**Expected behavior**:

- If a `ParserProvider` implements an optional `Watchable` interface with `WatchForUpdate() error`, the application should start a background goroutine that calls `WatchForUpdate()`. When the function returns without error (or with a specific sentinel indicating a clean session close, such as an intentional shutdown signal), the application should trigger a configuration reload by calling the existing service-refresh logic. If the error is a “session closed” sentinel (e.g., `ErrSessionClosed`), the watcher should log and exit without reloading.
- If a `ParserProvider` implements a `Closeable` interface with `Close(ctx context.Context) error`, the application must:
  - Call `Close` on the provider during a full application shutdown, before the service is shut down, and collect any error.
  - Call `Close` on the *current* provider at the beginning of a reload cycle, so that the old provider can clean up before a new one is instantiated. A failure to close should be returned as an error from the reload function.

**Context / impact**:

The existing `ParserProvider` interface currently has no lifecycle methods. Providers that need cleanup (like those wrapping a `configsource.Manager` that holds sessions and watcher goroutines) cannot integrate properly. This blocks adopters from implementing dynamic configuration sources that react to external changes or require graceful teardown. The fix should add the necessary optional interfaces alongside `ParserProvider` and integrate the lifecycle calls into `setupConfigurationComponents` (for watch) and `execute` / `reloadService` (for close), making sure the watcher correctly distinguishes a deliberate shutdown from an unexpected error that should trigger a reload.

Adding Watchable and Closeable to ParserProvider interface (#2954)


**Title:** Add `GetOrInsertDefault()` method to `configoptional.Optional`

**Background**
The `configoptional` package provides an `Optional[T]` type with three states: `Some(value)`, `Default(value)`, and `None`.  Callers constructing programmatic configurations (e.g., wiring up a receiver with an optional sub‑config) currently have to reach for `HasValue()` / `Get()` and manually fall back to an empty confmap unmarshal to obtain a usable pointer.  This pattern is duplicated across multiple test packages (e2e, otlpreceiver) as a private helper that takes `*testing.T`, but the same need exists in non‑test, programmatic setups.

**Request**
Add a public method on `*Optional[T]` that:

- Guarantees the optional is `Some` after the call.
- Returns `*T` pointing to the inner value so the caller can mutate it in place.
- Behaves as follows for each initial state:
  * `Some(v)` → return existing `v` unchanged (idempotent).
  * `Default(v)` → promote to `Some(v)`, return the pre‑stored default `v`.
  * `None` → promote to `Some(zeroVal)` where `zeroVal` is `T`'s zero value (identical to the effect of unmarshalling an empty map).
- Must not require `*testing.T` as a parameter (the method should be usable outside tests).
- Must panic immediately if `T` is not a struct or if `T` has a field tagged `mapstructure:"enabled"`—the same constraints already enforced by `Some`/`Default`/`None` for `Optional`.  The panics should use the existing `assertStructKind` / `assertNoEnabledField` helpers.
- In the `None`/`Default` paths the method should reuse the existing `Unmarshal` logic (unmarshal an empty `confmap.Conf`) to produce the value, keeping the single source of truth for how defaults are filled.

**Acceptance Criteria**
- The new method exists on `*Optional[T]` and satisfies the contract above.
- Unit tests cover `Some`, `Default`, `None`, `None[T]()` zero value behavior, and the panic cases for `T` that is not a struct or has an `enabled` field.
- All existing in‑repository call sites that previously used the duplicated `GetOrInsertDefault` helper functions are updated to use the new method, and those helper definitions are removed.

**Notes**
The helper duplication this replaces can be found by searching for functions named `GetOrInsertDefault` in non‑vendor code.  Those callers currently pass `*testing.T`; the new method must not require a test handle.

[configoptional] Add GetOrInsertDefault method (#13859)


When `Unmarshal` is called on a `*Conf` and a top-level custom unmarshaler/marshaler (e.g., an embedded struct implementing the `Unmarshaler`/`Marshaler` interface) returns an error, the error message is currently prefixed with `error decoding '': `. This prefix comes from the `mapstructure` wrapper and is confusing because the key is empty at the top level. Strip that prefix from the error so that the caller sees only the underlying error text. Errors from non-top-level keys (where the key is non-empty) should be left unchanged.

[chore] Remove the top level error if it indicates an empty name (#9763)


**Title:** OTLP receiver cannot be shut down and re-created with the same configuration

**Component:** `receiver/otlpreceiver`

**Problem:**
The OTLP receiver factory caches a single `otlpReceiver` instance per `Config` in a global map (to ensure that trace/metric/log receivers share the same underlying server). However:

1. The cache entry is never removed when the receiver is shut down. If a receiver is stopped and then a new receiver is requested with the *same configuration*, the factory returns the already‑shutdown instance. That instance cannot be started again and behaves incorrectly.

2. The `Shutdown` method signals the gRPC and HTTP servers to stop but does not wait for their serving goroutines to actually exit. This leaves the shutdown incomplete (e.g., ports still in use) and can cause races if a new receiver with the same configuration is created immediately.

3. Because of (1) and (2), the `TestDefaultReceivers` lifecycle test in `service/defaultcomponents` currently marks the OTLP receiver as `skipLifecyle: true`. Once the caching and shutdown issues are fixed, this test should cover the OTLP receiver without the skip.

**Expected behavior:**
- After `Shutdown` completes, the cached receiver entry must be cleaned up so that a subsequent call to create a receiver with the same configuration constructs a fresh, functional `otlpReceiver`.
- `Shutdown` must wait until all server goroutines have fully returned before returning, ensuring the shutdown is complete.
- The lifecycle test in `service/defaultcomponents` must pass for the OTLP receiver; the `skipLifecyle` flag should be removed.

**Constraints / Notes:**
- An OTLP receiver instance can only be started and shut down once. The fix must not try to restart a shut‑down instance; it must allow a *new* instance to be created for the same configuration after the old one has been fully shut down.
- The existing comment in `factory.go` describing the receiver map should be updated to document that entries are removed on shutdown.
- No changes to the public API of the receiver factory or the `otlpReceiver` type are required beyond fixing the lifecycle.

Allow multiple OTLP to be created (#2743)


Bug: tailsampling processor forwards traces multiple times to the next consumer when multiple sampling policies sample the same trace

**Observed behavior**
When the tailsampling processor is configured with more than one sampling policy and a trace matches multiple policies that all decide to sample, the trace gets sent to the next consumer (exporter / next pipeline component) once for every matching policy. This causes duplicate trace data to appear downstream, inflating span counts and other metrics.

**Expected behavior**
A trace should be forwarded to the next consumer **exactly once** per evaluation cycle, regardless of how many policies return a `Sampled` decision. If any policy decides to sample, the trace is sampled; the number of sampled policies should not multiply the output.

This invariant must also hold for late-arriving spans: when a span belonging to an already-sampled trace arrives late, it should be sent to the next consumer only once, not once per policy that would have sampled the trace.

**Impact**
With policies like "always_sample" and a rate-limiting policy that both match, every span appears N times in the exporter output (N = number of configured policies). This breaks downstream consumers that expect exactly-once delivery and leads to incorrect metrics, storage waste, and observability data corruption.

tailsampling: only send to next consumer once (#1735)


```
Title: --feature-gates flag ignored when running Collector as Windows service

Description:

I run the OpenTelemetry Collector as a Windows service and pass `--feature-gates` flags to control experimental features. The collector starts without error, but the specified feature gates are ignored; it always uses its built-in defaults.

If I stop the service and launch the same collector binary directly from a command prompt using exactly the same arguments, the feature gates are applied correctly.

This makes feature gates unusable on Windows when the collector runs as a service – I cannot enable or disable experimental features without recompiling, which defeats the purpose of the flag.

Expected behavior:
Feature gate flags should be parsed and applied consistently, whether the collector is started as a Windows service or as a normal process. The flag should control the same set of gates in both modes.

Environment:
- Windows service installation via `otelcol` (version latest)
- Flags passed as service startup parameters or through the service configuration
```

Consistent pattern usage for command flags (#6285)


Title: CombineErrors drops permanent error status

Description
The `componenterror.CombineErrors` function aggregates a list of errors into a single error, but it always produces a plain error. When one or more of the input errors were created with `consumererror.Permanent`, the resulting combined error never satisfies `consumererror.IsPermanent`. Downstream code that uses `IsPermanent` to decide whether an error is retriable therefore misclassifies combined permanent failures as transient and may retry them indefinitely.

Expected behavior
If any error in the input list is permanent, the error returned by `CombineErrors` should itself be permanent (i.e., `consumererror.IsPermanent` should return `true`). The combined error message should still include all individual error messages.

Minimal reproduction
```
perm := consumererror.Permanent(fmt.Errorf("permanent failure"))
errs := []error{fmt.Errorf("transient"), perm}
combined := componenterror.CombineErrors(errs)
// combined is not permanent, but should be.
fmt.Println(consumererror.IsPermanent(combined)) // outputs false, expected true
```

Impact
Components that combine errors from multiple sub-operations (e.g., exporters, receivers) and rely on the permanence flag lose that signal, potentially leading to stuck retry loops.

change combineerrors to return permanent error (#1743)


**Title:** Prometheus remote write exporter should signal permanent vs. transient errors

**Description:**
Currently, the Prometheus remote write exporter returns generic errors in almost every failure path. The collector treats all of these as transient and retries them, even when the error is guaranteed to never succeed on retry. This wastes CPU, delays processing of subsequent data, and can lead to endless retry loops.

**Observed behavior:**
- Exporter returns `errors.New(...)` for invalid metric type/temporal combinations, unsupported metric types, failures inside scalar/histogram handling, serialisation failures, HTTP request construction errors, and for any non-2xx HTTP response.
- The collector’s exporter helper sees only non-permanent errors and retries them all.

**Expected behavior:**
- Errors that are not retryable should be wrapped as **permanent errors** so the collector can skip retrying them. This includes:
  - Invalid metric type/temporal combination (data problem)
  - Unsupported metric type (data problem)
  - Errors from `handleScalarMetric` / `handleHistogramMetric` (data / transformation errors)
  - Serialisation / encoding errors (proto marshalling)
  - HTTP request creation errors
  - Non-2xx HTTP status codes **except 5xx** (4xx, 3xx, etc. represent client errors that won’t change on retry)
- HTTP **5xx status codes** (and any other transient errors, e.g., transport failures) should remain as *non-permanent* errors so the exporter retries them.
- The error classification should follow the existing collector convention (using `consumererror.Permanent` or an equivalent permanent-error marker recognised by the exporter helper / retry logic).

**Impact:**
Without this change the exporter wastes resources retrying bad data and may never progress past a broken batch. Proper error signalling aligns it with other exporters and improves overall stability.

Return permanent errors in prometheus remote write exporter (#2053)


```
Title: Provide direct Request constructors accepting pdata signals and deprecate SetX methods

The OTLP request wrappers plogotlp.Request, pmetricotlp.Request, and ptraceotlp.Request
currently require a two-step initialisation to carry signal data:

    req := plogotlp.NewRequest()
    req.SetLogs(ld)

Replace this with constructors that accept the corresponding pdata type directly:

    req := plogotlp.NewRequestFromLogs(ld)

The new constructors must preserve the existing “wrapper” invariant: the returned Request
and the original pdata value must share the same underlying protobuf representation, so
mutations to either are visible to the other – exactly as happens today with NewRequest +
SetX.

Acceptance criteria

• Add NewRequestFromLogs(plog.Logs) Request to package plogotlp.
• Add NewRequestFromMetrics(pmetric.Metrics) Request to package pmetricotlp.
• Add NewRequestFromTraces(ptrace.Traces) Request to package ptraceotlp.
• Deprecate the existing SetLogs, SetMetrics, SetTraces methods on the respective
  Request types with a comment pointing to the corresponding NewRequestFrom… constructor.
  Keep the methods functional so callers are not broken.
• Update all internal usages (exporters, receivers, and the pdata packages’ own tests)
  to use the new constructors instead of NewRequest + SetX.
• Update CHANGELOG.md with the deprecations.
```

[pdata] Replace `Request.Set<Signals>` with NewRequestFrom<Signals> (#5234)


The test verification helpers in `obsreporttest` (e.g., `CheckReceiverTraces`, `CheckExporterTraces`, `CheckProcessorMetrics`, etc.) currently take a `*testing.T` and call `require.NoError`/`require.Equal` internally. This forces any test that wants to check exported metrics to use the `testify/require` assertion library and fails the test directly inside the helper.

**Problem:**
Tests that prefer a different assertion style or that need to defer failure handling cannot use these helpers. For example, when a test wants to collect multiple check failures before aborting, the current behavior causes an immediate `t.Fatal` via `require`.

**Expected behavior:**
Refactor all `Check*` functions in the `obsreporttest` package to return `error` instead of accepting `*testing.T`. The helpers should use `view.RetrieveData` and compare values internally, returning a descriptive error when the expected values are not found or do not match (including cases where no row with the expected tags is present). The caller then asserts on the returned error using whatever testing library or pattern they choose (e.g., `if err != nil { t.Error(err) }`, `require.NoError`, etc.).

**Impact and additional constraints:**
- All test call sites within the repository that currently depend on these functions passing `t` must be updated to check the returned error (for example wrapping with `require.NoError`).
- The internal `checkValueForView` helper must also be updated to return `error` and produce informative messages when tags are not found or values mismatch. Remove the dependency on `testify/require` from the package so that the package itself no longer imports `github.com/stretchr/testify/require`.
- The change should not alter the semantics of the checks: the same metrics views are examined and the same value comparisons are performed; only the error propagation pattern changes.

obsreporttest now returns an error (#4080)


Add a warning log when a server's listening address is unspecified (the "0.0.0.0" address or its shorthand forms like `:port`), since listening on all interfaces can increase exposure to Denial of Service attacks. The warning should link to the security best practices documentation. Apply this in both `configgrpc` (gRPC server) and `confighttp` (HTTP server) server configuration. For gRPC, only emit the warning when the transport is TCP or UDP; do not warn for Unix domain socket transports. The warning must be a log at Warn level and must never cause an error – it should not reject the endpoint, just inform the operator.

[unrevert][config{grpc,http}] Add warning when using unspecified address (#6421)


---
**Title:** Builder default config produces empty module path, breaking generation

**Background & Problem**
`DefaultConfig()` returns a builder configuration with an empty `Distribution.Module`. The scaffolded `go.mod` uses `{{.Distribution.Module}}` as the Go module path, resulting in an invalid `module ` line. A call to `Generate(cfg)` (or `GenerateAndCompile`) with the default configuration therefore produces output that fails to compile.

**Desired Behavior**
- `DefaultConfig()` should include a sensible, valid Go module path for `Distribution.Module` so that the generated output compiles without manual intervention. A natural choice is the builder's own module path (`go.opentelemetry.io/collector/cmd/builder`).
- The default configuration should pass both `ParseModules()` and `Validate()` without error.
- Basic tests should confirm that:
  - The default configuration validates successfully.
  - Generating (and optionally compiling) from the default configuration succeeds.
  - Invalid collector versions or output paths that cannot be created are handled with clear errors.

**Constraints**
- Must not break existing tests that rely on the default config’s behavior.
- The added default should not interfere with explicit configuration loaded from YAML/manifest files (i.e., only a fallback when no distribution config is provided).

**Acceptance Criteria**
- Running `builder` (or using its API) with the zero-config default produces a compilable Go module.
- Tests verify generation and compilation from the default configuration without requiring any user-supplied manifest.

[tests] adding tests for builder (#4385)


**Title:** Make exporter observability metrics always carry the exporter name tag without caller-managed context

**Background**
The `obsreport` package currently provides a public `ExporterContext` function that callers must use to inject the exporter name tag into a context before calling `Start...ExportOp` / `End...ExportOp`. This is fragile: if a caller forgets to use `ExporterContext`, the resulting metrics (spans sent, failed spans, metric points, log records) are recorded without the exporter name tag, making them impossible to attribute to the correct exporter and breaking downstream monitoring.

Additionally, there is a latent bug: `NewExporter` initialises the stored mutator with `tagKeyProcessor` rather than `tagKeyExporter`, so even if the mutator were used it would attach the wrong tag key.

**Request**
1. Make `Exporter` self-sufficient: all metrics recorded through its `End...ExportOp` methods must always include the exporter name tag, without depending on callers to create a special context. The exporter name is already known at construction time; the existing `mutators` field should be used to apply the tag automatically during metric recording.
2. Remove the public `ExporterContext` function once callers no longer need it.
3. Fix the `NewExporter` bug so the mutator uses `tagKeyExporter` instead of `tagKeyProcessor`.
4. Update all internal call sites (notably in `exporter/exporterhelper` for traces, metrics, and logs) to stop calling `ExporterContext` and pass the original parent context directly.
5. Update the corresponding tests in `obsreport` and `obsreport/obsreporttest` to align with the new contract.

**Acceptance criteria**
- `Exporter.End*ExportOp` calls record metrics tagged with the correct exporter name even when the caller passes a plain context.
- `ExporterContext` is fully deleted from the codebase.
- No regressions in existing observable behaviour; all exporter observability tests continue to pass.

Remove obsreport.ExporterContext, always add exporter name as a tag (#2682)


The batch processor's `splitMetrics` function currently violates the expected ordering of metrics when a metrics payload exceeding the send batch size is split into smaller payloads. Specifically, the metrics within each split chunk are returned in reverse order relative to the original payload. This affects any downstream exporter or consumer that relies on the order in which metrics are received.

**Expected behavior:** splits should preserve the original sequential order of metrics—the first chunk should contain the first `size` metrics from the source payload, the second chunk should contain the next `size` metrics, and so forth, without reversing elements at any level of the hierarchy (ResourceMetrics, InstrumentationLibraryMetrics, Metrics).

**Additional optimization:** The splitting logic should be improved to reduce allocations and CPU time. Where possible, entire slices should be moved instead of copying individual metrics. For example, when all metrics of an `InstrumentationLibraryMetrics` fit within the remaining capacity of the current split, the entire metric slice should be moved (using `MoveAndAppendTo`) rather than copied metric-by-metric. This should also apply to higher-level containers when meaningful.

**Edge cases to handle correctly:**
- Multiple `ResourceMetrics` entries, each potentially containing multiple `InstrumentationLibraryMetrics`.
- A split size that is larger than the metric count within a single `InstrumentationLibraryMetrics` (so metrics from multiple instrumentation library entries or resource entries may fill one split).
- Empty `ResourceMetrics` and `InstrumentationLibraryMetrics` entries that become empty after all their metrics have been moved out should be removed from the original payload.

Fix batch processor metrics reorder, improve performance (#3034)


The golden dataset generators in `internal/goldendataset` silently lose data when building trace spans, events, links, and resource objects. This causes downstream tests that consume generated traces to receive incomplete telemetry data, and some path combinations produce panics or empty fields that defeat the purpose of the golden datasets.

Acceptance criteria:

1. **No silent data loss** — Every attribute, event, link, and status value configured for a generated span must actually appear in the output. If you request a span with `SpanAttrDatabaseSQL` attributes, the resulting `Span.Attributes()` map must contain exactly the expected database SQL attribute set with correct typed values.

2. **No panics from insert-on-duplicate-key** — Some attribute generators assign the same convention key more than once (e.g., `AttributeServiceName` appears twice in the Cloud VM resource generator). The code must not panic when this happens; later assignments should win.

3. **Status fields are correctly populated** — When the PICT status input is `Unset`, the generated span's status must remain at its code-and-message defaults (empty). When it is `Ok` or `Error`, the status code and message must match the expected mapping. Do not allocate and copy a separate status struct only to throw it away.

4. **Event, link, and child-span lists are built directly into the parent** — Currently some code paths create temporary intermediate slices or maps, conditionally return nil, then attempt to copy into the destination. This leaks data in the non-nil paths and obscures ownership. The generating functions must write directly into the provided destination containers so that no data is stranded in orphaned temporaries.

5. **Remove dead “Nil” enum variants** — The PICT input constants `ResourceNil`, `SpanAttrNil`, and `SpanChildCountNil` are not meaningful as separate test inputs. The “empty” case already covers the zero-attributes / zero-children scenario. Remove these variants from the PICT input definitions and from any generated pairwise input data files that reference them, updating the data files so they remain valid PICT input.

6. **Start-position tracking is eliminated** — The existing `GenerateSpans` function accepts a `startPos` and returns a `nextPos`, but callers always pass `0` and discard the returned position. This unused indirection should be removed; the function (or its replacement) should simply generate the requested number of spans without position bookkeeping. No caller behavior should change beyond losing unused return values.

**Safety constraint**: The existing public functions `GenerateResource`, `GenerateSpan`, `GenerateSpans`, and `GenerateTraces` are referenced by internal tests and by translator tests (`resource_to_oc_test.go`). Any signature changes or renames must be accompanied by updates to all call sites so the package compiles and existing tests continue to pass with identical or stricter assertions.

Fix usage of CopyTo/Append by passing the destination to the function calls (#3377)


**Request: Migrate Probabilistic Sampling Processor to the OTLP-based internal data model**

The Probabilistic Sampling Processor (`samplingprocessor/probabilisticsamplerprocessor`) currently operates on the deprecated OpenCensus-based internal representation. It converts incoming `pdata.Traces` to OpenCensus `TraceData` via `internaldata.TraceDataToOC`, processes spans in that form, and then converts the result back to `pdata.Traces` using `internaldata.OCToTraceData`. This conversion incurs unnecessary overhead and relies on deprecated translation functions that are being phased out across the collector codebase.

**Observed Problem**
- The processor is inconsistent with other processors that have already been migrated to work natively with the OTLP-backed `pdata` model (package `go.opentelemetry.io/collector/consumer/pdata`).
- It does not correctly handle the full OTLP structure: a single `pdata.Traces` can contain multiple resource spans, each containing multiple instrumentation library spans. The current conversion flattens this structure, which loses the original organization and may cause incorrect behavior when input traces have heterogenous resource contexts.
- The dependency on the deprecated `internaldata` package (specifically `TraceDataToOC` and `OCToTraceData`) needs to be removed so that those functions can eventually be retired.

**Expected Behavior**
1. **Input/Output**: The `ConsumeTraces` method should accept `pdata.Traces` directly and process it without converting to legacy types. The output should be a `pdata.Traces` object that preserves the resource and instrumentation-library hierarchy for the spans that survive sampling.
2. **Traversal**: For each incoming trace, the processor must iterate over resource spans, and within each resource span iterate over instrumentation library spans and their individual spans. The sampling decision is made per span (based on TraceID and the `sampling.priority` attribute), but the processor must accumulate sampled spans into an output `pdata.Traces` that reconstructs the corresponding resource and instrumentation-library groupings. If, after sampling, an instrumentation-library or resource container has no spans, it may be omitted.
3. **Attribute access**: The `parseSpanSamplingPriority` helper must be updated to use the `pdata.Span` API and attribute map methods (`Attributes().Get(...)`, `Type()`, `IntVal()`, `DoubleVal()`, `StringVal()`, etc.) instead of the OpenCensus protobuf types.
4. **No dependency on deprecated conversion**: Remove all imports of `internaldata` and the OpenCensus protobuf packages (`tracepb`, `consumerdata`). The processor should compile and pass all existing tests (which must be updated accordingly) without those references.
5. **Correct handling of multiple resource spans**: If an input trace contains multiple resource spans, the processor must not duplicate spans or mishandle the association between resources and spans. The output must contain only resource spans that contributed at least one sampled span.
6. **Backward compatibility**: The sampling algorithm (hash of TraceID, percentage scaling, handling of `sampling.priority` attribute values 0/positive/negative/non-numeric) must remain functionally identical; only the data-access layer changes.

**Impact**
This migration is necessary to modernize the probabilistic sampler, improve performance by eliminating serialization overhead, and unblock the removal of the deprecated OpenCensus translation functions. It also ensures consistent behavior with other processors that already operate on the native OTLP data model.

1305:Migrate Probabilistic Sampling Processor to the new OTLP-based i… (#1618)


# Implement a panic-recovery wrapper for decompressed request bodies

## Background

The HTTP decompression middleware in `config/confighttp` (used by the OTLP receiver and other components) delegates request-body decompression to registered decoder functions. Some decompression libraries (notably `zstd`) lazily initialise their state: the decoder's constructor succeeds, but a subsequent `Read` or `Close` on the returned `io.ReadCloser` can panic when the input is malformed. When that happens the entire HTTP handler goroutine panics, causing the server to either crash entirely or return an HTTP 500, neither of which is acceptable for a bad request from a client.

See the discussion in https://github.com/open-telemetry/opentelemetry-collector/issues/13228#issuecomment-3495221849 for more context.

## What we want

Any panic that originates from a decompression library during `Read` or `Close` of the decompressed request body must be recovered and converted into a normal `error`. The existing error-handling path should then treat it like any other decompression failure and return an HTTP 400 (Bad Request) to the caller, without crashing the server.

The protection must be generic – it should apply to *all* decoders, not just zstd, so that a custom decoder that panics is also safe.

## Acceptance criteria

- Sending a request with a valid `Content-Encoding` header but garbage payload (e.g. random bytes claiming to be zstd) returns HTTP 400, not 500, and the server remains healthy.
- A custom decoder that panics during `Read` or `Close` does not crash the server; the handler receives an error and the client sees an appropriate error response.
- Normal compression and uncompressed request handling is unaffected.

confighttp: recover from decompression panics during body Read (#15123)


```
[mdatagen] Eliminate field/method duplication between Metric and Event

Background:
In cmd/mdatagen/internal, the Metric and Event types currently each
define an identical set of fields (Enabled, Warnings, Description,
Stability, ExtendedDocumentation, Attributes) and both have the same
HasOptionalAttribute method. This duplication makes any future change to
these shared fields error-prone and tedious.

Goal:
Extract the shared fields and the HasOptionalAttribute method into a common
embedded struct (e.g., “Signal”) so that Metric and Event both embed it.
The public API of Metric and Event must not change – callers that access
Enabled, Warnings, etc. on a Metric or Event value should still compile
and work exactly as before, including the behaviour of HasOptionalAttribute.

Unmarshalling compatibility:
The metadata YAML files are parsed via mapstructure. To keep the existing
YAML format and parsing behaviour identical, use the mapstructure `,squash`
tag on the embedded field in both Metric and Event. No configuration or
generated code should require changes beyond the package itself.

Acceptance:
- No duplicated fields/method remain in Metric/Event.
- New embedded type holds Enabled, Warnings, Description, Stability,
  ExtendedDocumentation, Attributes, and HasOptionalAttribute.
- All tests in cmd/mdatagen pass (especially the loader tests).
- Confmap unmarshalling of Metric and Event produces the same values
  as before.
```

[chore] [mdatagen] Metric and Event structs to embed Signal struct (#13316)


```
obsreporttest: return all mismatched view errors, not just the first

The Check* functions (CheckReceiverTraces, CheckReceiverMetrics,
CheckReceiverLogs, CheckExporterTraces, CheckExporterMetrics,
CheckExporterLogs, CheckProcessorTraces, CheckProcessorMetrics,
CheckProcessorLogs, CheckScraperMetrics) currently abort on the first
view that doesn't match the expected value, hiding any subsequent
mismatches.  This makes debugging multi-view failures unnecessarily
tedious.

Change every such function so that *all* specified view checks are
always executed, and any errors from them are combined into a single
returned error.

Additionally:
• The exporter-check functions use misleading parameter names
  (acceptedSpans / droppedSpans etc.).  Rename the parameters to
  sentSpans / sendFailedSpans (and analogously for metrics and logs)
  so the names match the actual metric views (exporter/sent_spans,
  exporter/send_failed_spans, etc.).
• The internal helper that checks a view should include the view name
  in its error messages (e.g., “[exporter/sent_spans]: values did not
  match…”).  This is necessary because the combined error must
  unambiguously identify which checks failed.
```

obsreporttest: Improve tests, check for all possible errors always (#4395)


The testbed performance tests currently cover OTLP over gRPC but have no OTLP/HTTP coverage. Add support for OTLP/HTTP so the 10k-load tests for traces, metrics, and logs can exercise the HTTP transport path.

Implement testbed sender and receiver types for OTLP/HTTP (or extend the existing OTLP types to handle both transports). The OTLP/HTTP sender must use the `otlphttpexporter` exporter factory and configure it with an HTTP endpoint, insecure TLS, and with retries and queuing disabled (the testbed pushes data directly and handles errors). The corresponding receiver must configure the OTLP receiver for HTTP only, with an HTTP endpoint and gRPC disabled. The agent pipeline config generated by the sender/receiver pair must wire the `otlp` protocol with its `http` sub-protocol (i.e. `protocols: http:` in the receiver config) and use `otlphttp` as the exporter type.

Include the `otlphttp` exporter in the default component set so that it is available in the build used by the load tests.

Add `OTLP-HTTP` test entries to `TestTrace10kSPS`, `TestMetric10kDPS`, and `TestLog10kDPS` with resource expectations roughly comparable to the existing OTLP gRPC tests.

Add and enable loadtest for OTLP/HTTP (#1969)


```
Remove SetMapVal and SetArrayVal from AttributeValue

The AttributeValue type provides SetMapVal and SetArrayVal methods that allow replacing the entire map/array value in a setter style. Those methods are inconsistent with the rest of the generated pdata API, where non-immutable fields should only be mutated in-place through accessors like MapVal() and ArrayVal().

Remove SetMapVal and SetArrayVal from the public API. Update all callers to instead obtain the map/array via MapVal()/ArrayVal() and mutate it directly.

Additionally, ensure that deep-copy of AttributeValue (the internal copyTo path) no longer calls the removed setters. The deep-copy must:
- handle map values, including the case where the source has a nil KvlistValue
- handle array values, including the case where the source has a nil ArrayValue
- continue to correctly copy map/array contents when the destination already holds a value of a different type (type-switch to the target wrapper)

No change to the behavior of NewAttributeValueMap / NewAttributeValueArray — they must still return a value that can be populated by the caller.
```

Remove support to set map and array to attribute value (#2039)


```
Issue: Round-trip fidelity for zero/unknown timestamps in Jaeger trace conversion

When a Jaeger span is received with no start time (zero/unset), converting it to the internal representation and then back to Jaeger should produce the same span. Currently, that round-trip modifies the timestamp: the originally-unset start time becomes a non-zero value, breaking the invariant that ProtoBatchesToInternalTraces(InternalTracesToJaegerProto(traces)) equals traces.

The existing timestamp utilities in consumer/pdata handle conversion from TimestampUnixNano to time.Time, treating zero as Go's zero time (time.Time{}). However, the reverse conversion — from time.Time back to TimestampUnixNano — has no matching treatment, so a zero time.Time becomes a large non-zero timestamp (the actual Unix epoch equivalent of Go's year-1 representation).

We need the Jaeger-to-internal translator to correctly preserve zero/unset timestamps, as well as any other caller that may perform the reverse conversion.

Acceptance criteria:
- A Jaeger span with zero/unset start time round-trips through the internal representation without change.
- End time is handled consistently.
- The timestamp utilities provide a symmetric reverse conversion that maps a zero time.Time back to TimestampUnixNano(0), and the Jaeger-to-internal translator uses it for span start and end times.
- The existing zero-timestamp tests are extended to cover the reverse direction.
```

Fix trace jaeger conversion to internal traces zero time bug (#1957)


**Summary**: The OTLP HTTP receiver returns error responses whose `rpc.Status` body should contain a gRPC code that more accurately reflects the HTTP status code, and the HTTP status code itself should be derived from any gRPC status error that was propagated. The mapping between HTTP status codes and gRPC codes should be centralized in the `internal/errors` package to reduce duplication and improve maintainability.

**Detailed behavior (acceptance criteria)**:

1. **Accurate gRPC code from HTTP status code**
   When the OTLP HTTP receiver is about to return an error response and the error does **not** already carry a gRPC status (plain error or string message), the `code` field in the `google.rpc.Status` response body must be determined from the HTTP status code using the standard gRPC HTTP mapping:
   - `400` → `INVALID_ARGUMENT`
   - `401` → `UNAUTHENTICATED`
   - `403` → `PERMISSION_DENIED`
   - `404` → `UNIMPLEMENTED`
   - `429` → `RESOURCE_EXHAUSTED`
   - `502`, `503`, `504` → `UNAVAILABLE`
   - Any other HTTP status → `UNKNOWN`

   This mapping must be implemented in a single place inside the `internal/errors` package and reused by all error paths (both for “no request body” / “malformed request” and for errors that bubble up from the pipeline).

2. **HTTP status code derived from a gRPC status error**
   When the error being reported *is* a gRPC status error (e.g., an exporter returned `status.Error`) the HTTP response code must be selected based on the gRPC code, consistent with the existing retryable/non‑retryable semantics:
   - `UNAVAILABLE` → `503`
   - `RESOURCE_EXHAUSTED` → `429`
   - Any other gRPC code → `500` (or another appropriate non‑retryable code)

   The `rpc.Status` body must contain the **original** gRPC status (code + message) – do not re‑wrap it.

3. **Simplify the `GetHTTPStatusCodeFromStatus` helper**
   The existing `GetHTTPStatusCodeFromStatus` function in `internal/errors` currently accepts an `error` and performs a `status.FromError` extraction. Change it to accept a `*status.Status` directly. After the change:
   - Callers that already hold a `*status.Status` (e.g., after a `status.FromError` check) can pass it directly without a redundant extraction.
   - The function must only contain the mapping from gRPC code to HTTP status code (retryable → specific status, others → 500).

4. **Remove ad‑hoc mapping helpers**
   Any private function that does a partial or one‑off mapping from HTTP status to gRPC code (for example, only mapping 400 to `INVALID_ARGUMENT` and everything else to `UNKNOWN`) must be removed. All callers must use the centralized mapping from point **1**.

5. **No effect on the wire format outside the target fields**
   The HTTP response status code and the `rpc.Status` body remain the only changed observables; other aspects of the response (headers, content‑type negotiation, fallback message) must stay unchanged.

[receiver/otlp] Refactor http error handling (#9893)


```
confighttp: Apply MaxRequestBodySize to decompressed request bodies

Currently, when the HTTP server receives a request with a compressed body (e.g., Content-Encoding: gzip, zstd, …), the configured MaxRequestBodySize is only enforced against the compressed wire bytes. A tiny compressed payload can decompress into an arbitrarily large body, bypassing the limit and risking memory exhaustion.

Make the server also enforce MaxRequestBodySize on the decompressed body stream. When no MaxRequestBodySize is explicitly set, use a reasonable default maximum (20 MiB) for the decompressed body to prevent unbounded decompression.
```

[confighttp] Apply MaxRequestBodySize to the result of a decompressed body (#10289)


As a maintainer, I want to significantly speed up the Clone operations for telemetry data types (Logs, Metrics, Traces) and fix a nil-pointer panic in `AttributeValue.CopyTo`. Currently the Clone methods use `proto.Clone` under the hood, which is slow and also forces unnecessary round-trips through the internal protobuf representation. The generated slice and element `CopyTo` helpers already handle deep copying efficiently, and they should be used directly instead.

Additionally, when `AttributeValue.CopyTo` is asked to copy a nil source value, it crashes with a nil-pointer dereference. Instead it should safely transfer the nil state to the destination without panicking.

**Desired behavior:**
- `Logs.Clone()`, `Metrics.Clone()`, and `Traces.Clone()` should produce a deep copy at least 5× faster than the current implementation, by leveraging the existing `CopyTo` methods on the resource logs/metrics/spans slices.
- The Clone methods must continue to produce a fully independent copy that does not share any mutable sub-structures with the original.
- `AttributeValue.CopyTo(dest)` must not panic when the source (the receiver) is nil; it should set the destination to nil in that case.

**Non‑obvious constraints:**
- The new Clone implementation must not regress correctness for deeply nested data – the whole tree of resource, instrumentation library, spans/metrics/logs, attributes, etc. must be copied.
- The `CopyTo` helpers already exist on all slice and element types (`ResourceLogsSlice`, `ResourceMetricsSlice`, `ResourceSpansSlice`, and down through the nested structures). The fix should rely on those existing utilities rather than introducing new copying logic.
- The nil‑handling addition in `AttributeValue.CopyTo` should be a minimal guard that ensures the destination's `orig` pointer is set to nil when the source is nil, and should not break the normal copying path.

**Location hints:**
All involved types and their Clone/CopyTo methods live in `consumer/pdata/`. The slice and element types (including the `CopyTo` methods) are generated and reside in `consumer/pdata/generated_*.go`. The existing Clone methods use `github.com/gogo/protobuf/proto`; this dependency should be removed from the clone paths as part of the change.

Improve Clone performance by 5-7x (#1998)


Add `FromOtlpProtoBytes` to all pdata signals, remove deprecated helper, and clean up serialization paths

The `consumer/pdata` package provides `Traces`, `Metrics`, and `Logs` types for OTLP data. The `Traces` type exposes a `FromOtlpProtoBytes` method that parses OTLP collector `ExportTraceServiceRequest` protobuf bytes and replaces the internal state. The equivalent method is missing from `Metrics` and `Logs`, so callers cannot round-trip or deserialize those signal types in a consistent way.

1. Add `FromOtlpProtoBytes` to `Metrics` and `Logs`. The method should receive the OTLP collector `Export*ServiceRequest` bytes, unmarshal them, and set the internal resource span/metric/log slice. Return an `error` when unmarshalling fails. Follow the same panic-on-nil convention that `Traces` already documents: calling the method on a zero-value struct (not initialized via `NewMetrics` / `NewLogs`) will panic.

2. Remove the deprecated function `DeprecatedNewMetricsResourceSlice` from the `Metrics` type's file. It has no callers and was marked for removal.

3. Several `ToOtlpProtoBytes` and `FromOtlpProtoBytes` implementations use global `proto.Marshal` / `proto.Unmarshal` calls where the generated protobuf structs already provide `Marshal()` and `Unmarshal()` receivers. Update these methods to call the struct’s own methods, avoiding unnecessary pointer indirection and reducing allocations.

4. In `Logs.Clone`, the slice and loop variable are named `resourceSpansClones` (a copy-paste from the traces implementation). Rename them to `resourceLogsClones` to match the containing type.


**Title:** `ToDialOptions` and `ToServerOption` should accept `component.Host`, not a raw extensions map

**Description:**
The gRPC dial‑option and server‑option builders in `configgrpc` (`GRPCClientSettings.ToDialOptions` and `GRPCServerSettings.ToServerOption`) currently require callers to pass a `map[config.ComponentID]component.Extension`. This forces every consumer (e.g. the OTLP exporter and OTLP receiver) to extract the extensions map from the host by calling `host.GetExtensions()` before invoking these methods.

This pattern is inconsistent with the rest of the collector, where lifecycle hooks and helpers normally receive the whole `component.Host` and let the implementation access the extensions it needs. It also spreads the responsibility for nil‑checking the extensions map across multiple unrelated call sites, making the code harder to evolve.

**Expected behaviour:**
Both methods should accept a `component.Host` parameter instead of the raw extensions map. Internally they should call `host.GetExtensions()` themselves, and they must handle the case where that call returns `nil` (no extensions configured) exactly as the current `ext == nil` guard does.

**Impact:**
Removes unnecessary bookkeeping from every consumer, aligns the API with the rest of the codebase, and centralises the nil‑extension handling inside the config‑grpc layer. Existing callers like the OTLP exporter’s `newGrpcSender` and the OTLP receiver’s `startProtocolServers` should simply pass the host through without manually extracting the map.

use component.Host rather than map of extensions in ToServer (#4033)


### Bug Report: Missing OTLP compatibility conversion for deprecated IntSum metric type

**Summary**
When the OpenTelemetry Collector receives OTLP metrics using the deprecated `IntSum` field, it is not normalized to the newer `Sum` representation. This inconsistency can cause downstream metric processors and exporters that expect the `Sum` type to silently drop or mishandle the data.

**Background**
The OTLP protocol deprecated the int-only metric variants (`IntSum`, `IntGauge`, `IntHistogram`) in favor of unified types (`Sum`, `Gauge`, `Histogram`) that use `NumberDataPoint` to hold either an integer or a floating-point value. The collector’s compatibility layer (`MetricsCompatibilityChanges`) already translates `IntGauge` → `Gauge` and `IntHistogram` → `Histogram`, but the equivalent translation for `IntSum` → `Sum` was never implemented (the code contains a `TODO` comment indicating it was planned but missing).

**Observed problem**
Metrics that arrive with the `IntSum` variant remain as `IntSum` after passing through the collector. Components that only handle the newer `Sum` type (e.g., exporters that rely on `NumberDataPoint`) will not see these metrics, leading to data loss or failure to export. This can happen when an older OTLP client or SDK still emits `IntSum`.

**Expected behavior**
The compatibility layer should convert deprecated `IntSum` metrics to `Sum`, in the same way it already converts the other deprecated integer types. Each `IntDataPoint` inside `IntSum` must be mapped to a `NumberDataPoint` with the integer value placed in the `AsInt` field, and any `IntExemplar` instances should be converted to `Exemplar` instances using the existing helper strategy. The conversion should be a no-op for metrics that already use the `Sum` variant.

**Impact**
Without this fix, interop between newer Collectors and older OTLP clients (or in mixed-version deployments) is broken for sum-type metrics. Implementing the missing conversion closes a gap that was already addressed for gauge and histogram data.

translate IntSum to Sum in otlp_wrappers (#3621)


We need to update the codebase to match the new pdata model for metrics, where separate int/double-specific types (IntGauge, IntSum, etc.) have been replaced by unified Gauge and Sum types that carry a `MetricValueType` (int or double) on their data points. The following components need to be adapted while preserving their existing behavior:

1. **goldendataset metric generation**:
   - The `MetricsCfg` struct must allow specifying the value type for gauge and sum metrics (int or double) independently of the metric kind.
   - `DefaultCfg` should now produce a `MetricDataTypeGauge` metric with `MetricValueTypeInt`.
   - The generator function `populateMetrics` must use the unified `MetricDataTypeGauge` and `MetricDataTypeSum` types (not the old int/double variants) and delegate to a single function that populates `NumberDataPointSlice` with the appropriate int or double value based on the configuration's value type.
   - The PICT-to-config mapping (`pictToCfg`) must translate the old metric type constants (e.g., `MetricTypeIntGauge`, `MetricTypeDoubleGauge`, etc.) to the new unified types with the correct `MetricValueType` and `MetricDataType`.

2. **filterexpr matcher**:
   - `MatchMetric` must handle only `MetricDataTypeGauge`, `MetricDataTypeSum`, and `MetricDataTypeHistogram` (removing the old int-specific cases).
   - The matching logic for gauges and sums should work entirely with `Gauge.DataPoints()` and `Sum.DataPoints()` (both returning `NumberDataPointSlice`), without any separate int-gauge or int-sum handling.

3. **metric diffing in the correctness testbed**:
   - `DiffMetric` should diff gauges and sums using `NumberDataPointSlice` and compare both the `MetricValueType` and the corresponding int or double value.
   - The code must handle exemplars similarly: compare value types and the correct numeric accessor.
   - Remove any diff helpers that worked with old `IntDataPointSlice` or assumed double-only data points.

4. **tests across the repository**:
   - All tests in `internal/processor/filterexpr`, `processor/filterprocessor`, `testbed/correctness/metrics`, and `testbed/tests` that construct or examine metrics should use the new unified types and set/check the `MetricValueType` and the correct numeric accessor (`IntVal` or `DoubleVal`) instead of the old type-specific methods like `IntGauge`, `IntSum`, `DoubleVal`, or `Value()`.
   - The tests must still cover both int and double variants for gauges and sums, validating that filtering, matching, and diffing work correctly for each.

This is a behavioral refactoring: the outputs of the affected components should remain the same from the caller’s perspective, only the internal representation of the metric data changes. No new functionality is added beyond the ability to configure and differentiate int vs double in the unified model.

Convert testbed to new Number metrics (#3719)


**Request:** Update `servicetest` load helpers to use the collector’s own config type instead of the deprecated `config.Config`, and ensure configuration validation does not happen inside the config provider.

**Background:**
The `servicetest` package provides `LoadConfig` and `LoadConfigAndValidate` helpers that currently return the deprecated `*config.Config` type. Internally these helpers bypass the collector’s config loading stack and use a standalone unmarshaler. This makes them brittle and misaligned with how the collector processes configuration.

**What needs to change (observable behavior & acceptance criteria):**

1. **`servicetest.LoadConfig` and `servicetest.LoadConfigAndValidate`**
   - Must **no longer return `*config.Config`**; they should return the same config type that the collector’s config provider returns (the concrete type used internally, currently `*service.Config`).
   - Must **load configuration using the full service config provider**, including the same set of providers and converters the collector uses (e.g. file, environment variable, yaml, http providers and the expand converter). This ensures the helpers behave identically to a real collector loading a file.
   - `LoadConfig` must **not validate** the configuration after loading.
   - `LoadConfigAndValidate` must **explicitly validate** the configuration after loading, and return any validation error.

2. **Config provider’s `Get` method**
   - `Get` must **stop performing configuration validation**. It should successfully return the unmarshaled configuration even if that configuration is invalid.
   - Any callers (including `servicetest` helpers) should be able to retrieve an invalid configuration without error.

3. **Collector startup**
   - The collector must **still reject invalid configuration** when starting up. Specifically, calling `Run` (or the internal component setup triggered by `Run`) must result in an error when the configuration fails `Validate()`. This preserves the existing user-facing behavior: a misconfigured collector refuses to start.

Avoid using deprecated config.Config in servicetest (#6393)


Title: Component attributes silently dropped when logger already has custom fields via `Logger.With`

## Description

When a Zap logger that has been processed by `componentattribute.ZapLoggerWithAttributes` subsequently has custom fields added via `Logger.With`, any later attempt to update the component attributes (again through `ZapLoggerWithAttributes` or the underlying `WithAttributeSet`) fails silently. The component attributes are not present in the logged output.

**Observed behavior**
- The logged record includes the custom fields from `Logger.With` but lacks the component attributes entirely, even though the attribute set was provided.

**Expected behavior**
- Both the previously added custom fields and the newly supplied component attributes appear in the log output.
- The ordering should be consistent: fields that were present when the original core was created (e.g., “preexisting”), followed by the component attributes, followed by any user-added `With` fields.

## Steps to reproduce
1. Create a Zap core that already has some initial fields (the core’s own `With` output).
2. Build a logger from that core.
3. Add a custom field using `logger.With(zap.String("postexisting", "value"))`.
4. Call `componentattribute.ZapLoggerWithAttributes` on the logger to set component attributes.
5. Log a message and inspect the resulting log record.

**Actual result**: The component attributes are missing; only the initial core fields and the custom `With` field are present.

**Expected result**: All three sets of fields appear: initial core fields, then component attributes, then the custom `With` field.

## Context

The `componentattribute` package wraps a Zap core to inject component attributes. When `Logger.With` is called on a logger whose core has been wrapped, the wrapper is discarded because it does not override `Core.With`. This means subsequent attribute updates or even the initial attribute injection no longer acts on the wrapped core, and attributes are silently lost.

Currently no internal components trigger this exact sequence (none call `Logger.With` before using the attribute setter), so the bug is latent. However, it represents a correctness gap in the API that should be addressed.

Fix Logger.With followed by componentattribute.WithAttributeSet (#13610)


Remove the redundant `persistentQueue` wrapper struct in `exporter/exporterhelper/internal`. This type only embeds `persistentContiguousStorage` and adds a few extra fields; it should be eliminated by folding those fields into `persistentContiguousStorage` itself and letting the storage directly implement the `Queue` interface.

Key requirements:
- Move the fields `set`, `storageID`, and `dataType` from the wrapper into `persistentContiguousStorage`.
- Replace the standalone `logger` field in the storage struct with the logger obtained from `set.Logger` (the `exporter.CreateSettings` field).
- Remove the private `start` method (which took a client and called `initPersistentContiguousStorage`) and instead expose a `Start` method on `persistentContiguousStorage` that obtains the storage client from the host and calls a renamed `initClient` method (the body of the old `start`).
- Update `NewPersistentQueue` to construct and return `*persistentContiguousStorage` directly, initializing channels and capacity there.
- Adjust any test helper that used the old private constructor (`newPersistentContiguousStorage`) to construct the storage through the public `NewPersistentQueue` and call `initClient`, keeping the test behavior unchanged.
- The public API (the `Queue` interface and the signature of `NewPersistentQueue`) must remain the same. All existing tests should continue to pass.

[chore] [exporterhelper] Remove redundant persistentQueue struct (#8930)


```
Feature request: Context value propagation in exporter batching

When requests are batched by the exporter helper (exporterhelper), any context values
attached to individual request contexts are currently discarded because the batch
context is always built from context.Background(). This prevents passing important
metadata (e.g., authentication tokens, tenant IDs) through batching.

Please add an opt-in mechanism that allows users to supply a custom merge function
for combining context values when multiple requests are merged into a batch.
- The function should be of type `func(context.Context, context.Context) context.Context`.
- The function should be exposed as a field in the existing `Settings` struct used to
  configure the queue+batcher (`MergeCtx`). When the field is nil, the default
  behavior MUST remain the same as today: no context values from the original
  contexts are retained.
- The merged context returned by the user-supplied function (or `context.Background()`
  when the field is nil) must be used as the base context when storing the merged
  span links that are already maintained by the batching logic. Span link merging
  must continue to work exactly as before.
- The returned context from the merge function is not required to override the
  `Value()` method on the context passed to the downstream consumer.

The result should allow users to preserve needed context values across batching
without breaking existing batcher behavior.
```

[exporterhelper][queuebatcher] Context value propagation during batching - approach #2 (#13460)


Remove internal proto dependency from Kafka receiver's OTLP traces unmarshaller

The Kafka receiver's OTLP trace unmarshaller currently imports `internal/protogen` types (e.g., `otlptrace.ExportTraceServiceRequest`) to decode trace data. That internal dependency needs to be eliminated. Instead, the unmarshaller should use the public `pdata.Traces` byte-level helpers (`FromOtlpProtoBytes`) to unmarshal the raw bytes directly.

Rename the existing `otlpProtoUnmarshaller` type to a more specific name—for instance, `otlpTracesPbUnmarshaller`—so it is clear the unmarshaller handles only the traces protobuf encoding, not a generic OTLP proto.

Update all references to the type, including the default unmarshaller map, and adjust the tests to serialize test data via `pdata.Traces.ToOtlpProtoBytes` rather than manually constructing internal protobuf request objects. No user-facing configuration or behavior should change beyond the removal of internal package imports.

Change Kafka receiver to not use internal data (#2697)