Skip to content

Switch the dictionaries of dictionary tables only once#14709

Merged
mx-psi merged 4 commits into
open-telemetry:mainfrom
dmathieu:pprofile-bugfix
Mar 10, 2026
Merged

Switch the dictionaries of dictionary tables only once#14709
mx-psi merged 4 commits into
open-telemetry:mainfrom
dmathieu:pprofile-bugfix

Conversation

@dmathieu

@dmathieu dmathieu commented Mar 5, 2026

Copy link
Copy Markdown
Member

Right now, when merging profiles, we switch dictionary entries when they are used.

For example, for each sample, we do:

  • Run switchDictionary for that sample.
  • Switch all the sample indices dictionaries.
  • Run switchDictionary for the stack associated with that sample.
  • Update the sample's stack ID with the one provided by the new dictionary.

This has a pretty big issue, as when stacks are associated to multiple samples (which is very common in production workloads, but was missed in tests), we will try switching the stack's dictionary multiple times.

  • Switch the stack's dictionary, works fine.
  • Switch it again. Now, we try assigning indices from the source dictionary when they have meaning in the destination one.

Instead, we now do the following:

  • Run switchDictionary for the stacks.
  • Loop through samples, and run switchDictionary for each of them.
  • Retrieve the stack. Because we already switched its dictionary, we get a stack already pointing at the new dictionary.
  • Update the sample's stack ID with the one provided by the new dictionary.

This investigation and PR were proudly done without the use of any LLM.

@codecov

codecov Bot commented Mar 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 60.00000% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.91%. Comparing base (92d7303) to head (8fc93e9).
⚠️ Report is 29 commits behind head on main.

Files with missing lines Patch % Lines
pdata/pprofile/profiles.go 60.00% 4 Missing and 4 partials ⚠️

❌ Your patch status has failed because the patch coverage (60.00%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #14709      +/-   ##
==========================================
- Coverage   91.94%   91.91%   -0.03%     
==========================================
  Files         685      688       +3     
  Lines       43244    43512     +268     
==========================================
+ Hits        39760    39995     +235     
- Misses       2413     2429      +16     
- Partials     1071     1088      +17     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pdata/pprofile/sample.go Outdated
Comment thread pdata/pprofile/profiles.go
@mx-psi
mx-psi added this pull request to the merge queue Mar 10, 2026
Merged via the queue into open-telemetry:main with commit ea50525 Mar 10, 2026
65 of 66 checks passed
TimoBehrendt pushed a commit to TimoBehrendt/tracebasedlogsampler that referenced this pull request Mar 26, 2026
…ocessortest to v0.148.0 (#40)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [go.opentelemetry.io/collector/processor/processortest](https://github.com/open-telemetry/opentelemetry-collector) | `v0.147.0` → `v0.148.0` | ![age](https://developer.mend.io/api/mc/badges/age/go/go.opentelemetry.io%2fcollector%2fprocessor%2fprocessortest/v0.148.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/go.opentelemetry.io%2fcollector%2fprocessor%2fprocessortest/v0.147.0/v0.148.0?slim=true) |

---

### Release Notes

<details>
<summary>open-telemetry/opentelemetry-collector (go.opentelemetry.io/collector/processor/processortest)</summary>

### [`v0.148.0`](https://github.com/open-telemetry/opentelemetry-collector/blob/HEAD/CHANGELOG.md#v1540v01480)

[Compare Source](open-telemetry/opentelemetry-collector@v0.147.0...v0.148.0)

##### ❗ Known Issues ❗

- `service`: The collector's internal Prometheus metrics endpoint (`:8888`) now emits OTel service labels with underscore
  names (`service_name`, `service_instance_id`, `service_version`) instead of dot-notation names (`service.name`,
  `service.instance.id`, `service.version`). Users scraping this endpoint with the Prometheus receiver will see these renamed
  labels in resource and datapoint attributes. As a workaround, add the following `metric_relabel_configs` to your scrape
  config in prometheus receiver:
  ```yaml
  metric_relabel_configs:
    - source_labels: [service_name]
      target_label: service.name
    - source_labels: [service_instance_id]
      target_label: service.instance.id
    - source_labels: [service_version]
      target_label: service.version
    - regex: service_name|service_instance_id|service_version
      action: labeldrop
  ```
  See [#&#8203;14814](open-telemetry/opentelemetry-collector#14814) for details and updates.

##### 🛑 Breaking changes 🛑

- `all`: Change metric units to be singular to match OTel specification, e.g. `{requests}` -> `{request}` ([#&#8203;14753](open-telemetry/opentelemetry-collector#14753))

##### 💡 Enhancements 💡

- `cmd/mdatagen`: Add deprecated\_type field to allow specifying an alias for component types. ([#&#8203;14718](open-telemetry/opentelemetry-collector#14718))
- `cmd/mdatagen`: Generate entity-scoped MetricsBuilder API that enforces entity-metric associations at compile time ([#&#8203;14659](open-telemetry/opentelemetry-collector#14659))
- `cmd/mdatagen`: Skip generating reaggregation config options for metrics that have no aggregatable attributes. ([#&#8203;14689](open-telemetry/opentelemetry-collector#14689))
- `pkg/service`: The internal status reporter no longer drops repeated Ok and RecoverableError statuses ([#&#8203;14282](open-telemetry/opentelemetry-collector#14282))
  Status events can now carry metadata and there's value in allowing them to be emitted despite the status value itself
  not changing.

##### 🧰 Bug fixes 🧰

- `cmd/builder`: Add `.exe` to output binary names when building for Windows targets. ([#&#8203;12591](open-telemetry/opentelemetry-collector#12591))

- `exporter/debug`: Add printing of metric metadata in detailed verbosity. ([#&#8203;14667](open-telemetry/opentelemetry-collector#14667))

- `exporter/otlp_grpc`: Prevent nil pointer panic when push methods are called before the OTLP exporter initializes its gRPC clients. ([#&#8203;14663](open-telemetry/opentelemetry-collector#14663))
  When the sending queue and retry are disabled, calling ConsumeTraces,
  ConsumeMetrics, ConsumeLogs, or ConsumeProfiles before the OTLP exporter
  initializes its gRPC clients could cause a nil pointer dereference panic.
  The push methods now return an error instead of panicking.

- `exporter/otlp_http`: Show the actual destination URL in error messages when request URL is modified by middleware. ([#&#8203;14673](open-telemetry/opentelemetry-collector#14673))
  Unwraps the `*url.Error` returned by `http.Client.Do()` to prevent misleading error logs when a middleware extension dynamically updates the endpoint.

- `pdata/pprofile`: Switch the dictionary of dictionary tables entries only once when merging profiles ([#&#8203;14709](open-telemetry/opentelemetry-collector#14709))
  For dictionary table data, we used to switch their dictionaries when doing
  the switch for the data that uses them.
  However, when an entry is associated with multiple other data (several
  samples can use the same stack), we would have been switching the
  dictionaries of the entry multiple times.

  We now switch dictionaries for dictionary table data only once, before
  switching the resource profiles.

<!-- previous-version -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://gitea.t000-n.de/t.behrendt/tracebasedlogsampler/pulls/40
Reviewed-by: t.behrendt <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
Co-committed-by: Renovate Bot <[email protected]>
TimoBehrendt pushed a commit to TimoBehrendt/tracebasedlogsampler that referenced this pull request Mar 26, 2026
…1.54.0 (#33)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [go.opentelemetry.io/collector/confmap](https://github.com/open-telemetry/opentelemetry-collector) | `v1.50.0` → `v1.54.0` | ![age](https://developer.mend.io/api/mc/badges/age/go/go.opentelemetry.io%2fcollector%2fconfmap/v1.54.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/go.opentelemetry.io%2fcollector%2fconfmap/v1.50.0/v1.54.0?slim=true) |

---

### Release Notes

<details>
<summary>open-telemetry/opentelemetry-collector (go.opentelemetry.io/collector/confmap)</summary>

### [`v1.54.0`](https://github.com/open-telemetry/opentelemetry-collector/blob/HEAD/CHANGELOG.md#v1540v01480)

##### ❗ Known Issues ❗

- `service`: The collector's internal Prometheus metrics endpoint (`:8888`) now emits OTel service labels with underscore
  names (`service_name`, `service_instance_id`, `service_version`) instead of dot-notation names (`service.name`,
  `service.instance.id`, `service.version`). Users scraping this endpoint with the Prometheus receiver will see these renamed
  labels in resource and datapoint attributes. As a workaround, add the following `metric_relabel_configs` to your scrape
  config in prometheus receiver:
  ```yaml
  metric_relabel_configs:
    - source_labels: [service_name]
      target_label: service.name
    - source_labels: [service_instance_id]
      target_label: service.instance.id
    - source_labels: [service_version]
      target_label: service.version
    - regex: service_name|service_instance_id|service_version
      action: labeldrop
  ```
  See [#&#8203;14814](open-telemetry/opentelemetry-collector#14814) for details and updates.

##### 🛑 Breaking changes 🛑

- `all`: Change metric units to be singular to match OTel specification, e.g. `{requests}` -> `{request}` ([#&#8203;14753](open-telemetry/opentelemetry-collector#14753))

##### 💡 Enhancements 💡

- `cmd/mdatagen`: Add deprecated\_type field to allow specifying an alias for component types. ([#&#8203;14718](open-telemetry/opentelemetry-collector#14718))
- `cmd/mdatagen`: Generate entity-scoped MetricsBuilder API that enforces entity-metric associations at compile time ([#&#8203;14659](open-telemetry/opentelemetry-collector#14659))
- `cmd/mdatagen`: Skip generating reaggregation config options for metrics that have no aggregatable attributes. ([#&#8203;14689](open-telemetry/opentelemetry-collector#14689))
- `pkg/service`: The internal status reporter no longer drops repeated Ok and RecoverableError statuses ([#&#8203;14282](open-telemetry/opentelemetry-collector#14282))
  Status events can now carry metadata and there's value in allowing them to be emitted despite the status value itself
  not changing.

##### 🧰 Bug fixes 🧰

- `cmd/builder`: Add `.exe` to output binary names when building for Windows targets. ([#&#8203;12591](open-telemetry/opentelemetry-collector#12591))

- `exporter/debug`: Add printing of metric metadata in detailed verbosity. ([#&#8203;14667](open-telemetry/opentelemetry-collector#14667))

- `exporter/otlp_grpc`: Prevent nil pointer panic when push methods are called before the OTLP exporter initializes its gRPC clients. ([#&#8203;14663](open-telemetry/opentelemetry-collector#14663))
  When the sending queue and retry are disabled, calling ConsumeTraces,
  ConsumeMetrics, ConsumeLogs, or ConsumeProfiles before the OTLP exporter
  initializes its gRPC clients could cause a nil pointer dereference panic.
  The push methods now return an error instead of panicking.

- `exporter/otlp_http`: Show the actual destination URL in error messages when request URL is modified by middleware. ([#&#8203;14673](open-telemetry/opentelemetry-collector#14673))
  Unwraps the `*url.Error` returned by `http.Client.Do()` to prevent misleading error logs when a middleware extension dynamically updates the endpoint.

- `pdata/pprofile`: Switch the dictionary of dictionary tables entries only once when merging profiles ([#&#8203;14709](open-telemetry/opentelemetry-collector#14709))
  For dictionary table data, we used to switch their dictionaries when doing
  the switch for the data that uses them.
  However, when an entry is associated with multiple other data (several
  samples can use the same stack), we would have been switching the
  dictionaries of the entry multiple times.

  We now switch dictionaries for dictionary table data only once, before
  switching the resource profiles.

<!-- previous-version -->

### [`v1.53.0`](https://github.com/open-telemetry/opentelemetry-collector/blob/HEAD/CHANGELOG.md#v1530v01470)

##### 💡 Enhancements 💡

- `exporter/debug`: Output bucket counts for exponential histogram data points in normal verbosity. ([#&#8203;10463](open-telemetry/opentelemetry-collector#10463))
- `pkg/exporterhelper`: Add `metadata_keys` configuration to `sending_queue.batch.partition` to partition batches by client metadata ([#&#8203;14139](open-telemetry/opentelemetry-collector#14139))
  The `metadata_keys` configuration option is now available in the `sending_queue.batch.partition` section for all exporters.
  When specified, batches are partitioned based on the values of the listed metadata keys, allowing separate batching per metadata partition. This feature
  is automatically configured when using `exporterhelper.WithQueue()`.

##### 🧰 Bug fixes 🧰

- `cmd/builder`: Fix duplicate error output when CLI command execution fails in the builder tool. ([#&#8203;14436](open-telemetry/opentelemetry-collector#14436))

- `cmd/mdatagen`: Fix duplicate error output when CLI command execution fails in the mdatagen tool. ([#&#8203;14436](open-telemetry/opentelemetry-collector#14436))

- `cmd/mdatagen`: Fix semconv URL validation for metrics with underscores in their names ([#&#8203;14583](open-telemetry/opentelemetry-collector#14583))
  Metrics like `system.disk.io_time` now correctly validate against semantic convention URLs containing underscores in the anchor tag.

- `extension/memory_limiter`: Use ChainUnaryInterceptor instead of UnaryInterceptor to allow multiple interceptors. ([#&#8203;14634](open-telemetry/opentelemetry-collector#14634))
  If multiple extensions that use the UnaryInterceptor are set the binary panics at start time.

- `extension/memory_limiter`: Add support for streaming services. ([#&#8203;14634](open-telemetry/opentelemetry-collector#14634))

- `pkg/config/configmiddleware`: Add context.Context to HTTP middleware interface constructors. ([#&#8203;14523](open-telemetry/opentelemetry-collector#14523))
  This is a breaking API change for components that implement or use extensionmiddleware.

- `pkg/confmap`: Fix another issue where configs could fail to decode when using interpolated values in string fields. ([#&#8203;14034](open-telemetry/opentelemetry-collector#14034))
  For example, a resource attribute can be set via an environment variable to a string that is parseable as a number, e.g. `1234`.

  (A similar bug was fixed in a previous release: that one was triggered when the field was nested in a struct,
  whereas this one is triggered when the field internally has type "pointer to string" rather than "string".)

- `pkg/otelcol`: The featuregate subcommand now rejects extra positional arguments instead of silently ignoring them. ([#&#8203;14554](open-telemetry/opentelemetry-collector#14554))

- `pkg/queuebatch`: Fix data race in partition\_batcher where resetTimer() was called outside mutex, causing concurrent timer.Reset() calls and unpredictable batch flush timing under load. ([#&#8203;14491](open-telemetry/opentelemetry-collector#14491))

- `pkg/scraperhelper`: Log scrapers now emit log-appropriate receiver telemetry ([#&#8203;14654](open-telemetry/opentelemetry-collector#14654))
  Log scrapers previously emitted the same receiver telemetry as metric scrapers,
  such as the otelcol\_receiver\_accepted\_metric\_points metric (instead of otelcol\_receiver\_accepted\_log\_records),
  or spans named receiver/myreceiver/MetricsReceived (instead of receiver/myreceiver/LogsReceived).

  This did not affect scraper-specific spans and metrics.

- `processor/batch`: Fixes a bug where the batch processor would not copy `SchemaUrl` metadata from resource and scope containers during partial batch splits. ([#&#8203;12279](open-telemetry/opentelemetry-collector#12279), [#&#8203;14620](open-telemetry/opentelemetry-collector#14620))

<!-- previous-version -->

### [`v1.52.0`](https://github.com/open-telemetry/opentelemetry-collector/blob/HEAD/CHANGELOG.md#v1520v01461)

<!-- previous-version -->

### [`v1.51.0`](https://github.com/open-telemetry/opentelemetry-collector/blob/HEAD/CHANGELOG.md#v1510v01450)

##### 💡 Enhancements 💡

- `pkg/scraperhelper`: ScraperID has been added to the logs for metrics, logs, and profiles ([#&#8203;14461](open-telemetry/opentelemetry-collector#14461))

##### 🧰 Bug fixes 🧰

- `exporter/otlp_grpc`: Fix the OTLP exporter balancer to use round\_robin by default, as intended. ([#&#8203;14090](open-telemetry/opentelemetry-collector#14090))

- `pkg/config/configoptional`: Fix `Unmarshal` methods not being called when config is wrapped inside `Optional` ([#&#8203;14500](open-telemetry/opentelemetry-collector#14500))
  This bug notably manifested in the fact that the `sending_queue::batch::sizer` config for exporters
  stopped defaulting to `sending_queue::sizer`, which sometimes caused the wrong units to be used
  when configuring `sending_queue::batch::min_size` and `max_size`.

  As part of the fix, `xconfmap` exposes a new `xconfmap.WithForceUnmarshaler` option, to be used in the `Unmarshal` methods
  of wrapper types like `configoptional.Optional` to make sure the `Unmarshal` method of the inner type is called.

  The default behavior remains that calling `conf.Unmarshal` on the `confmap.Conf` passed as argument to an `Unmarshal`
  method will skip any top-level `Unmarshal` methods to avoid infinite recursion in standard use cases.

- `pkg/confmap`: Fix an issue where configs could fail to decode when using interpolated values in string fields. ([#&#8203;14413](open-telemetry/opentelemetry-collector#14413))
  For example, a header can be set via an environment variable to a string that is parseable as a number, e.g. `1234`

- `pkg/service`: Don't error on startup when process metrics are enabled on unsupported OSes (e.g. AIX) ([#&#8203;14307](open-telemetry/opentelemetry-collector#14307))

<!-- previous-version -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41LjQiLCJ1cGRhdGVkSW5WZXIiOiI0My41LjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

Reviewed-on: https://gitea.t000-n.de/t.behrendt/tracebasedlogsampler/pulls/33
Reviewed-by: t.behrendt <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
Co-committed-by: Renovate Bot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants