diff --git a/info/v2/container.go b/info/v2/container.go index f0824027a3..7845fe4c48 100644 --- a/info/v2/container.go +++ b/info/v2/container.go @@ -200,6 +200,8 @@ type Percentiles struct { Ninety uint64 `json:"ninety"` // 95th percentile over the collected sample. NinetyFive uint64 `json:"ninetyfive"` + // Number of samples used to calculate these percentiles. + Count uint64 `json:"count"` } type Usage struct { diff --git a/summary/percentiles.go b/summary/percentiles.go index 8ce706ad9e..bca056e9f0 100644 --- a/summary/percentiles.go +++ b/summary/percentiles.go @@ -109,6 +109,7 @@ func (r *resource) AddSample(val uint64) { Fifty: val, Ninety: val, NinetyFive: val, + Count: 1, } r.Add(sample) } @@ -121,6 +122,8 @@ func (r *resource) GetAllPercentiles() info.Percentiles { p.Fifty = r.samples.GetPercentile(0.5) p.Ninety = r.samples.GetPercentile(0.9) p.NinetyFive = r.samples.GetPercentile(0.95) + // len(samples) is equal to count stored in mean. + p.Count = r.mean.count p.Present = true return p } diff --git a/summary/percentiles_test.go b/summary/percentiles_test.go index 4dbe3665d3..b4cf6206a5 100644 --- a/summary/percentiles_test.go +++ b/summary/percentiles_test.go @@ -84,6 +84,8 @@ func TestAggregates(t *testing.T) { Fifty: 1000, Ninety: 1000, NinetyFive: 1000, + // Since cpu is calculated between samples, we lose 1 sample. + Count: N - 2, } if usage.Cpu != cpuExpected { t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected) @@ -95,6 +97,7 @@ func TestAggregates(t *testing.T) { Fifty: 50 * 1024, Ninety: 90 * 1024, NinetyFive: 95 * 1024, + Count: N - 1, } if usage.Memory != memExpected { t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected) @@ -133,6 +136,8 @@ func TestSamplesCloseInTimeIgnored(t *testing.T) { Fifty: 1000, Ninety: 1000, NinetyFive: 1000, + // Since cpu is calculated between samples, we lose 1 sample. + Count: N - 2, } if usage.Cpu != cpuExpected { t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected) @@ -144,6 +149,7 @@ func TestSamplesCloseInTimeIgnored(t *testing.T) { Fifty: 50 * 1024, Ninety: 90 * 1024, NinetyFive: 95 * 1024, + Count: N - 1, } if usage.Memory != memExpected { t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected) @@ -184,6 +190,8 @@ func TestDerivedStats(t *testing.T) { Fifty: 50 * Nanosecond, Ninety: 90 * Nanosecond, NinetyFive: 95 * Nanosecond, + // GetDerivedPercentiles calculates directly from samples, hence we don't lose any samples. + Count: N - 1, } if usage.Cpu != cpuExpected { t.Errorf("cpu stats are %+v. Expected %+v", usage.Cpu, cpuExpected) @@ -195,6 +203,7 @@ func TestDerivedStats(t *testing.T) { Fifty: 50 * 1024, Ninety: 90 * 1024, NinetyFive: 95 * 1024, + Count: N - 1, } if usage.Memory != memExpected { t.Errorf("memory stats are mean %+v. Expected %+v", usage.Memory, memExpected)