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

[PoC] Mitigation for InMemoryExporter + Metrics (for discussion) #2907

Closed
wants to merge 6 commits into from
Closed

[PoC] Mitigation for InMemoryExporter + Metrics (for discussion) #2907

wants to merge 6 commits into from

Conversation

TimothyMothra
Copy link
Contributor

This is an alternative to DeepCopying the Metric.
Discussing this in #2361.

Changes

  • DeepCopy MetricPoint. This includes minor changes to MetricPoint and HistogramBuckets.
  • Metric.GetMetricPoints changed to always return a deepcopy.
    This change passes all unit tests locally.
    Need to discuss if this change is acceptable.
  • InMemoryExporter to clear the exportedItems collection when exporting Metric.
    This mitigates the issue with growing the collection with copies of the same Metric.
    Need to discuss if this change is acceptable.

For significant contributions please make sure you have completed the following items:

Sorry, something went wrong.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
update
@@ -128,7 +128,10 @@ public sealed class Metric

public MetricPointsAccessor GetMetricPoints()
Copy link
Contributor

@utpilla utpilla Feb 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot update this method as this would be used by all other exporters for best performance.

We need to add a new method GetClonedMetricPoints which should call this.aggStore.GetClonedMetricPoints. The user of InMemoryExporter has to be aware of this method and call GetClonedMetricPoints instead of GetMetricPoints:

foreach (var metric in batch)
{
    foreach (ref readonly var metricPoint in metric.GetCloneMetricPoints())
    {
        ...
        ...
        ...
    }
}

@@ -28,7 +28,8 @@ public struct MetricPoint
{
private readonly AggregationType aggType;

private readonly HistogramBuckets histogramBuckets;
// Note: Removing "readonly" enables DeepCopy using the MemberwiseClone pattern below.
private HistogramBuckets histogramBuckets;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need to deep copy HistogramBuckets.SnapshotBucketCounts.

@codecov
Copy link

codecov bot commented Feb 18, 2022

Codecov Report

Merging #2907 (e9dee07) into main (84821ff) will decrease coverage by 0.33%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2907      +/-   ##
==========================================
- Coverage   84.22%   83.89%   -0.34%     
==========================================
  Files         251      253       +2     
  Lines        8883     8922      +39     
==========================================
+ Hits         7482     7485       +3     
- Misses       1401     1437      +36     
Impacted Files Coverage Δ
src/OpenTelemetry/Metrics/HistogramBuckets.cs 95.65% <0.00%> (-4.35%) ⬇️
...penTelemetry.Exporter.InMemory/InMemoryExporter.cs 100.00% <100.00%> (ø)
src/OpenTelemetry/Metrics/AggregatorStore.cs 83.24% <100.00%> (+0.38%) ⬆️
src/OpenTelemetry/Metrics/Metric.cs 94.52% <100.00%> (+0.07%) ⬆️
src/OpenTelemetry/Metrics/MetricPoint.cs 85.92% <100.00%> (+0.31%) ⬆️
...Telemetry/Metrics/PeriodicExportingMetricReader.cs 0.00% <0.00%> (-78.73%) ⬇️
...nTelemetryProtocol/OtlpMetricExporterExtensions.cs 64.28% <0.00%> (-35.72%) ⬇️
...OpenTelemetry/Metrics/BaseExportingMetricReader.cs 83.33% <0.00%> (-1.67%) ⬇️
...umentation.AspNet/Implementation/HttpInListener.cs 88.31% <0.00%> (-0.30%) ⬇️
...metryProtocol/OtlpTraceExporterHelperExtensions.cs 94.73% <0.00%> (-0.27%) ⬇️
... and 11 more

// Need to discuss if this is an acceptible change.
if (this.isMetric)
{
this.exportedItems.Clear();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's first decide on this. Do we want the collection of exported items to hold the MetricPoint state corresponding to every export made so far?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I feel like... no, it shouldn't auto-clear anything. Whoever constructed the InMemoryExporter owns the collection that was passed in. So they can clear it if needed based on whatever test is being modeled? But yes the exporter should move copies into that collection so the data doesn't continue to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @CodeBlanch,
If the InMemoryExporter could deepcopy the Metric into the export collection, I believe that would fully address this issue.
However, I don't see an obvious way to accomplish this.
I listed here several methods to perform a deepcopy and the blocking issues with each.
If you have any other ideas, I'm eager to get your input!

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.

None yet

3 participants