Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CompositeMeterRegistry fails to propagate Meter removals to a MeterRegistry that has Filters #2354

Closed
ldesgoui opened this issue Nov 18, 2020 · 5 comments
Labels
bug A general bug
Milestone

Comments

@ldesgoui
Copy link

ldesgoui commented Nov 18, 2020

Hello,

Consider the simple set up:
Metrics.globalRegistry has no Filters applied
A DatadogMeterRegistry instance has a CommonTags Filter applied and is parented by Metrics.globalRegistry
When Meters are written to Metrics.globalRegistry, they are propagated to the DatadogMeterRegister instance and the Filters are applied
When Meters are removed from Metrics.globalRegistry, they are propagated to the DatadogMeterRegister instance but the Filters are not applied, causing the lookup to fail and them to not get properly deleted

This is caused by this event handler which calls this method, in which the filters are not applied.

This causes the equivalent of a memory leak and aggravates heavily with high-cardinality Meters (such as metrics from reactor executors while using "elastic" schedulers)

I don't have enough Java expertise to offer an accompanying fix and tests, apologies.

@ldesgoui ldesgoui changed the title CompositeMeterRegistry fails to propagate Meter removals to a MeterRegistry that has filters CompositeMeterRegistry fails to propagate Meter removals to a MeterRegistry that has Filters Nov 18, 2020
@shakuzen shakuzen added the bug A general bug label Nov 25, 2020
@shakuzen shakuzen added this to the 1.3.x milestone Nov 25, 2020
@shakuzen
Copy link
Member

Thanks for the detailed report. The behavior of the remove method has changed since it was introduced - it used to apply MeterFilters, now it doesn't. We've run into the issue of one behavior being desired in some cases in not others.

While I think we should be able to fix this regardless, can share more details about your use case for removing meters? This is just so we have a more complete picture of the background behind the use case.

@shakuzen
Copy link
Member

Here is a unit test that I believe captures the scenario (written in CompositeMeterRegistryTest):

@Test
@Issue("#2354")
void meterRemovedInChildRegistryWithModifyingFilter() {
    this.simple.config().commonTags("host", "localhost");
    this.composite.add(this.simple);

    Counter counter = this.composite.counter("my.counter");
    this.composite.remove(counter);

    assertThat(this.composite.getMeters()).isEmpty();
    assertThat(this.simple.getMeters()).isEmpty(); // this assertion fails
}

@ldesgoui
Copy link
Author

We use Spring which configures and manages its own CompositeMeterRegistry, and reactor which simply writes to micrometer's globalRegistry, globalRegistry is not modified by Spring (aside from adding children), we end up with plenty of Meters from reactor that don't get removed over time.
It seems that reactor recently added functionality to use a different registry than globalRegistry, which could solve our problem I suppose.
We ended up applying the CommonTags configurations to globalRegistry as a temporary workaround.

Test looks good to me.

@admoca60
Copy link

Please @shakuzen , take into consideration the PR https://github.com/micrometer-metrics/micrometer/pull/2281/files. This solves the problem.

@shakuzen shakuzen modified the milestones: 1.3.x, 1.3.16 Nov 27, 2020
shakuzen added a commit to shakuzen/micrometer that referenced this issue Dec 8, 2020
Child registries may have a `MeterFilter` configured that alter the Id of meters when registered. In this case, calling `remove` with the Id from the `CompositeMeterRegistry` will not match unless it also has the same `MeterFilter` configured. The behavior of the `remove` method has fluctuated as these cases come to light. This adds public API for removing a meter with its pre-mapped Id and clarifies the behavior in the JavaDoc of all `remove` methods. `CompositeMeterRegistry` can now use this new API to have the expected behavior.

Resolves micrometer-metricsgh-2354
@shakuzen
Copy link
Member

shakuzen commented Dec 8, 2020

The fix for this is available now in snapshots for 1.3.16, 1.5.8, and 1.6.2. I will be releasing these soon, so feel free to test the snapshots now or the release versions once available to confirm the issue reported here is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants