Head Cardinality Status Page (#6125)
* Adding TSDB Head Stats like cardinality to Status Page Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Moving mutx to Head Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Renaming variabls Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Renaming variabls and html Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Removing unwanted whitespaces Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding Tests, Banchmarks and Max Heap for Postings Stats Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding more tests for postingstats and web handler Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding more tests for postingstats and web handler Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Remove generated asset file that is no longer used Signed-off-by: Chris Marchbanks <csmarchbanks@gmail.com> * Changing comment and variable name for more readability Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Using time.Duration in postings status function and removing refresh button from web page Signed-off-by: Sharad Gaur <sgaur@splunk.com>pull/6273/head
parent
1a38075f83
commit
e94503ff5c
@ -0,0 +1,69 @@ |
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package index |
||||||
|
|
||||||
|
import ( |
||||||
|
"math" |
||||||
|
"sort" |
||||||
|
) |
||||||
|
|
||||||
|
// Stat holds values for a single cardinality statistic.
|
||||||
|
type Stat struct { |
||||||
|
Name string |
||||||
|
Count uint64 |
||||||
|
} |
||||||
|
|
||||||
|
type maxHeap struct { |
||||||
|
maxLength int |
||||||
|
minValue uint64 |
||||||
|
minIndex int |
||||||
|
Items []Stat |
||||||
|
} |
||||||
|
|
||||||
|
func (m *maxHeap) init(len int) { |
||||||
|
m.maxLength = len |
||||||
|
m.minValue = math.MaxUint64 |
||||||
|
m.Items = make([]Stat, 0, len) |
||||||
|
} |
||||||
|
|
||||||
|
func (m *maxHeap) push(item Stat) { |
||||||
|
if len(m.Items) < m.maxLength { |
||||||
|
if item.Count < m.minValue { |
||||||
|
m.minValue = item.Count |
||||||
|
m.minIndex = len(m.Items) |
||||||
|
} |
||||||
|
m.Items = append(m.Items, item) |
||||||
|
return |
||||||
|
} |
||||||
|
if item.Count < m.minValue { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
m.Items[m.minIndex] = item |
||||||
|
m.minValue = item.Count |
||||||
|
|
||||||
|
for i, stat := range m.Items { |
||||||
|
if stat.Count < m.minValue { |
||||||
|
m.minValue = stat.Count |
||||||
|
m.minIndex = i |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
func (m *maxHeap) get() []Stat { |
||||||
|
sort.Slice(m.Items, func(i, j int) bool { |
||||||
|
return m.Items[i].Count > m.Items[j].Count |
||||||
|
}) |
||||||
|
return m.Items |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
// Copyright 2019 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package index |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/util/testutil" |
||||||
|
) |
||||||
|
|
||||||
|
func TestPostingsStats(t *testing.T) { |
||||||
|
stats := &maxHeap{} |
||||||
|
max := 3000000 |
||||||
|
heapLength := 10 |
||||||
|
stats.init(heapLength) |
||||||
|
for i := 0; i < max; i++ { |
||||||
|
item := Stat{ |
||||||
|
Name: "Label-da", |
||||||
|
Count: uint64(i), |
||||||
|
} |
||||||
|
stats.push(item) |
||||||
|
} |
||||||
|
stats.push(Stat{Name: "Stuff", Count: 3000000}) |
||||||
|
|
||||||
|
data := stats.get() |
||||||
|
testutil.Equals(t, 10, len(data)) |
||||||
|
for i := 0; i < heapLength; i++ { |
||||||
|
fmt.Printf("%d", data[i].Count) |
||||||
|
testutil.Equals(t, uint64(max-i), data[i].Count) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
func TestPostingsStats2(t *testing.T) { |
||||||
|
stats := &maxHeap{} |
||||||
|
heapLength := 10 |
||||||
|
|
||||||
|
stats.init(heapLength) |
||||||
|
stats.push(Stat{Name: "Stuff", Count: 10}) |
||||||
|
stats.push(Stat{Name: "Stuff", Count: 11}) |
||||||
|
stats.push(Stat{Name: "Stuff", Count: 1}) |
||||||
|
stats.push(Stat{Name: "Stuff", Count: 6}) |
||||||
|
|
||||||
|
data := stats.get() |
||||||
|
|
||||||
|
testutil.Equals(t, 4, len(data)) |
||||||
|
testutil.Equals(t, uint64(11), data[0].Count) |
||||||
|
} |
||||||
|
func BenchmarkPostingStatsMaxHep(b *testing.B) { |
||||||
|
stats := &maxHeap{} |
||||||
|
max := 9000000 |
||||||
|
heapLength := 10 |
||||||
|
b.ResetTimer() |
||||||
|
for n := 0; n < b.N; n++ { |
||||||
|
stats.init(heapLength) |
||||||
|
for i := 0; i < max; i++ { |
||||||
|
item := Stat{ |
||||||
|
Name: "Label-da", |
||||||
|
Count: uint64(i), |
||||||
|
} |
||||||
|
stats.push(item) |
||||||
|
} |
||||||
|
stats.get() |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue