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

Exponential Histogram : observed bucket counts sometimes not matching with overall count #4450

Closed
kothariroshni8 opened this issue Jan 30, 2024 · 17 comments · Fixed by #4459
Closed
Labels
bug Something isn't working priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect

Comments

@kothariroshni8
Copy link

What happened?

When using Exponential Histogram for metrics, we have encountered intermittent mismatch between the overall count and the sum of bucket counts.

Steps to Reproduce

  1. Setup Otel JS metrics
  2. Use Exponential histogram aggregation.
  3. Export metrics to Open-telemetry collector gateway (https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.91.0)
  4. Open-telemetry collector gateway exports it to Mimir Cluster using prometheusremotewrite (https://github.com/grafana/mimir/releases/tag/mimir-2.10.5)

Our metrics pipeline is running inside K8s. Plainly, we have a collection of service pods running an otel collector as a sidecar agent. Services are publishing metrics to their local sidecar agent, which in turn publishes metrics via otlphttp to our OpenTelemetryCollector Gateway (i.e. cluster of otel collector pods). Pods in our OpenTelemetryCollector Gateway deployment then publish metrics to Grafana Mimir via prometheusremotewrite.

Expected Result

No Mismatch in counts.

Actual Result

Mimir Distributor Log:
error exporterhelper/common.go:49 Exporting failed. Dropping data. Try enabling sending_queue to survive temporary failures. {"kind": "exporter", "data_type": "metrics", "name": "prometheusremotewrite/mimir", "dropped_items": 66, "error": "Permanent error: Permanent error: remote write returned HTTP status 500 Internal Server Error; err = %!w(<nil>): failed pushing to ingester: rpc error: code = Unknown desc = user={user}: 16504 observations found in buckets, but the Count field is 13906: histogram's observation count should be at least the number of observations found in the bucket

Additional Details

ScopeMetrics #0 
ScopeMetrics SchemaURL: 
InstrumentationScope: {service_name} 
Metric #0 
Descriptor: 
     -> Name: {metric_name}
     -> Unit: 
     -> DataType: ExponentialHistogram 
     -> AggregationTemporality: Cumulative 
ExponentialHistogramDataPoints #0 
StartTimestamp: 2024-01-19 17:21:10.7 +0000 UTC 
Timestamp: 2024-01-19 17:35:39.081999872 +0000 UTC 
Count: 13906 
Sum: 32.756000 
Min: 0.000000 
Max: 0.213000 
Bucket [0, 0], Count: 3112 
Bucket (0.000977, 0.001065], Count: 9473 
Bucket (0.001065, 0.001161], Count: 0 
Bucket (0.001161, 0.001266], Count: 0 
Bucket (0.001266, 0.001381], Count: 0 
Bucket (0.001381, 0.001506], Count: 0 
Bucket (0.001506, 0.001642], Count: 0 
Bucket (0.001642, 0.001791], Count: 0 
Bucket (0.001791, 0.001953], Count: 0 
Bucket (0.001953, 0.002130], Count: 512 
Bucket (0.002130, 0.002323], Count: 0 
Bucket (0.002323, 0.002533], Count: 0 
Bucket (0.002533, 0.002762], Count: 0 
Bucket (0.002762, 0.003012], Count: 154 
Bucket (0.003012, 0.003285], Count: 0 
Bucket (0.003285, 0.003582], Count: 0 
Bucket (0.003582, 0.003906], Count: 0 
Bucket (0.003906, 0.004260], Count: 49 
Bucket (0.004260, 0.004645], Count: 0 
Bucket (0.004645, 0.005066], Count: 41 
Bucket (0.005066, 0.005524], Count: 0 
Bucket (0.005524, 0.006024], Count: 36 
Bucket (0.006024, 0.006570], Count: 0 
Bucket (0.006570, 0.007164], Count: 31 
Bucket (0.007164, 0.007813], Count: 0 
Bucket (0.007813, 0.008520], Count: 25 
Bucket (0.008520, 0.009291], Count: 18 
Bucket (0.009291, 0.010132], Count: 20 
Bucket (0.010132, 0.011049], Count: 18 
Bucket (0.011049, 0.012049], Count: 10 
Bucket (0.012049, 0.013139], Count: 9 
Bucket (0.013139, 0.014328], Count: 10 
Bucket (0.014328, 0.015625], Count: 9 
Bucket (0.015625, 0.017039], Count: 19 
Bucket (0.017039, 0.018581], Count: 16 
Bucket (0.018581, 0.020263], Count: 32 
Bucket (0.020263, 0.022097], Count: 20 
Bucket (0.022097, 0.024097], Count: 11 
Bucket (0.024097, 0.026278], Count: 9 
Bucket (0.026278, 0.028656], Count: 6 
Bucket (0.028656, 0.031250], Count: 7 
Bucket (0.031250, 0.034078], Count: 6 
Bucket (0.034078, 0.037163], Count: 7 
Bucket (0.037163, 0.040526], Count: 25 
Bucket (0.040526, 0.044194], Count: 32 
Bucket (0.044194, 0.048194], Count: 14 
Bucket (0.048194, 0.052556], Count: 12 
Bucket (0.052556, 0.057313], Count: 9 
Bucket (0.057313, 0.062500], Count: 21 
Bucket (0.062500, 0.068157], Count: 40 
Bucket (0.068157, 0.074325], Count: 25 
Bucket (0.074325, 0.081052], Count: 18 
Bucket (0.081052, 0.088388], Count: 26 
Bucket (0.088388, 0.096388], Count: 6 
Bucket (0.096388, 0.105112], Count: 5 
Bucket (0.105112, 0.114626], Count: 0 
Bucket (0.114626, 0.125000], Count: 0 
Bucket (0.125000, 0.136313], Count: 3 
Bucket (0.136313, 0.148651], Count: 0 
Bucket (0.148651, 0.162105], Count: 1 
Bucket (0.162105, 0.176777], Count: 1 
Bucket (0.176777, 0.192776], Count: 1 
Bucket (0.192776, 0.210224], Count: 6 
Bucket (0.210224, 0.229251], Count: 1 
Bucket (0.229251, 0.250000], Count: 0 
Bucket (0.250000, 0.272627], Count: 0 
Bucket (0.272627, 0.297302], Count: 0 
Bucket (0.297302, 0.324210], Count: 0 
Bucket (0.324210, 0.353553], Count: 0 
Bucket (0.353553, 0.385553], Count: 0 
Bucket (0.385553, 0.420448], Count: 0 
Bucket (0.420448, 0.458502], Count: 0 
Bucket (0.458502, 0.500000], Count: 0 
Bucket (0.500000, 0.545254], Count: 0 
Bucket (0.545254, 0.594604], Count: 0 
Bucket (0.594604, 0.648420], Count: 0 
Bucket (0.648420, 0.707107], Count: 0 
Bucket (0.707107, 0.771105], Count: 0 
Bucket (0.771105, 0.840896], Count: 0 
Bucket (0.840896, 0.917004], Count: 0 
Bucket (0.917004, 1.000000], Count: 0 
Bucket (1.000000, 1.090508], Count: 5710

OpenTelemetry Setup Code

const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
      const { PeriodicExportingMetricReader, MeterProvider, InstrumentType, View, ExponentialHistogramAggregation } = require('@opentelemetry/sdk-metrics');

      // Initialize a global Meter with default OTLPTraceExporter (unless configured otherwise)
      // Initialize a global Meter with default PeriodicExportingMetricReader (unless configured otherwise)
      // If metrics are not enabled, do not initialize metricReader
      const otlpMetricExporterConfig = Object.assign({ url: process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT }, opts.otlpMetricExporterConfig);
      const metricExporter =  new OTLPMetricExporter(otlpMetricExporterConfig);
      const metricReaderOptions = Object.assign({ exporter: metricExporter, exportIntervalMillis: 30000 }, opts.metricReaderOptions);


      const meterProvider = new MeterProvider({ resource, views: [ new View({
        instrumentType: InstrumentType.HISTOGRAM,
        aggregation: new ExponentialHistogramAggregation() 
      })  ]});
      
      
      meterProvider.addMetricReader(new PeriodicExportingMetricReader(metricReaderOptions));
      api.metrics.setGlobalMeterProvider(meterProvider);

      ['SIGINT', 'SIGTERM'].forEach(signal => {
        process.on(signal, () => meterProvider.shutdown().catch(console.error));
      });

.....

  const httpResponseTime = meter.createHistogram("http.client.request.duration", {
    description: "Duration of HTTP client requests."
  });
  httpResponseTime.record(duration.{route: request.route.path});

package.json

"dependencies": {
    "@opentelemetry/api": "1.4.1",
    "@opentelemetry/exporter-metrics-otlp-grpc": "0.39.1",
    "@opentelemetry/exporter-trace-otlp-grpc": "0.39.1",
    "@opentelemetry/instrumentation": "0.39.1",
    "@opentelemetry/instrumentation-amqplib": "0.32.4",
    "@opentelemetry/instrumentation-hapi": "0.31.3",
    "@opentelemetry/instrumentation-http": "0.39.1",
    "@opentelemetry/instrumentation-pg": "0.35.2",
    "@opentelemetry/instrumentation-redis": "0.34.6",
    "@opentelemetry/instrumentation-redis-4": "0.34.5",
    "@opentelemetry/resource-detector-container": "0.3.0",
    "@opentelemetry/resources": "1.13.0",
    "@opentelemetry/sdk-metrics": "1.13.0",
    "@opentelemetry/sdk-trace-base": "1.13.0",
    "@opentelemetry/sdk-trace-node": "1.13.0",
    "lodash": "^4.17.21"
  },

Relevant log output

No response

@kothariroshni8 kothariroshni8 added bug Something isn't working triage labels Jan 30, 2024
@dyladan dyladan added priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect and removed triage labels Jan 31, 2024
@dyladan
Copy link
Member

dyladan commented Jan 31, 2024

@kothariroshni8 is there a minimal way to reproduce this? How often is "intermittent"? Without a reproduction this may be hard to track down, but I think it is important to fix.

@mwear can you please look into this? I think this should definitely not be possible.

edit: sorry Aaron for the errant ping

@mwear
Copy link
Member

mwear commented Jan 31, 2024

@martinkuba and I looked at the code involving the counts and zero counts and were not able to find anything obviously wrong. We'd like to see if there is some way to narrow this down more definitively to an issue in the JS sdk. I'll paste an image below that has what I believe to be something representative of your current setup (on top).

Screenshot 2024-01-31 at 3 45 46 PM

Would you be able to setup a single JS process that reports into a single collector that exports to mimir (like the lower part of the diagram) and see if that repros? If it does, and you can provide logs (as in your original post) that would be helpful. We're just trying to rule out some of the potential complexities in the multi-process, multi-collector scenario you are currently running.

@kothariroshni8
Copy link
Author

kothariroshni8 commented Jan 31, 2024

@dyladan Yes, it is difficult to reproduce, I tried multiple ways but no luck.
Two observation:

  1. Max Value is incorrect.
  2. The amount of difference is always equal to (last bucket count - zero bucket count).
    For eg in above case
    Sum of bucket counts = 16504
    Count = 13906
    last bucket count = 5710
    Zero bucket = 3112.
    sum of bucket counts = Count+ last bucket count - zero bucket count.

@mwear
Copy link
Member

mwear commented Feb 1, 2024

Those observations are helpful. Looking at the data, I suspect that the max value might actually be correct and that the counts in the last bucket might be there as the result of an off by 1 error. The prior non-zero bucket is (0.210224, 0.229251], Count: 1 which would correspond to max: 0.213000. @martinkuba and I will continue to look into this.

@pichlermarc
Copy link
Member

I just realized that we allow NaN to be recorded into instruments may cause a discrepancy in the sum of bucket count values and the overall count (see #4455), as NaN will be a value counted, but will never match a bucket. Unfortunately it does not explain the incorrect max value.

Just speculating, but maybe this is behavior here is the result of two different issues. 🤔

@kothariroshni8
Copy link
Author

kothariroshni8 commented Feb 2, 2024

I think error is coming from the Merge Function in ExponentialHistogram.ts

What I Tried

I Patched the merge function and compared the count after it runs.

ExponentialHistogramAggregator.prototype.merge = new Proxy(ExponentialHistogramAggregator.prototype.merge, {
    apply: function(target, that, args){
      console.log("Merge Called"); 
      let return1 = target.apply(that, args);
      try{
        let  sumCount  = 0;
        return1._positive.counts().map(x =>{
          sumCount += x;
        });
        if(sumCount > return1._count){
          instruments.CountMismatchCounter.add(1, {"count": return1._count, "BucketCount": sumCount, "when": "after Merge"});
          console.log("context while Error", return1);
        }
        return return1;
      }
      catch(error){
        console.log("Error in  Merge", error);
        return return1;
      }
    }
  });

Output Log.


 Merge Called 
 context while Error ExponentialHistogramAccumulation { 
   startTime: [ 1706832573, 958000000 ], 
   _maxSize: 160, 
   _recordMinMax: true, 
   _sum: 2.3390000000000004, 
   _count: 879, 
   _zeroCount: 172, 
   _min: 0, 
   _max: 0.131, 
   _positive: Buckets { 
     backing: BucketsBacking { _counts: [Array] }, 
     indexBase: -80, 
     indexStart: -80, 
     indexEnd: 0 
   }, 
   _negative: Buckets { 
     backing: BucketsBacking { _counts: [Array] }, 
     indexBase: 0, 
     indexStart: 0, 
     indexEnd: 0 
   }, 
   _mapping: LogarithmMapping { 
     _scale: 3, 
     _scaleFactor: 11.541560327111707, 
     _inverseFactor: 0.08664339756999316 
   } 
 } 
 Bucket Count Mismatch: 
 count 879 scale 3  zeroCount 172 BucketCount 1224 
 Bucket Length 81 negtive 0 

Also, it mostly happens with bucket length 81 and 161.
@mwear : When we are calling this Merge function? and could you also check logic in there?

@mwear
Copy link
Member

mwear commented Feb 2, 2024

@kothariroshni8 thanks for your debugging work and isolating this to the merge operation; it's super helpful. I'll look into the merge logic in detail tomorrow. merge is called here by the TemporalMetricProcessor as it is accumulating batches for export.

@mwear
Copy link
Member

mwear commented Feb 2, 2024

If you have the time, you could add the following to the ExponentialHistogramAccumulation:

  printBuckets() {
    console.log(`scale: %d\ncount: %d\nzero count: %d\nmin: %d\nmax: %d\nsum: %d`,
      this.scale, this.count, this.zeroCount, this.min, this.max, this.sum);
      const buckets = this.positive;
      for (let i = 0; i < buckets.length; i++) {
        const index = buckets.offset + i;
        const lower = this._mapping.lowerBoundary(index).toFixed(8);
        const upper = this._mapping.lowerBoundary(index + 1).toFixed(8)
        const count = buckets.at(i);
        console.log(`Bucket: (%d, %d], Count: %d, Index: %d`, lower,  upper, count, index);
      }
  }

Then you could modify merge in the ExponentialHistogramAggregator:

merge(
  previous: ExponentialHistogramAccumulation,
  delta: ExponentialHistogramAccumulation
): ExponentialHistogramAccumulation {
  const result = delta.clone();
  result.merge(previous);
  
  // if counts not matching
  console.log('merge: delta');
  delta.printBuckets();
  console.log('merge: previous');
  previous.printBuckets();
  console.log('merge: result');
  result.printBuckets();
  
  return result;
}

That will output the buckets, counts, etc in a very similar format to what you see in the collector. I should be able to reconstruct the histograms from that if need be.

@kothariroshni8
Copy link
Author

kothariroshni8 commented Feb 2, 2024

@mwear : PFB bucket details as you requested :

merge: delta
scale: 0
count: 2
zero count: 2
min: 0
max: 0
sum: 0
merge: previous
scale: 4
count: 88
zero count: 2
min: 0
max: 0.103
sum: 0.9600000000000002
Bucket: (0.00097656, 0.0010198], Count: 41, Index: -160
Bucket: (0.0010198, 0.00106495], Count: 0, Index: -159
Bucket: (0.00106495, 0.0011121], Count: 0, Index: -158
Bucket: (0.0011121, 0.00116134], Count: 0, Index: -157
Bucket: (0.00116134, 0.00121275], Count: 0, Index: -156
Bucket: (0.00121275, 0.00126644], Count: 0, Index: -155
Bucket: (0.00126644, 0.00132252], Count: 0, Index: -154
Bucket: (0.00132252, 0.00138107], Count: 0, Index: -153
Bucket: (0.00138107, 0.00144221], Count: 0, Index: -152
Bucket: (0.00144221, 0.00150607], Count: 0, Index: -151
Bucket: (0.00150607, 0.00157274], Count: 0, Index: -150
Bucket: (0.00157274, 0.00164238], Count: 0, Index: -149
Bucket: (0.00164238, 0.00171509], Count: 0, Index: -148
Bucket: (0.00171509, 0.00179102], Count: 0, Index: -147
Bucket: (0.00179102, 0.00187032], Count: 0, Index: -146
Bucket: (0.00187032, 0.00195313], Count: 0, Index: -145
Bucket: (0.00195313, 0.0020396], Count: 17, Index: -144
Bucket: (0.0020396, 0.0021299], Count: 0, Index: -143
Bucket: (0.0021299, 0.0022242], Count: 0, Index: -142
Bucket: (0.0022242, 0.00232267], Count: 0, Index: -141
Bucket: (0.00232267, 0.0024255], Count: 0, Index: -140
Bucket: (0.0024255, 0.00253289], Count: 0, Index: -139
Bucket: (0.00253289, 0.00264503], Count: 0, Index: -138
Bucket: (0.00264503, 0.00276214], Count: 0, Index: -137
Bucket: (0.00276214, 0.00288443], Count: 0, Index: -136
Bucket: (0.00288443, 0.00301213], Count: 1, Index: -135
Bucket: (0.00301213, 0.00314549], Count: 0, Index: -134
Bucket: (0.00314549, 0.00328475], Count: 0, Index: -133
Bucket: (0.00328475, 0.00343018], Count: 0, Index: -132
Bucket: (0.00343018, 0.00358205], Count: 0, Index: -131
Bucket: (0.00358205, 0.00374064], Count: 0, Index: -130
Bucket: (0.00374064, 0.00390625], Count: 0, Index: -129
Bucket: (0.00390625, 0.00407919], Count: 1, Index: -128
Bucket: (0.00407919, 0.0042598], Count: 0, Index: -127
Bucket: (0.0042598, 0.00444839], Count: 0, Index: -126
Bucket: (0.00444839, 0.00464534], Count: 0, Index: -125
Bucket: (0.00464534, 0.00485101], Count: 0, Index: -124
Bucket: (0.00485101, 0.00506578], Count: 2, Index: -123
Bucket: (0.00506578, 0.00529006], Count: 0, Index: -122
Bucket: (0.00529006, 0.00552427], Count: 0, Index: -121
Bucket: (0.00552427, 0.00576885], Count: 0, Index: -120
Bucket: (0.00576885, 0.00602426], Count: 0, Index: -119
Bucket: (0.00602426, 0.00629098], Count: 0, Index: -118
Bucket: (0.00629098, 0.0065695], Count: 0, Index: -117
Bucket: (0.0065695, 0.00686036], Count: 0, Index: -116
Bucket: (0.00686036, 0.00716409], Count: 0, Index: -115
Bucket: (0.00716409, 0.00748128], Count: 0, Index: -114
Bucket: (0.00748128, 0.0078125], Count: 0, Index: -113
Bucket: (0.0078125, 0.00815839], Count: 0, Index: -112
Bucket: (0.00815839, 0.00851959], Count: 0, Index: -111
Bucket: (0.00851959, 0.00889679], Count: 0, Index: -110
Bucket: (0.00889679, 0.00929068], Count: 1, Index: -109
Bucket: (0.00929068, 0.00970201], Count: 0, Index: -108
Bucket: (0.00970201, 0.01013156], Count: 0, Index: -107
Bucket: (0.01013156, 0.01058012], Count: 0, Index: -106
Bucket: (0.01058012, 0.01104854], Count: 0, Index: -105
Bucket: (0.01104854, 0.0115377], Count: 0, Index: -104
Bucket: (0.0115377, 0.01204852], Count: 0, Index: -103
Bucket: (0.01204852, 0.01258196], Count: 0, Index: -102
Bucket: (0.01258196, 0.01313901], Count: 0, Index: -101
Bucket: (0.01313901, 0.01372072], Count: 0, Index: -100
Bucket: (0.01372072, 0.01432819], Count: 0, Index: -99
Bucket: (0.01432819, 0.01496255], Count: 0, Index: -98
Bucket: (0.01496255, 0.015625], Count: 0, Index: -97
Bucket: (0.015625, 0.01631678], Count: 0, Index: -96
Bucket: (0.01631678, 0.01703918], Count: 0, Index: -95
Bucket: (0.01703918, 0.01779357], Count: 0, Index: -94
Bucket: (0.01779357, 0.01858136], Count: 0, Index: -93
Bucket: (0.01858136, 0.01940403], Count: 1, Index: -92
Bucket: (0.01940403, 0.02026312], Count: 0, Index: -91
Bucket: (0.02026312, 0.02116024], Count: 2, Index: -90
Bucket: (0.02116024, 0.02209709], Count: 3, Index: -89
Bucket: (0.02209709, 0.02307541], Count: 0, Index: -88
Bucket: (0.02307541, 0.02409704], Count: 2, Index: -87
Bucket: (0.02409704, 0.02516391], Count: 0, Index: -86
Bucket: (0.02516391, 0.02627801], Count: 2, Index: -85
Bucket: (0.02627801, 0.02744144], Count: 1, Index: -84
Bucket: (0.02744144, 0.02865638], Count: 0, Index: -83
Bucket: (0.02865638, 0.0299251], Count: 0, Index: -82
Bucket: (0.0299251, 0.03125], Count: 2, Index: -81
Bucket: (0.03125, 0.03263356], Count: 1, Index: -80
Bucket: (0.03263356, 0.03407837], Count: 1, Index: -79
Bucket: (0.03407837, 0.03558714], Count: 0, Index: -78
Bucket: (0.03558714, 0.03716272], Count: 0, Index: -77
Bucket: (0.03716272, 0.03880806], Count: 1, Index: -76
Bucket: (0.03880806, 0.04052624], Count: 1, Index: -75
Bucket: (0.04052624, 0.04232049], Count: 0, Index: -74
Bucket: (0.04232049, 0.04419417], Count: 1, Index: -73
Bucket: (0.04419417, 0.04615082], Count: 1, Index: -72
Bucket: (0.04615082, 0.04819409], Count: 0, Index: -71
Bucket: (0.04819409, 0.05032782], Count: 1, Index: -70
Bucket: (0.05032782, 0.05255603], Count: 0, Index: -69
Bucket: (0.05255603, 0.05488288], Count: 0, Index: -68
Bucket: (0.05488288, 0.05731275], Count: 0, Index: -67
Bucket: (0.05731275, 0.05985021], Count: 0, Index: -66
Bucket: (0.05985021, 0.0625], Count: 0, Index: -65
Bucket: (0.0625, 0.06526711], Count: 0, Index: -64
Bucket: (0.06526711, 0.06815673], Count: 1, Index: -63
Bucket: (0.06815673, 0.07117429], Count: 0, Index: -62
Bucket: (0.07117429, 0.07432544], Count: 0, Index: -61
Bucket: (0.07432544, 0.07761611], Count: 0, Index: -60
Bucket: (0.07761611, 0.08105247], Count: 0, Index: -59
Bucket: (0.08105247, 0.08464097], Count: 0, Index: -58
Bucket: (0.08464097, 0.08838835], Count: 0, Index: -57
Bucket: (0.08838835, 0.09230163], Count: 0, Index: -56
Bucket: (0.09230163, 0.09638818], Count: 1, Index: -55
Bucket: (0.09638818, 0.10065565], Count: 0, Index: -54
Bucket: (0.10065565, 0.10511205], Count: 1, Index: -53
merge: result
scale: 4
count: 90
zero count: 4
min: 0
max: 0.103
sum: 0.9600000000000002
Bucket: (0.00097656, 0.0010198], Count: 41, Index: -160
Bucket: (0.0010198, 0.00106495], Count: 0, Index: -159
Bucket: (0.00106495, 0.0011121], Count: 0, Index: -158
Bucket: (0.0011121, 0.00116134], Count: 0, Index: -157
Bucket: (0.00116134, 0.00121275], Count: 0, Index: -156
Bucket: (0.00121275, 0.00126644], Count: 0, Index: -155
Bucket: (0.00126644, 0.00132252], Count: 0, Index: -154
Bucket: (0.00132252, 0.00138107], Count: 0, Index: -153
Bucket: (0.00138107, 0.00144221], Count: 0, Index: -152
Bucket: (0.00144221, 0.00150607], Count: 0, Index: -151
Bucket: (0.00150607, 0.00157274], Count: 0, Index: -150
Bucket: (0.00157274, 0.00164238], Count: 0, Index: -149
Bucket: (0.00164238, 0.00171509], Count: 0, Index: -148
Bucket: (0.00171509, 0.00179102], Count: 0, Index: -147
Bucket: (0.00179102, 0.00187032], Count: 0, Index: -146
Bucket: (0.00187032, 0.00195313], Count: 0, Index: -145
Bucket: (0.00195313, 0.0020396], Count: 17, Index: -144
Bucket: (0.0020396, 0.0021299], Count: 0, Index: -143
Bucket: (0.0021299, 0.0022242], Count: 0, Index: -142
Bucket: (0.0022242, 0.00232267], Count: 0, Index: -141
Bucket: (0.00232267, 0.0024255], Count: 0, Index: -140
Bucket: (0.0024255, 0.00253289], Count: 0, Index: -139
Bucket: (0.00253289, 0.00264503], Count: 0, Index: -138
Bucket: (0.00264503, 0.00276214], Count: 0, Index: -137
Bucket: (0.00276214, 0.00288443], Count: 0, Index: -136
Bucket: (0.00288443, 0.00301213], Count: 1, Index: -135
Bucket: (0.00301213, 0.00314549], Count: 0, Index: -134
Bucket: (0.00314549, 0.00328475], Count: 0, Index: -133
Bucket: (0.00328475, 0.00343018], Count: 0, Index: -132
Bucket: (0.00343018, 0.00358205], Count: 0, Index: -131
Bucket: (0.00358205, 0.00374064], Count: 0, Index: -130
Bucket: (0.00374064, 0.00390625], Count: 0, Index: -129
Bucket: (0.00390625, 0.00407919], Count: 1, Index: -128
Bucket: (0.00407919, 0.0042598], Count: 0, Index: -127
Bucket: (0.0042598, 0.00444839], Count: 0, Index: -126
Bucket: (0.00444839, 0.00464534], Count: 0, Index: -125
Bucket: (0.00464534, 0.00485101], Count: 0, Index: -124
Bucket: (0.00485101, 0.00506578], Count: 2, Index: -123
Bucket: (0.00506578, 0.00529006], Count: 0, Index: -122
Bucket: (0.00529006, 0.00552427], Count: 0, Index: -121
Bucket: (0.00552427, 0.00576885], Count: 0, Index: -120
Bucket: (0.00576885, 0.00602426], Count: 0, Index: -119
Bucket: (0.00602426, 0.00629098], Count: 0, Index: -118
Bucket: (0.00629098, 0.0065695], Count: 0, Index: -117
Bucket: (0.0065695, 0.00686036], Count: 0, Index: -116
Bucket: (0.00686036, 0.00716409], Count: 0, Index: -115
Bucket: (0.00716409, 0.00748128], Count: 0, Index: -114
Bucket: (0.00748128, 0.0078125], Count: 0, Index: -113
Bucket: (0.0078125, 0.00815839], Count: 0, Index: -112
Bucket: (0.00815839, 0.00851959], Count: 0, Index: -111
Bucket: (0.00851959, 0.00889679], Count: 0, Index: -110
Bucket: (0.00889679, 0.00929068], Count: 1, Index: -109
Bucket: (0.00929068, 0.00970201], Count: 0, Index: -108
Bucket: (0.00970201, 0.01013156], Count: 0, Index: -107
Bucket: (0.01013156, 0.01058012], Count: 0, Index: -106
Bucket: (0.01058012, 0.01104854], Count: 0, Index: -105
Bucket: (0.01104854, 0.0115377], Count: 0, Index: -104
Bucket: (0.0115377, 0.01204852], Count: 0, Index: -103
Bucket: (0.01204852, 0.01258196], Count: 0, Index: -102
Bucket: (0.01258196, 0.01313901], Count: 0, Index: -101
Bucket: (0.01313901, 0.01372072], Count: 0, Index: -100
Bucket: (0.01372072, 0.01432819], Count: 0, Index: -99
Bucket: (0.01432819, 0.01496255], Count: 0, Index: -98
Bucket: (0.01496255, 0.015625], Count: 0, Index: -97
Bucket: (0.015625, 0.01631678], Count: 0, Index: -96
Bucket: (0.01631678, 0.01703918], Count: 0, Index: -95
Bucket: (0.01703918, 0.01779357], Count: 0, Index: -94
Bucket: (0.01779357, 0.01858136], Count: 0, Index: -93
Bucket: (0.01858136, 0.01940403], Count: 1, Index: -92
Bucket: (0.01940403, 0.02026312], Count: 0, Index: -91
Bucket: (0.02026312, 0.02116024], Count: 2, Index: -90
Bucket: (0.02116024, 0.02209709], Count: 3, Index: -89
Bucket: (0.02209709, 0.02307541], Count: 0, Index: -88
Bucket: (0.02307541, 0.02409704], Count: 2, Index: -87
Bucket: (0.02409704, 0.02516391], Count: 0, Index: -86
Bucket: (0.02516391, 0.02627801], Count: 2, Index: -85
Bucket: (0.02627801, 0.02744144], Count: 1, Index: -84
Bucket: (0.02744144, 0.02865638], Count: 0, Index: -83
Bucket: (0.02865638, 0.0299251], Count: 0, Index: -82
Bucket: (0.0299251, 0.03125], Count: 2, Index: -81
Bucket: (0.03125, 0.03263356], Count: 1, Index: -80
Bucket: (0.03263356, 0.03407837], Count: 1, Index: -79
Bucket: (0.03407837, 0.03558714], Count: 0, Index: -78
Bucket: (0.03558714, 0.03716272], Count: 0, Index: -77
Bucket: (0.03716272, 0.03880806], Count: 1, Index: -76
Bucket: (0.03880806, 0.04052624], Count: 1, Index: -75
Bucket: (0.04052624, 0.04232049], Count: 0, Index: -74
Bucket: (0.04232049, 0.04419417], Count: 1, Index: -73
Bucket: (0.04419417, 0.04615082], Count: 1, Index: -72
Bucket: (0.04615082, 0.04819409], Count: 0, Index: -71
Bucket: (0.04819409, 0.05032782], Count: 1, Index: -70
Bucket: (0.05032782, 0.05255603], Count: 0, Index: -69
Bucket: (0.05255603, 0.05488288], Count: 0, Index: -68
Bucket: (0.05488288, 0.05731275], Count: 0, Index: -67
Bucket: (0.05731275, 0.05985021], Count: 0, Index: -66
Bucket: (0.05985021, 0.0625], Count: 0, Index: -65
Bucket: (0.0625, 0.06526711], Count: 0, Index: -64
Bucket: (0.06526711, 0.06815673], Count: 1, Index: -63
Bucket: (0.06815673, 0.07117429], Count: 0, Index: -62
Bucket: (0.07117429, 0.07432544], Count: 0, Index: -61
Bucket: (0.07432544, 0.07761611], Count: 0, Index: -60
Bucket: (0.07761611, 0.08105247], Count: 0, Index: -59
Bucket: (0.08105247, 0.08464097], Count: 0, Index: -58
Bucket: (0.08464097, 0.08838835], Count: 0, Index: -57
Bucket: (0.08838835, 0.09230163], Count: 0, Index: -56
Bucket: (0.09230163, 0.09638818], Count: 1, Index: -55
Bucket: (0.09638818, 0.10065565], Count: 0, Index: -54
Bucket: (0.10065565, 0.10511205], Count: 1, Index: -53
Bucket: (0.10511205, 0.10976576], Count: 0, Index: -52
Bucket: (0.10976576, 0.11462551], Count: 0, Index: -51
Bucket: (0.11462551, 0.11970041], Count: 0, Index: -50
Bucket: (0.11970041, 0.125], Count: 0, Index: -49
Bucket: (0.125, 0.13053422], Count: 0, Index: -48
Bucket: (0.13053422, 0.13631347], Count: 0, Index: -47
Bucket: (0.13631347, 0.14234858], Count: 0, Index: -46
Bucket: (0.14234858, 0.14865089], Count: 0, Index: -45
Bucket: (0.14865089, 0.15523223], Count: 0, Index: -44
Bucket: (0.15523223, 0.16210494], Count: 0, Index: -43
Bucket: (0.16210494, 0.16928194], Count: 0, Index: -42
Bucket: (0.16928194, 0.1767767], Count: 0, Index: -41
Bucket: (0.1767767, 0.18460327], Count: 0, Index: -40
Bucket: (0.18460327, 0.19277635], Count: 0, Index: -39
Bucket: (0.19277635, 0.20131129], Count: 0, Index: -38
Bucket: (0.20131129, 0.2102241], Count: 0, Index: -37
Bucket: (0.2102241, 0.21953152], Count: 0, Index: -36
Bucket: (0.21953152, 0.22925101], Count: 0, Index: -35
Bucket: (0.22925101, 0.23940082], Count: 0, Index: -34
Bucket: (0.23940082, 0.25], Count: 0, Index: -33
Bucket: (0.25, 0.26106845], Count: 0, Index: -32
Bucket: (0.26106845, 0.27262693], Count: 0, Index: -31
Bucket: (0.27262693, 0.28469716], Count: 0, Index: -30
Bucket: (0.28469716, 0.29730178], Count: 0, Index: -29
Bucket: (0.29730178, 0.31046445], Count: 0, Index: -28
Bucket: (0.31046445, 0.32420989], Count: 0, Index: -27
Bucket: (0.32420989, 0.33856389], Count: 0, Index: -26
Bucket: (0.33856389, 0.35355339], Count: 0, Index: -25
Bucket: (0.35355339, 0.36920654], Count: 0, Index: -24
Bucket: (0.36920654, 0.38555271], Count: 0, Index: -23
Bucket: (0.38555271, 0.40262258], Count: 0, Index: -22
Bucket: (0.40262258, 0.42044821], Count: 0, Index: -21
Bucket: (0.42044821, 0.43906304], Count: 0, Index: -20
Bucket: (0.43906304, 0.45850202], Count: 0, Index: -19
Bucket: (0.45850202, 0.47880164], Count: 0, Index: -18
Bucket: (0.47880164, 0.5], Count: 0, Index: -17
Bucket: (0.5, 0.52213689], Count: 0, Index: -16
Bucket: (0.52213689, 0.54525387], Count: 0, Index: -15
Bucket: (0.54525387, 0.56939432], Count: 0, Index: -14
Bucket: (0.56939432, 0.59460356], Count: 0, Index: -13
Bucket: (0.59460356, 0.62092891], Count: 0, Index: -12
Bucket: (0.62092891, 0.64841978], Count: 0, Index: -11
Bucket: (0.64841978, 0.67712777], Count: 0, Index: -10
Bucket: (0.67712777, 0.70710678], Count: 0, Index: -9
Bucket: (0.70710678, 0.73841307], Count: 0, Index: -8
Bucket: (0.73841307, 0.77110541], Count: 0, Index: -7
Bucket: (0.77110541, 0.80524517], Count: 0, Index: -6
Bucket: (0.80524517, 0.84089642], Count: 0, Index: -5
Bucket: (0.84089642, 0.87812608], Count: 0, Index: -4
Bucket: (0.87812608, 0.91700404], Count: 0, Index: -3
Bucket: (0.91700404, 0.95760328], Count: 0, Index: -2
Bucket: (0.95760328, 1], Count: 0, Index: -1
Bucket: (1, 1.04427378], Count: 41, Index: 0
Bucket Count Mismatch:

 count 90 scale 4  zeroCount 4 BucketCount 127
Bucket Length 161 negative 0

@kothariroshni8
Copy link
Author

is it happening when any one of the buckets has no value?

@mwear
Copy link
Member

mwear commented Feb 3, 2024

I setup a test case to replicate the data from your original comment #4450 (comment) (which has since been edited). By the way, the current edit doesn't include the data from all three histograms: delta, previous, and result, so I can't do the same analysis on it. I'll describe my process with your original data and see if you might be able to replicate it on any output you capture and see if we can find anything interesting or a reliable repro.

Before getting into the data, I wanted to point out one detail. The count for the histogram includes the counts of all the buckets, plus the zero count. Zero doesn't get a dedicated bucket in the output. I think that is one detail missing when you are detecting a mismatch in your patched merge function. That said, the data you provided shows the counts are off by more than just the zero count.

The data I'm working was from your first comment before the edits, which I'll paste below:

merge: delta
scale: 4
count: 11
zero count: 0
min: 0.001
max: 0.125
sum: 0.16000000000000003
Bucket: [0.00097656, 0.0010198], Count: 2, Index: -160
Bucket: [0.0010198, 0.00106495], Count: 0, Index: -159
Bucket: [0.00106495, 0.0011121], Count: 0, Index: -158
Bucket: [0.0011121, 0.00116134], Count: 0, Index: -157
Bucket: [0.00116134, 0.00121275], Count: 0, Index: -156
Bucket: [0.00121275, 0.00126644], Count: 0, Index: -155
Bucket: [0.00126644, 0.00132252], Count: 0, Index: -154
Bucket: [0.00132252, 0.00138107], Count: 0, Index: -153
Bucket: [0.00138107, 0.00144221], Count: 0, Index: -152
Bucket: [0.00144221, 0.00150607], Count: 0, Index: -151
Bucket: [0.00150607, 0.00157274], Count: 0, Index: -150
Bucket: [0.00157274, 0.00164238], Count: 0, Index: -149
Bucket: [0.00164238, 0.00171509], Count: 0, Index: -148
Bucket: [0.00171509, 0.00179102], Count: 0, Index: -147
Bucket: [0.00179102, 0.00187032], Count: 0, Index: -146
Bucket: [0.00187032, 0.00195313], Count: 0, Index: -145
Bucket: [0.00195313, 0.0020396], Count: 2, Index: -144
Bucket: [0.0020396, 0.0021299], Count: 0, Index: -143
Bucket: [0.0021299, 0.0022242], Count: 0, Index: -142
Bucket: [0.0022242, 0.00232267], Count: 0, Index: -141
Bucket: [0.00232267, 0.0024255], Count: 0, Index: -140
Bucket: [0.0024255, 0.00253289], Count: 0, Index: -139
Bucket: [0.00253289, 0.00264503], Count: 0, Index: -138
Bucket: [0.00264503, 0.00276214], Count: 0, Index: -137
Bucket: [0.00276214, 0.00288443], Count: 0, Index: -136
Bucket: [0.00288443, 0.00301213], Count: 2, Index: -135
Bucket: [0.00301213, 0.00314549], Count: 0, Index: -134
Bucket: [0.00314549, 0.00328475], Count: 0, Index: -133
Bucket: [0.00328475, 0.00343018], Count: 0, Index: -132
Bucket: [0.00343018, 0.00358205], Count: 0, Index: -131
Bucket: [0.00358205, 0.00374064], Count: 0, Index: -130
Bucket: [0.00374064, 0.00390625], Count: 0, Index: -129
Bucket: [0.00390625, 0.00407919], Count: 1, Index: -128
Bucket: [0.00407919, 0.0042598], Count: 0, Index: -127
Bucket: [0.0042598, 0.00444839], Count: 0, Index: -126
Bucket: [0.00444839, 0.00464534], Count: 0, Index: -125
Bucket: [0.00464534, 0.00485101], Count: 0, Index: -124
Bucket: [0.00485101, 0.00506578], Count: 1, Index: -123
Bucket: [0.00506578, 0.00529006], Count: 0, Index: -122
Bucket: [0.00529006, 0.00552427], Count: 0, Index: -121
Bucket: [0.00552427, 0.00576885], Count: 0, Index: -120
Bucket: [0.00576885, 0.00602426], Count: 1, Index: -119
Bucket: [0.00602426, 0.00629098], Count: 0, Index: -118
Bucket: [0.00629098, 0.0065695], Count: 0, Index: -117
Bucket: [0.0065695, 0.00686036], Count: 0, Index: -116
Bucket: [0.00686036, 0.00716409], Count: 0, Index: -115
Bucket: [0.00716409, 0.00748128], Count: 0, Index: -114
Bucket: [0.00748128, 0.0078125], Count: 0, Index: -113
Bucket: [0.0078125, 0.00815839], Count: 1, Index: -112
Bucket: [0.00815839, 0.00851959], Count: 0, Index: -111
Bucket: [0.00851959, 0.00889679], Count: 0, Index: -110
Bucket: [0.00889679, 0.00929068], Count: 0, Index: -109
Bucket: [0.00929068, 0.00970201], Count: 0, Index: -108
Bucket: [0.00970201, 0.01013156], Count: 0, Index: -107
Bucket: [0.01013156, 0.01058012], Count: 0, Index: -106
Bucket: [0.01058012, 0.01104854], Count: 0, Index: -105
Bucket: [0.01104854, 0.0115377], Count: 0, Index: -104
Bucket: [0.0115377, 0.01204852], Count: 0, Index: -103
Bucket: [0.01204852, 0.01258196], Count: 0, Index: -102
Bucket: [0.01258196, 0.01313901], Count: 0, Index: -101
Bucket: [0.01313901, 0.01372072], Count: 0, Index: -100
Bucket: [0.01372072, 0.01432819], Count: 0, Index: -99
Bucket: [0.01432819, 0.01496255], Count: 0, Index: -98
Bucket: [0.01496255, 0.015625], Count: 0, Index: -97
Bucket: [0.015625, 0.01631678], Count: 0, Index: -96
Bucket: [0.01631678, 0.01703918], Count: 0, Index: -95
Bucket: [0.01703918, 0.01779357], Count: 0, Index: -94
Bucket: [0.01779357, 0.01858136], Count: 0, Index: -93
Bucket: [0.01858136, 0.01940403], Count: 0, Index: -92
Bucket: [0.01940403, 0.02026312], Count: 0, Index: -91
Bucket: [0.02026312, 0.02116024], Count: 0, Index: -90
Bucket: [0.02116024, 0.02209709], Count: 0, Index: -89
Bucket: [0.02209709, 0.02307541], Count: 0, Index: -88
Bucket: [0.02307541, 0.02409704], Count: 0, Index: -87
Bucket: [0.02409704, 0.02516391], Count: 0, Index: -86
Bucket: [0.02516391, 0.02627801], Count: 0, Index: -85
Bucket: [0.02627801, 0.02744144], Count: 0, Index: -84
Bucket: [0.02744144, 0.02865638], Count: 0, Index: -83
Bucket: [0.02865638, 0.0299251], Count: 0, Index: -82
Bucket: [0.0299251, 0.03125], Count: 0, Index: -81
Bucket: [0.03125, 0.03263356], Count: 0, Index: -80
Bucket: [0.03263356, 0.03407837], Count: 0, Index: -79
Bucket: [0.03407837, 0.03558714], Count: 0, Index: -78
Bucket: [0.03558714, 0.03716272], Count: 0, Index: -77
Bucket: [0.03716272, 0.03880806], Count: 0, Index: -76
Bucket: [0.03880806, 0.04052624], Count: 0, Index: -75
Bucket: [0.04052624, 0.04232049], Count: 0, Index: -74
Bucket: [0.04232049, 0.04419417], Count: 0, Index: -73
Bucket: [0.04419417, 0.04615082], Count: 0, Index: -72
Bucket: [0.04615082, 0.04819409], Count: 0, Index: -71
Bucket: [0.04819409, 0.05032782], Count: 0, Index: -70
Bucket: [0.05032782, 0.05255603], Count: 0, Index: -69
Bucket: [0.05255603, 0.05488288], Count: 0, Index: -68
Bucket: [0.05488288, 0.05731275], Count: 0, Index: -67
Bucket: [0.05731275, 0.05985021], Count: 0, Index: -66
Bucket: [0.05985021, 0.0625], Count: 0, Index: -65
Bucket: [0.0625, 0.06526711], Count: 0, Index: -64
Bucket: [0.06526711, 0.06815673], Count: 0, Index: -63
Bucket: [0.06815673, 0.07117429], Count: 0, Index: -62
Bucket: [0.07117429, 0.07432544], Count: 0, Index: -61
Bucket: [0.07432544, 0.07761611], Count: 0, Index: -60
Bucket: [0.07761611, 0.08105247], Count: 0, Index: -59
Bucket: [0.08105247, 0.08464097], Count: 0, Index: -58
Bucket: [0.08464097, 0.08838835], Count: 0, Index: -57
Bucket: [0.08838835, 0.09230163], Count: 0, Index: -56
Bucket: [0.09230163, 0.09638818], Count: 0, Index: -55
Bucket: [0.09638818, 0.10065565], Count: 0, Index: -54
Bucket: [0.10065565, 0.10511205], Count: 0, Index: -53
Bucket: [0.10511205, 0.10976576], Count: 0, Index: -52
Bucket: [0.10976576, 0.11462551], Count: 0, Index: -51
Bucket: [0.11462551, 0.11970041], Count: 0, Index: -50
Bucket: [0.11970041, 0.125], Count: 1, Index: -49

merge: previous
scale: 3
count: 86
zero count: 1
min: 0
max: 0.205
sum: 1.288
Bucket: [0.00097656, 0.00106495], Count: 29, Index: -80
Bucket: [0.00106495, 0.00116134], Count: 0, Index: -79
Bucket: [0.00116134, 0.00126644], Count: 0, Index: -78
Bucket: [0.00126644, 0.00138107], Count: 0, Index: -77
Bucket: [0.00138107, 0.00150607], Count: 0, Index: -76
Bucket: [0.00150607, 0.00164238], Count: 0, Index: -75
Bucket: [0.00164238, 0.00179102], Count: 0, Index: -74
Bucket: [0.00179102, 0.00195313], Count: 0, Index: -73
Bucket: [0.00195313, 0.0021299], Count: 14, Index: -72
Bucket: [0.0021299, 0.00232267], Count: 0, Index: -71
Bucket: [0.00232267, 0.00253289], Count: 0, Index: -70
Bucket: [0.00253289, 0.00276214], Count: 0, Index: -69
Bucket: [0.00276214, 0.00301213], Count: 10, Index: -68
Bucket: [0.00301213, 0.00328475], Count: 0, Index: -67
Bucket: [0.00328475, 0.00358205], Count: 0, Index: -66
Bucket: [0.00358205, 0.00390625], Count: 0, Index: -65
Bucket: [0.00390625, 0.0042598], Count: 2, Index: -64
Bucket: [0.0042598, 0.00464534], Count: 0, Index: -63
Bucket: [0.00464534, 0.00506578], Count: 3, Index: -62
Bucket: [0.00506578, 0.00552427], Count: 0, Index: -61
Bucket: [0.00552427, 0.00602426], Count: 0, Index: -60
Bucket: [0.00602426, 0.0065695], Count: 0, Index: -59
Bucket: [0.0065695, 0.00716409], Count: 1, Index: -58
Bucket: [0.00716409, 0.0078125], Count: 0, Index: -57
Bucket: [0.0078125, 0.00851959], Count: 2, Index: -56
Bucket: [0.00851959, 0.00929068], Count: 0, Index: -55
Bucket: [0.00929068, 0.01013156], Count: 0, Index: -54
Bucket: [0.01013156, 0.01104854], Count: 0, Index: -53
Bucket: [0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: [0.01204852, 0.01313901], Count: 0, Index: -51
Bucket: [0.01313901, 0.01432819], Count: 0, Index: -50
Bucket: [0.01432819, 0.015625], Count: 0, Index: -49
Bucket: [0.015625, 0.01703918], Count: 0, Index: -48
Bucket: [0.01703918, 0.01858136], Count: 0, Index: -47
Bucket: [0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: [0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: [0.02209709, 0.02409704], Count: 0, Index: -44
Bucket: [0.02409704, 0.02627801], Count: 0, Index: -43
Bucket: [0.02627801, 0.02865638], Count: 0, Index: -42
Bucket: [0.02865638, 0.03125], Count: 2, Index: -41
Bucket: [0.03125, 0.03407837], Count: 0, Index: -40
Bucket: [0.03407837, 0.03716272], Count: 0, Index: -39
Bucket: [0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: [0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: [0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: [0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: [0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: [0.05731275, 0.0625], Count: 1, Index: -33
Bucket: [0.0625, 0.06815673], Count: 0, Index: -32
Bucket: [0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: [0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: [0.08105247, 0.08838835], Count: 0, Index: -29
Bucket: [0.08838835, 0.09638818], Count: 0, Index: -28
Bucket: [0.09638818, 0.10511205], Count: 0, Index: -27
Bucket: [0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: [0.11462551, 0.125], Count: 0, Index: -25
Bucket: [0.125, 0.13631347], Count: 0, Index: -24
Bucket: [0.13631347, 0.14865089], Count: 0, Index: -23
Bucket: [0.14865089, 0.16210494], Count: 0, Index: -22
Bucket: [0.16210494, 0.1767767], Count: 0, Index: -21
Bucket: [0.1767767, 0.19277635], Count: 0, Index: -20
Bucket: [0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: [0.2102241, 0.22925101], Count: 0, Index: -18
Bucket: [0.22925101, 0.25], Count: 0, Index: -17
Bucket: [0.25, 0.27262693], Count: 0, Index: -16
Bucket: [0.27262693, 0.29730178], Count: 0, Index: -15
Bucket: [0.29730178, 0.32420989], Count: 0, Index: -14
Bucket: [0.32420989, 0.35355339], Count: 0, Index: -13
Bucket: [0.35355339, 0.38555271], Count: 0, Index: -12
Bucket: [0.38555271, 0.42044821], Count: 0, Index: -11
Bucket: [0.42044821, 0.45850202], Count: 0, Index: -10
Bucket: [0.45850202, 0.5], Count: 0, Index: -9
Bucket: [0.5, 0.54525387], Count: 0, Index: -8
Bucket: [0.54525387, 0.59460356], Count: 0, Index: -7
Bucket: [0.59460356, 0.64841978], Count: 0, Index: -6
Bucket: [0.64841978, 0.70710678], Count: 0, Index: -5
Bucket: [0.70710678, 0.77110541], Count: 0, Index: -4
Bucket: [0.77110541, 0.84089642], Count: 0, Index: -3
Bucket: [0.84089642, 0.91700404], Count: 0, Index: -2
Bucket: [0.91700404, 1], Count: 0, Index: -1
Bucket: [1, 1.09050773], Count: 9, Index: 0

merge: result
scale: 3
count: 97
zero count: 1
min: 0
max: 0.205
sum: 1.448
Bucket: [0.00097656, 0.00106495], Count: 31, Index: -80
Bucket: [0.00106495, 0.00116134], Count: 0, Index: -79
Bucket: [0.00116134, 0.00126644], Count: 0, Index: -78
Bucket: [0.00126644, 0.00138107], Count: 0, Index: -77
Bucket: [0.00138107, 0.00150607], Count: 0, Index: -76
Bucket: [0.00150607, 0.00164238], Count: 0, Index: -75
Bucket: [0.00164238, 0.00179102], Count: 0, Index: -74
Bucket: [0.00179102, 0.00195313], Count: 0, Index: -73
Bucket: [0.00195313, 0.0021299], Count: 16, Index: -72
Bucket: [0.0021299, 0.00232267], Count: 0, Index: -71
Bucket: [0.00232267, 0.00253289], Count: 0, Index: -70
Bucket: [0.00253289, 0.00276214], Count: 0, Index: -69
Bucket: [0.00276214, 0.00301213], Count: 12, Index: -68
Bucket: [0.00301213, 0.00328475], Count: 0, Index: -67
Bucket: [0.00328475, 0.00358205], Count: 0, Index: -66
Bucket: [0.00358205, 0.00390625], Count: 0, Index: -65
Bucket: [0.00390625, 0.0042598], Count: 3, Index: -64
Bucket: [0.0042598, 0.00464534], Count: 0, Index: -63
Bucket: [0.00464534, 0.00506578], Count: 4, Index: -62
Bucket: [0.00506578, 0.00552427], Count: 0, Index: -61
Bucket: [0.00552427, 0.00602426], Count: 1, Index: -60
Bucket: [0.00602426, 0.0065695], Count: 0, Index: -59
Bucket: [0.0065695, 0.00716409], Count: 1, Index: -58
Bucket: [0.00716409, 0.0078125], Count: 0, Index: -57
Bucket: [0.0078125, 0.00851959], Count: 3, Index: -56
Bucket: [0.00851959, 0.00929068], Count: 0, Index: -55
Bucket: [0.00929068, 0.01013156], Count: 0, Index: -54
Bucket: [0.01013156, 0.01104854], Count: 0, Index: -53
Bucket: [0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: [0.01204852, 0.01313901], Count: 0, Index: -51
Bucket: [0.01313901, 0.01432819], Count: 0, Index: -50
Bucket: [0.01432819, 0.015625], Count: 0, Index: -49
Bucket: [0.015625, 0.01703918], Count: 0, Index: -48
Bucket: [0.01703918, 0.01858136], Count: 0, Index: -47
Bucket: [0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: [0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: [0.02209709, 0.02409704], Count: 0, Index: -44
Bucket: [0.02409704, 0.02627801], Count: 0, Index: -43
Bucket: [0.02627801, 0.02865638], Count: 0, Index: -42
Bucket: [0.02865638, 0.03125], Count: 2, Index: -41
Bucket: [0.03125, 0.03407837], Count: 0, Index: -40
Bucket: [0.03407837, 0.03716272], Count: 0, Index: -39
Bucket: [0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: [0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: [0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: [0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: [0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: [0.05731275, 0.0625], Count: 1, Index: -33
Bucket: [0.0625, 0.06815673], Count: 0, Index: -32
Bucket: [0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: [0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: [0.08105247, 0.08838835], Count: 0, Index: -29
Bucket: [0.08838835, 0.09638818], Count: 0, Index: -28
Bucket: [0.09638818, 0.10511205], Count: 0, Index: -27
Bucket: [0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: [0.11462551, 0.125], Count: 1, Index: -25
Bucket: [0.125, 0.13631347], Count: 0, Index: -24
Bucket: [0.13631347, 0.14865089], Count: 0, Index: -23
Bucket: [0.14865089, 0.16210494], Count: 0, Index: -22
Bucket: [0.16210494, 0.1767767], Count: 0, Index: -21
Bucket: [0.1767767, 0.19277635], Count: 0, Index: -20
Bucket: [0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: [0.2102241, 0.22925101], Count: 0, Index: -18
Bucket: [0.22925101, 0.25], Count: 0, Index: -17
Bucket: [0.25, 0.27262693], Count: 0, Index: -16
Bucket: [0.27262693, 0.29730178], Count: 0, Index: -15
Bucket: [0.29730178, 0.32420989], Count: 0, Index: -14
Bucket: [0.32420989, 0.35355339], Count: 0, Index: -13
Bucket: [0.35355339, 0.38555271], Count: 0, Index: -12
Bucket: [0.38555271, 0.42044821], Count: 0, Index: -11
Bucket: [0.42044821, 0.45850202], Count: 0, Index: -10
Bucket: [0.45850202, 0.5], Count: 0, Index: -9
Bucket: [0.5, 0.54525387], Count: 0, Index: -8
Bucket: [0.54525387, 0.59460356], Count: 0, Index: -7
Bucket: [0.59460356, 0.64841978], Count: 0, Index: -6
Bucket: [0.64841978, 0.70710678], Count: 0, Index: -5
Bucket: [0.70710678, 0.77110541], Count: 0, Index: -4
Bucket: [0.77110541, 0.84089642], Count: 0, Index: -3
Bucket: [0.84089642, 0.91700404], Count: 0, Index: -2
Bucket: [0.91700404, 1], Count: 0, Index: -1
Bucket: [1, 1.09050773], Count: 9, Index: 0

In the data provided, delta had a count of 11, which matched its bucket count. Previous had a count of 86, and a zero count of 1. It does not match the expected bucket count (including the zero count) of 95. The count for result was off because of this. Your data showed a count of 97 when the bucket count (including zero count) should be 106.

I filtered out the buckets with 0 items to make processing them easier (more on this soon). I copied the relevant lines and ran pbpaste | grep --invert-match "Count: 0". This gave me:

delta

Bucket: [0.00097656, 0.0010198], Count: 2, Index: -160
Bucket: [0.00195313, 0.0020396], Count: 2, Index: -144
Bucket: [0.00288443, 0.00301213], Count: 2, Index: -135
Bucket: [0.00390625, 0.00407919], Count: 1, Index: -128
Bucket: [0.00485101, 0.00506578], Count: 1, Index: -123
Bucket: [0.00576885, 0.00602426], Count: 1, Index: -119
Bucket: [0.0078125, 0.00815839], Count: 1, Index: -112
Bucket: [0.11970041, 0.125], Count: 1, Index: -49

previous

Bucket: [0.00097656, 0.00106495], Count: 29, Index: -80
Bucket: [0.00195313, 0.0021299], Count: 14, Index: -72
Bucket: [0.00276214, 0.00301213], Count: 10, Index: -68
Bucket: [0.00390625, 0.0042598], Count: 2, Index: -64
Bucket: [0.00464534, 0.00506578], Count: 3, Index: -62
Bucket: [0.0065695, 0.00716409], Count: 1, Index: -58
Bucket: [0.0078125, 0.00851959], Count: 2, Index: -56
Bucket: [0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: [0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: [0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: [0.02865638, 0.03125], Count: 2, Index: -41
Bucket: [0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: [0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: [0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: [0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: [0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: [0.05731275, 0.0625], Count: 1, Index: -33
Bucket: [0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: [0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: [0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: [0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: [1, 1.09050773], Count: 9, Index: 0

result

Bucket: [0.00097656, 0.00106495], Count: 31, Index: -80
Bucket: [0.00195313, 0.0021299], Count: 16, Index: -72
Bucket: [0.00276214, 0.00301213], Count: 12, Index: -68
Bucket: [0.00390625, 0.0042598], Count: 3, Index: -64
Bucket: [0.00464534, 0.00506578], Count: 4, Index: -62
Bucket: [0.00552427, 0.00602426], Count: 1, Index: -60
Bucket: [0.0065695, 0.00716409], Count: 1, Index: -58
Bucket: [0.0078125, 0.00851959], Count: 3, Index: -56
Bucket: [0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: [0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: [0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: [0.02865638, 0.03125], Count: 2, Index: -41
Bucket: [0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: [0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: [0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: [0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: [0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: [0.05731275, 0.0625], Count: 1, Index: -33
Bucket: [0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: [0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: [0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: [0.11462551, 0.125], Count: 1, Index: -25
Bucket: [0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: [1, 1.09050773], Count: 9, Index: 0

I then converted these into histograms to use in a mocha test case. Since I don't have the exact values available, I picked values that are just inside the range for each bucket. This will give us histograms with the same scale, same buckets, and same counts in each bucket, but slightly different values for max, min, and sum. This test case is available in a branch here: main...mwear:opentelemetry-js:expohisto-debug, but I'll paste it below for the purpose of discussion.

import {
  ExponentialHistogramAccumulation,
} from '../../src/aggregator/ExponentialHistogram';
import * as assert from 'assert';

describe('debug', () => {
  it.only('attempts to repro', () => {
    const delta = new ExponentialHistogramAccumulation([0, 0], 160);
    delta.updateByIncrement(0.000979, 2); // Bucket: [0.00097656, 0.0010198], Count: 2, Index: -160
    delta.updateByIncrement(0.001959, 2); // Bucket: [0.00195313, 0.0020396], Count: 2, Index: -144
    delta.updateByIncrement(0.002889, 2); // Bucket: [0.00288443, 0.00301213], Count: 2, Index: -135
    delta.updateByIncrement(0.003909, 1); // Bucket: [0.00390625, 0.00407919], Count: 1, Index: -128
    delta.updateByIncrement(0.004859, 1); // Bucket: [0.00485101, 0.00506578], Count: 1, Index: -123
    delta.updateByIncrement(0.005769, 1); // Bucket: [0.00576885, 0.00602426], Count: 1, Index: -119
    delta.updateByIncrement(0.007819, 1); // Bucket: [0.0078125, 0.00815839], Count: 1, Index: -112
    delta.updateByIncrement(0.119709, 1); // Bucket: [0.11970041, 0.125], Count: 1, Index: -49

    console.log('delta');
    delta.printBuckets();

    const previous = new ExponentialHistogramAccumulation([0, 0], 160);
    previous.updateByIncrement(0, 1);
    previous.updateByIncrement(0.000979, 29); // Bucket: [0.00097656, 0.00106495], Count: 29, Index: -80
    previous.updateByIncrement(0.001959, 14); // Bucket: [0.00195313, 0.0021299], Count: 14, Index: -72
    previous.updateByIncrement(0.002769, 10); // Bucket: [0.00276214, 0.00301213], Count: 10, Index: -68
    previous.updateByIncrement(0.003909, 2);  // Bucket: [0.00390625, 0.0042598], Count: 2, Index: -64
    previous.updateByIncrement(0.004649, 3);  // Bucket: [0.00464534, 0.00506578], Count: 3, Index: -62
    previous.updateByIncrement(0.006569, 1);  // Bucket: [0.0065695, 0.00716409], Count: 1, Index: -58
    previous.updateByIncrement(0.007819, 2);  // Bucket: [0.0078125, 0.00851959], Count: 2, Index: -56
    previous.updateByIncrement(0.011049, 1);  // Bucket: [0.01104854, 0.01204852], Count: 1, Index: -52
    previous.updateByIncrement(0.018589, 3);  // Bucket: [0.01858136, 0.02026312], Count: 3, Index: -46
    previous.updateByIncrement(0.020269, 5);  // Bucket: [0.02026312, 0.02209709], Count: 5, Index: -45
    previous.updateByIncrement(0.028659, 2);  // Bucket: [0.02865638, 0.03125], Count: 2, Index: -41
    previous.updateByIncrement(0.037169, 2);  // Bucket: [0.03716272, 0.04052624], Count: 2, Index: -38
    previous.updateByIncrement(0.040529, 1);  // Bucket: [0.04052624, 0.04419417], Count: 1, Index: -37
    previous.updateByIncrement(0.044199, 1);  // Bucket: [0.04419417, 0.04819409], Count: 1, Index: -36
    previous.updateByIncrement(0.048199, 1);  // Bucket: [0.04819409, 0.05255603], Count: 1, Index: -35
    previous.updateByIncrement(0.052559, 2);  // Bucket: [0.05255603, 0.05731275], Count: 2, Index: -34
    previous.updateByIncrement(0.057319, 1);  // Bucket: [0.05731275, 0.0625], Count: 1, Index: -33
    previous.updateByIncrement(0.068159, 2);  // Bucket: [0.06815673, 0.07432544], Count: 2, Index: -31
    previous.updateByIncrement(0.074329, 1);  // Bucket: [0.07432544, 0.08105247], Count: 1, Index: -30
    previous.updateByIncrement(0.105119, 1);  // Bucket: [0.10511205, 0.11462551], Count: 1, Index: -26
    previous.updateByIncrement(0.192779, 1);  // Bucket: [0.19277635, 0.2102241], Count: 1, Index: -19
    previous.updateByIncrement(1.010000, 9);  // Bucket: [1, 1.09050773], Count: 9, Index: 0

    console.log('previous');
    previous.printBuckets();

    const result = delta.clone();
    result.merge(previous);

    console.log('result')
    result.printBuckets();

    assert.equal(result.count, delta.count + previous.count);
    assert.equal(result.count, bucketCounts(result));
    assert.equal(delta.count, bucketCounts(delta));
    assert.equal(previous.count, bucketCounts(previous));
    assert.equal(bucketCounts(result), bucketCounts(delta) + bucketCounts(previous));
  })
});

function bucketCounts(histo: ExponentialHistogramAccumulation): number {
  // zero counts do not get a dedicated bucket, but they are part of the overall
  // histogram count
  return histo.toPointValue().positive.bucketCounts.reduce(
    (total, current) => total += current,
    histo.zeroCount
  );
}

In this test case, the counts were the expected counts, and did not show discrepancies from your original data. The output from the test is below:

delta
scale: 4
count: 11
zero count: 0
min: 0.000979
max: 0.119709
sum: 0.153719
Bucket: (0.00097656, 0.0010198], Count: 2, Index: -160
Bucket: (0.0010198, 0.00106495], Count: 0, Index: -159
Bucket: (0.00106495, 0.0011121], Count: 0, Index: -158
Bucket: (0.0011121, 0.00116134], Count: 0, Index: -157
Bucket: (0.00116134, 0.00121275], Count: 0, Index: -156
Bucket: (0.00121275, 0.00126644], Count: 0, Index: -155
Bucket: (0.00126644, 0.00132252], Count: 0, Index: -154
Bucket: (0.00132252, 0.00138107], Count: 0, Index: -153
Bucket: (0.00138107, 0.00144221], Count: 0, Index: -152
Bucket: (0.00144221, 0.00150607], Count: 0, Index: -151
Bucket: (0.00150607, 0.00157274], Count: 0, Index: -150
Bucket: (0.00157274, 0.00164238], Count: 0, Index: -149
Bucket: (0.00164238, 0.00171509], Count: 0, Index: -148
Bucket: (0.00171509, 0.00179102], Count: 0, Index: -147
Bucket: (0.00179102, 0.00187032], Count: 0, Index: -146
Bucket: (0.00187032, 0.00195313], Count: 0, Index: -145
Bucket: (0.00195313, 0.0020396], Count: 2, Index: -144
Bucket: (0.0020396, 0.0021299], Count: 0, Index: -143
Bucket: (0.0021299, 0.0022242], Count: 0, Index: -142
Bucket: (0.0022242, 0.00232267], Count: 0, Index: -141
Bucket: (0.00232267, 0.0024255], Count: 0, Index: -140
Bucket: (0.0024255, 0.00253289], Count: 0, Index: -139
Bucket: (0.00253289, 0.00264503], Count: 0, Index: -138
Bucket: (0.00264503, 0.00276214], Count: 0, Index: -137
Bucket: (0.00276214, 0.00288443], Count: 0, Index: -136
Bucket: (0.00288443, 0.00301213], Count: 2, Index: -135
Bucket: (0.00301213, 0.00314549], Count: 0, Index: -134
Bucket: (0.00314549, 0.00328475], Count: 0, Index: -133
Bucket: (0.00328475, 0.00343018], Count: 0, Index: -132
Bucket: (0.00343018, 0.00358205], Count: 0, Index: -131
Bucket: (0.00358205, 0.00374064], Count: 0, Index: -130
Bucket: (0.00374064, 0.00390625], Count: 0, Index: -129
Bucket: (0.00390625, 0.00407919], Count: 1, Index: -128
Bucket: (0.00407919, 0.0042598], Count: 0, Index: -127
Bucket: (0.0042598, 0.00444839], Count: 0, Index: -126
Bucket: (0.00444839, 0.00464534], Count: 0, Index: -125
Bucket: (0.00464534, 0.00485101], Count: 0, Index: -124
Bucket: (0.00485101, 0.00506578], Count: 1, Index: -123
Bucket: (0.00506578, 0.00529006], Count: 0, Index: -122
Bucket: (0.00529006, 0.00552427], Count: 0, Index: -121
Bucket: (0.00552427, 0.00576885], Count: 0, Index: -120
Bucket: (0.00576885, 0.00602426], Count: 1, Index: -119
Bucket: (0.00602426, 0.00629098], Count: 0, Index: -118
Bucket: (0.00629098, 0.0065695], Count: 0, Index: -117
Bucket: (0.0065695, 0.00686036], Count: 0, Index: -116
Bucket: (0.00686036, 0.00716409], Count: 0, Index: -115
Bucket: (0.00716409, 0.00748128], Count: 0, Index: -114
Bucket: (0.00748128, 0.0078125], Count: 0, Index: -113
Bucket: (0.0078125, 0.00815839], Count: 1, Index: -112
Bucket: (0.00815839, 0.00851959], Count: 0, Index: -111
Bucket: (0.00851959, 0.00889679], Count: 0, Index: -110
Bucket: (0.00889679, 0.00929068], Count: 0, Index: -109
Bucket: (0.00929068, 0.00970201], Count: 0, Index: -108
Bucket: (0.00970201, 0.01013156], Count: 0, Index: -107
Bucket: (0.01013156, 0.01058012], Count: 0, Index: -106
Bucket: (0.01058012, 0.01104854], Count: 0, Index: -105
Bucket: (0.01104854, 0.0115377], Count: 0, Index: -104
Bucket: (0.0115377, 0.01204852], Count: 0, Index: -103
Bucket: (0.01204852, 0.01258196], Count: 0, Index: -102
Bucket: (0.01258196, 0.01313901], Count: 0, Index: -101
Bucket: (0.01313901, 0.01372072], Count: 0, Index: -100
Bucket: (0.01372072, 0.01432819], Count: 0, Index: -99
Bucket: (0.01432819, 0.01496255], Count: 0, Index: -98
Bucket: (0.01496255, 0.015625], Count: 0, Index: -97
Bucket: (0.015625, 0.01631678], Count: 0, Index: -96
Bucket: (0.01631678, 0.01703918], Count: 0, Index: -95
Bucket: (0.01703918, 0.01779357], Count: 0, Index: -94
Bucket: (0.01779357, 0.01858136], Count: 0, Index: -93
Bucket: (0.01858136, 0.01940403], Count: 0, Index: -92
Bucket: (0.01940403, 0.02026312], Count: 0, Index: -91
Bucket: (0.02026312, 0.02116024], Count: 0, Index: -90
Bucket: (0.02116024, 0.02209709], Count: 0, Index: -89
Bucket: (0.02209709, 0.02307541], Count: 0, Index: -88
Bucket: (0.02307541, 0.02409704], Count: 0, Index: -87
Bucket: (0.02409704, 0.02516391], Count: 0, Index: -86
Bucket: (0.02516391, 0.02627801], Count: 0, Index: -85
Bucket: (0.02627801, 0.02744144], Count: 0, Index: -84
Bucket: (0.02744144, 0.02865638], Count: 0, Index: -83
Bucket: (0.02865638, 0.0299251], Count: 0, Index: -82
Bucket: (0.0299251, 0.03125], Count: 0, Index: -81
Bucket: (0.03125, 0.03263356], Count: 0, Index: -80
Bucket: (0.03263356, 0.03407837], Count: 0, Index: -79
Bucket: (0.03407837, 0.03558714], Count: 0, Index: -78
Bucket: (0.03558714, 0.03716272], Count: 0, Index: -77
Bucket: (0.03716272, 0.03880806], Count: 0, Index: -76
Bucket: (0.03880806, 0.04052624], Count: 0, Index: -75
Bucket: (0.04052624, 0.04232049], Count: 0, Index: -74
Bucket: (0.04232049, 0.04419417], Count: 0, Index: -73
Bucket: (0.04419417, 0.04615082], Count: 0, Index: -72
Bucket: (0.04615082, 0.04819409], Count: 0, Index: -71
Bucket: (0.04819409, 0.05032782], Count: 0, Index: -70
Bucket: (0.05032782, 0.05255603], Count: 0, Index: -69
Bucket: (0.05255603, 0.05488288], Count: 0, Index: -68
Bucket: (0.05488288, 0.05731275], Count: 0, Index: -67
Bucket: (0.05731275, 0.05985021], Count: 0, Index: -66
Bucket: (0.05985021, 0.0625], Count: 0, Index: -65
Bucket: (0.0625, 0.06526711], Count: 0, Index: -64
Bucket: (0.06526711, 0.06815673], Count: 0, Index: -63
Bucket: (0.06815673, 0.07117429], Count: 0, Index: -62
Bucket: (0.07117429, 0.07432544], Count: 0, Index: -61
Bucket: (0.07432544, 0.07761611], Count: 0, Index: -60
Bucket: (0.07761611, 0.08105247], Count: 0, Index: -59
Bucket: (0.08105247, 0.08464097], Count: 0, Index: -58
Bucket: (0.08464097, 0.08838835], Count: 0, Index: -57
Bucket: (0.08838835, 0.09230163], Count: 0, Index: -56
Bucket: (0.09230163, 0.09638818], Count: 0, Index: -55
Bucket: (0.09638818, 0.10065565], Count: 0, Index: -54
Bucket: (0.10065565, 0.10511205], Count: 0, Index: -53
Bucket: (0.10511205, 0.10976576], Count: 0, Index: -52
Bucket: (0.10976576, 0.11462551], Count: 0, Index: -51
Bucket: (0.11462551, 0.11970041], Count: 0, Index: -50
Bucket: (0.11970041, 0.125], Count: 1, Index: -49

previous
scale: 3
count: 95
zero count: 1
min: 0
max: 1.01
sum: 10.321204999999999
Bucket: (0.00097656, 0.00106495], Count: 29, Index: -80
Bucket: (0.00106495, 0.00116134], Count: 0, Index: -79
Bucket: (0.00116134, 0.00126644], Count: 0, Index: -78
Bucket: (0.00126644, 0.00138107], Count: 0, Index: -77
Bucket: (0.00138107, 0.00150607], Count: 0, Index: -76
Bucket: (0.00150607, 0.00164238], Count: 0, Index: -75
Bucket: (0.00164238, 0.00179102], Count: 0, Index: -74
Bucket: (0.00179102, 0.00195313], Count: 0, Index: -73
Bucket: (0.00195313, 0.0021299], Count: 14, Index: -72
Bucket: (0.0021299, 0.00232267], Count: 0, Index: -71
Bucket: (0.00232267, 0.00253289], Count: 0, Index: -70
Bucket: (0.00253289, 0.00276214], Count: 0, Index: -69
Bucket: (0.00276214, 0.00301213], Count: 10, Index: -68
Bucket: (0.00301213, 0.00328475], Count: 0, Index: -67
Bucket: (0.00328475, 0.00358205], Count: 0, Index: -66
Bucket: (0.00358205, 0.00390625], Count: 0, Index: -65
Bucket: (0.00390625, 0.0042598], Count: 2, Index: -64
Bucket: (0.0042598, 0.00464534], Count: 0, Index: -63
Bucket: (0.00464534, 0.00506578], Count: 3, Index: -62
Bucket: (0.00506578, 0.00552427], Count: 0, Index: -61
Bucket: (0.00552427, 0.00602426], Count: 0, Index: -60
Bucket: (0.00602426, 0.0065695], Count: 1, Index: -59
Bucket: (0.0065695, 0.00716409], Count: 0, Index: -58
Bucket: (0.00716409, 0.0078125], Count: 0, Index: -57
Bucket: (0.0078125, 0.00851959], Count: 2, Index: -56
Bucket: (0.00851959, 0.00929068], Count: 0, Index: -55
Bucket: (0.00929068, 0.01013156], Count: 0, Index: -54
Bucket: (0.01013156, 0.01104854], Count: 0, Index: -53
Bucket: (0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: (0.01204852, 0.01313901], Count: 0, Index: -51
Bucket: (0.01313901, 0.01432819], Count: 0, Index: -50
Bucket: (0.01432819, 0.015625], Count: 0, Index: -49
Bucket: (0.015625, 0.01703918], Count: 0, Index: -48
Bucket: (0.01703918, 0.01858136], Count: 0, Index: -47
Bucket: (0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: (0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: (0.02209709, 0.02409704], Count: 0, Index: -44
Bucket: (0.02409704, 0.02627801], Count: 0, Index: -43
Bucket: (0.02627801, 0.02865638], Count: 0, Index: -42
Bucket: (0.02865638, 0.03125], Count: 2, Index: -41
Bucket: (0.03125, 0.03407837], Count: 0, Index: -40
Bucket: (0.03407837, 0.03716272], Count: 0, Index: -39
Bucket: (0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: (0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: (0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: (0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: (0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: (0.05731275, 0.0625], Count: 1, Index: -33
Bucket: (0.0625, 0.06815673], Count: 0, Index: -32
Bucket: (0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: (0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: (0.08105247, 0.08838835], Count: 0, Index: -29
Bucket: (0.08838835, 0.09638818], Count: 0, Index: -28
Bucket: (0.09638818, 0.10511205], Count: 0, Index: -27
Bucket: (0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: (0.11462551, 0.125], Count: 0, Index: -25
Bucket: (0.125, 0.13631347], Count: 0, Index: -24
Bucket: (0.13631347, 0.14865089], Count: 0, Index: -23
Bucket: (0.14865089, 0.16210494], Count: 0, Index: -22
Bucket: (0.16210494, 0.1767767], Count: 0, Index: -21
Bucket: (0.1767767, 0.19277635], Count: 0, Index: -20
Bucket: (0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: (0.2102241, 0.22925101], Count: 0, Index: -18
Bucket: (0.22925101, 0.25], Count: 0, Index: -17
Bucket: (0.25, 0.27262693], Count: 0, Index: -16
Bucket: (0.27262693, 0.29730178], Count: 0, Index: -15
Bucket: (0.29730178, 0.32420989], Count: 0, Index: -14
Bucket: (0.32420989, 0.35355339], Count: 0, Index: -13
Bucket: (0.35355339, 0.38555271], Count: 0, Index: -12
Bucket: (0.38555271, 0.42044821], Count: 0, Index: -11
Bucket: (0.42044821, 0.45850202], Count: 0, Index: -10
Bucket: (0.45850202, 0.5], Count: 0, Index: -9
Bucket: (0.5, 0.54525387], Count: 0, Index: -8
Bucket: (0.54525387, 0.59460356], Count: 0, Index: -7
Bucket: (0.59460356, 0.64841978], Count: 0, Index: -6
Bucket: (0.64841978, 0.70710678], Count: 0, Index: -5
Bucket: (0.70710678, 0.77110541], Count: 0, Index: -4
Bucket: (0.77110541, 0.84089642], Count: 0, Index: -3
Bucket: (0.84089642, 0.91700404], Count: 0, Index: -2
Bucket: (0.91700404, 1], Count: 0, Index: -1
Bucket: (1, 1.09050773], Count: 9, Index: 0

result
scale: 3
count: 106
zero count: 1
min: 0
max: 1.01
sum: 10.474924
Bucket: (0.00097656, 0.00106495], Count: 31, Index: -80
Bucket: (0.00106495, 0.00116134], Count: 0, Index: -79
Bucket: (0.00116134, 0.00126644], Count: 0, Index: -78
Bucket: (0.00126644, 0.00138107], Count: 0, Index: -77
Bucket: (0.00138107, 0.00150607], Count: 0, Index: -76
Bucket: (0.00150607, 0.00164238], Count: 0, Index: -75
Bucket: (0.00164238, 0.00179102], Count: 0, Index: -74
Bucket: (0.00179102, 0.00195313], Count: 0, Index: -73
Bucket: (0.00195313, 0.0021299], Count: 16, Index: -72
Bucket: (0.0021299, 0.00232267], Count: 0, Index: -71
Bucket: (0.00232267, 0.00253289], Count: 0, Index: -70
Bucket: (0.00253289, 0.00276214], Count: 0, Index: -69
Bucket: (0.00276214, 0.00301213], Count: 12, Index: -68
Bucket: (0.00301213, 0.00328475], Count: 0, Index: -67
Bucket: (0.00328475, 0.00358205], Count: 0, Index: -66
Bucket: (0.00358205, 0.00390625], Count: 0, Index: -65
Bucket: (0.00390625, 0.0042598], Count: 3, Index: -64
Bucket: (0.0042598, 0.00464534], Count: 0, Index: -63
Bucket: (0.00464534, 0.00506578], Count: 4, Index: -62
Bucket: (0.00506578, 0.00552427], Count: 0, Index: -61
Bucket: (0.00552427, 0.00602426], Count: 1, Index: -60
Bucket: (0.00602426, 0.0065695], Count: 1, Index: -59
Bucket: (0.0065695, 0.00716409], Count: 0, Index: -58
Bucket: (0.00716409, 0.0078125], Count: 0, Index: -57
Bucket: (0.0078125, 0.00851959], Count: 3, Index: -56
Bucket: (0.00851959, 0.00929068], Count: 0, Index: -55
Bucket: (0.00929068, 0.01013156], Count: 0, Index: -54
Bucket: (0.01013156, 0.01104854], Count: 0, Index: -53
Bucket: (0.01104854, 0.01204852], Count: 1, Index: -52
Bucket: (0.01204852, 0.01313901], Count: 0, Index: -51
Bucket: (0.01313901, 0.01432819], Count: 0, Index: -50
Bucket: (0.01432819, 0.015625], Count: 0, Index: -49
Bucket: (0.015625, 0.01703918], Count: 0, Index: -48
Bucket: (0.01703918, 0.01858136], Count: 0, Index: -47
Bucket: (0.01858136, 0.02026312], Count: 3, Index: -46
Bucket: (0.02026312, 0.02209709], Count: 5, Index: -45
Bucket: (0.02209709, 0.02409704], Count: 0, Index: -44
Bucket: (0.02409704, 0.02627801], Count: 0, Index: -43
Bucket: (0.02627801, 0.02865638], Count: 0, Index: -42
Bucket: (0.02865638, 0.03125], Count: 2, Index: -41
Bucket: (0.03125, 0.03407837], Count: 0, Index: -40
Bucket: (0.03407837, 0.03716272], Count: 0, Index: -39
Bucket: (0.03716272, 0.04052624], Count: 2, Index: -38
Bucket: (0.04052624, 0.04419417], Count: 1, Index: -37
Bucket: (0.04419417, 0.04819409], Count: 1, Index: -36
Bucket: (0.04819409, 0.05255603], Count: 1, Index: -35
Bucket: (0.05255603, 0.05731275], Count: 2, Index: -34
Bucket: (0.05731275, 0.0625], Count: 1, Index: -33
Bucket: (0.0625, 0.06815673], Count: 0, Index: -32
Bucket: (0.06815673, 0.07432544], Count: 2, Index: -31
Bucket: (0.07432544, 0.08105247], Count: 1, Index: -30
Bucket: (0.08105247, 0.08838835], Count: 0, Index: -29
Bucket: (0.08838835, 0.09638818], Count: 0, Index: -28
Bucket: (0.09638818, 0.10511205], Count: 0, Index: -27
Bucket: (0.10511205, 0.11462551], Count: 1, Index: -26
Bucket: (0.11462551, 0.125], Count: 1, Index: -25
Bucket: (0.125, 0.13631347], Count: 0, Index: -24
Bucket: (0.13631347, 0.14865089], Count: 0, Index: -23
Bucket: (0.14865089, 0.16210494], Count: 0, Index: -22
Bucket: (0.16210494, 0.1767767], Count: 0, Index: -21
Bucket: (0.1767767, 0.19277635], Count: 0, Index: -20
Bucket: (0.19277635, 0.2102241], Count: 1, Index: -19
Bucket: (0.2102241, 0.22925101], Count: 0, Index: -18
Bucket: (0.22925101, 0.25], Count: 0, Index: -17
Bucket: (0.25, 0.27262693], Count: 0, Index: -16
Bucket: (0.27262693, 0.29730178], Count: 0, Index: -15
Bucket: (0.29730178, 0.32420989], Count: 0, Index: -14
Bucket: (0.32420989, 0.35355339], Count: 0, Index: -13
Bucket: (0.35355339, 0.38555271], Count: 0, Index: -12
Bucket: (0.38555271, 0.42044821], Count: 0, Index: -11
Bucket: (0.42044821, 0.45850202], Count: 0, Index: -10
Bucket: (0.45850202, 0.5], Count: 0, Index: -9
Bucket: (0.5, 0.54525387], Count: 0, Index: -8
Bucket: (0.54525387, 0.59460356], Count: 0, Index: -7
Bucket: (0.59460356, 0.64841978], Count: 0, Index: -6
Bucket: (0.64841978, 0.70710678], Count: 0, Index: -5
Bucket: (0.70710678, 0.77110541], Count: 0, Index: -4
Bucket: (0.77110541, 0.84089642], Count: 0, Index: -3
Bucket: (0.84089642, 0.91700404], Count: 0, Index: -2
Bucket: (0.91700404, 1], Count: 0, Index: -1
Bucket: (1, 1.09050773], Count: 9, Index: 0

I think you are definitely on to something with your debug process, but you should update your logic to detect mismatched counts to add both the bucket counts and the zero count otherwise it will find false positives. My observation from this data, is that the previous histogram already has invalid counts before merging it with delta, which causes invalid counts in result. If this is reliably the case, we need to figure out how the previous histogram is getting corrupted. My guess is that this could be happening from an earlier merge, one where delta and previous have the correct counts, but result doesn't. If we can catch that in action, we could validate that's how the corruption occurs, and try to build a similar test case from the input data. If we can't find that happening, we'll have to explore other possibilities.

@kothariroshni8
Copy link
Author

@mwear Sorry for confusion. I shouldn't have edited the same comment.
I replaced the log because in my earlier log , previous value was already corrupted.
So I looked back in to logs and tried to find first occurrence of the issue.

Logs which I updated later is the first occurrence of issue.

@kothariroshni8
Copy link
Author

and Buckets are missing for Delta because ZeroCount is also equal to 2.

merge: delta
scale: 0
count: 2
zero count: 2
min: 0
max: 0
sum: 0

@kothariroshni8
Copy link
Author

@mwear Use below code to repro the error:

const delta = new ExponentialHistogramAccumulation([0, 0], 160);
        delta.updateByIncrement(0, 2); 
        console.log('delta');
        delta.printBuckets();
        const previous = new ExponentialHistogramAccumulation([0, 0], 160);
        previous.updateByIncrement(0, 2);
        previous.updateByIncrement(0.00097657,41);
        previous.updateByIncrement(0.00195313,17);
        previous.updateByIncrement(0.00288443, 1);
        previous.updateByIncrement(0.00390625, 1);
        previous.updateByIncrement(0.00485101, 2);
        previous.updateByIncrement(0.00889679, 1);
        previous.updateByIncrement(0.01858136, 1);
        previous.updateByIncrement(0.02026312, 2);
        previous.updateByIncrement(0.02116024, 3);
        previous.updateByIncrement(0.02307541, 2);
        previous.updateByIncrement(0.02516391, 2);
        previous.updateByIncrement(0.02627801, 1);
        previous.updateByIncrement(0.0299251,  2);
        previous.updateByIncrement(0.03125,    1);
        previous.updateByIncrement(0.03263356, 1);
        previous.updateByIncrement(0.03716272, 1);
        previous.updateByIncrement(0.03880806, 1);
        previous.updateByIncrement(0.04232049, 1);
        previous.updateByIncrement(0.04419417, 1);
        previous.updateByIncrement(0.04819409, 1);
        previous.updateByIncrement(0.06526711, 1);
        previous.updateByIncrement(0.09230163, 1);
        previous.updateByIncrement(0.10065565, 1);
        console.log('previous');
        previous.printBuckets();
        const result = delta.clone();
        result.merge(previous);

        console.log('result')
        result.printBuckets();

@mwear
Copy link
Member

mwear commented Feb 4, 2024

@kothariroshni8 thank you so much for your help. That does indeed repro and I have a tentative fix. I'll open a PR shortly. If you wanted to try this out early, I added a special case for a histogram with zero length buckets to _incrementIndexBy.

The lines I added were:

    if (buckets.length === 0) {
      buckets.indexStart = buckets.indexEnd = buckets.indexBase = index;
    }

The full function looks like this:

  private _incrementIndexBy(
    buckets: Buckets,
    index: number,
    increment: number
  ) {
    if (increment === 0) {
      // nothing to do for a zero increment, can happen during a merge operation
      return;
    }

    if (buckets.length === 0) {
      buckets.indexStart = buckets.indexEnd = buckets.indexBase = index;
    }

    if (index < buckets.indexStart) {
      const span = buckets.indexEnd - index;
      if (span >= buckets.backing.length) {
        this._grow(buckets, span + 1);
      }
      buckets.indexStart = index;
    } else if (index > buckets.indexEnd) {
      const span = index - buckets.indexStart;
      if (span >= buckets.backing.length) {
        this._grow(buckets, span + 1);
      }
      buckets.indexEnd = index;
    }

    let bucketIndex = index - buckets.indexBase;
    if (bucketIndex < 0) {
      bucketIndex += buckets.backing.length;
    }
    buckets.incrementBucket(bucketIndex, increment);
  }

@kothariroshni8
Copy link
Author

kothariroshni8 commented Feb 21, 2024

When you will release this fix? @pichlermarc @mwear

@pichlermarc
Copy link
Member

When you will release this fix? @pichlermarc @mwear

Aiming for next week. 🙂
There are few PRs left that should to make it in before I can open the release PR, sorry for the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants