From cd1dafc2fd05deb24181a4eaa7852909749586f3 Mon Sep 17 00:00:00 2001 From: Nguyen Le Vu Long Date: Thu, 7 Jan 2021 13:41:32 +0700 Subject: [PATCH] tsdb: Expose total number of label pairs in head in TSDB stats page (#8343) * tsdb: Expose total number of label pairs in head Signed-off-by: Nguyen Le Vu Long * fix: add comment for NumLabelPairs Signed-off-by: Nguyen Le Vu Long * fix: remove comment Signed-off-by: Nguyen Le Vu Long --- tsdb/index/postings.go | 4 ++++ web/api/v1/api.go | 18 ++++++++++-------- .../src/pages/tsdbStatus/TSDBStatus.test.tsx | 3 ++- .../src/pages/tsdbStatus/TSDBStatus.tsx | 4 +++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go index 055f74118e..a9048e4c62 100644 --- a/tsdb/index/postings.go +++ b/tsdb/index/postings.go @@ -115,6 +115,7 @@ type PostingsStats struct { CardinalityLabelStats []Stat LabelValueStats []Stat LabelValuePairsStats []Stat + NumLabelPairs int } // Stats calculates the cardinality statistics from postings. @@ -128,6 +129,7 @@ func (p *MemPostings) Stats(label string) *PostingsStats { labels := &maxHeap{} labelValueLength := &maxHeap{} labelValuePairs := &maxHeap{} + numLabelPairs := 0 metrics.init(maxNumOfRecords) labels.init(maxNumOfRecords) @@ -139,6 +141,7 @@ func (p *MemPostings) Stats(label string) *PostingsStats { continue } labels.push(Stat{Name: n, Count: uint64(len(e))}) + numLabelPairs += len(e) size = 0 for name, values := range e { if n == label { @@ -157,6 +160,7 @@ func (p *MemPostings) Stats(label string) *PostingsStats { CardinalityLabelStats: labels.get(), LabelValueStats: labelValueLength.get(), LabelValuePairsStats: labelValuePairs.get(), + NumLabelPairs: numLabelPairs, } } diff --git a/web/api/v1/api.go b/web/api/v1/api.go index df5640d545..9963f52ec4 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -1236,10 +1236,11 @@ type stat struct { // HeadStats has information about the TSDB head. type HeadStats struct { - NumSeries uint64 `json:"numSeries"` - ChunkCount int64 `json:"chunkCount"` - MinTime int64 `json:"minTime"` - MaxTime int64 `json:"maxTime"` + NumSeries uint64 `json:"numSeries"` + NumLabelPairs int `json:"numLabelPairs"` + ChunkCount int64 `json:"chunkCount"` + MinTime int64 `json:"minTime"` + MaxTime int64 `json:"maxTime"` } // tsdbStatus has information of cardinality statistics from postings. @@ -1281,10 +1282,11 @@ func (api *API) serveTSDBStatus(*http.Request) apiFuncResult { } return apiFuncResult{tsdbStatus{ HeadStats: HeadStats{ - NumSeries: s.NumSeries, - ChunkCount: chunkCount, - MinTime: s.MinTime, - MaxTime: s.MaxTime, + NumSeries: s.NumSeries, + ChunkCount: chunkCount, + MinTime: s.MinTime, + MaxTime: s.MaxTime, + NumLabelPairs: s.IndexPostingStats.NumLabelPairs, }, SeriesCountByMetricName: convertStats(s.IndexPostingStats.CardinalityMetricsStats), LabelValueCountByLabelName: convertStats(s.IndexPostingStats.CardinalityLabelStats), diff --git a/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx b/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx index f8e360f4d8..f25c784275 100644 --- a/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx +++ b/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx @@ -15,6 +15,7 @@ const fakeTSDBStatusResponse: { data: { headStats: { numSeries: 508, + numLabelPairs: 1234, chunkCount: 937, minTime: 1591516800000, maxTime: 1598896800143, @@ -85,7 +86,7 @@ describe('TSDB Stats', () => { .at(0) .find('tbody') .find('td'); - ['508', '937', '2020-06-07T08:00:00.000Z (1591516800000)', '2020-08-31T18:00:00.143Z (1598896800143)'].forEach( + ['508', '937', '1234', '2020-06-07T08:00:00.000Z (1591516800000)', '2020-08-31T18:00:00.143Z (1598896800143)'].forEach( (value, i) => { expect(headStats.at(i).text()).toEqual(value); } diff --git a/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx b/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx index d5539ccf7b..c124d79213 100644 --- a/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx +++ b/web/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx @@ -14,6 +14,7 @@ interface Stats { interface HeadStats { numSeries: number; + numLabelPairs: number; chunkCount: number; minTime: number; maxTime: number; @@ -35,10 +36,11 @@ export const TSDBStatusContent: FC = ({ seriesCountByLabelValuePair, }) => { const unixToTime = (unix: number): string => new Date(unix).toISOString(); - const { chunkCount, numSeries, minTime, maxTime } = headStats; + const { chunkCount, numSeries, numLabelPairs, minTime, maxTime } = headStats; const stats = [ { header: 'Number of Series', value: numSeries }, { header: 'Number of Chunks', value: chunkCount }, + { header: 'Number of Label Pairs', value: numLabelPairs }, { header: 'Current Min Time', value: `${unixToTime(minTime)} (${minTime})` }, { header: 'Current Max Time', value: `${unixToTime(maxTime)} (${maxTime})` }, ];