Repository: prometheus/prometheus
File: web/api/v1/api.go (Go)

Code before:
	NumLabelPairs int    `json:"numLabelPairs"`
	ChunkCount    int64  `json:"chunkCount"`
	MinTime       int64  `json:"minTime"`
	MaxTime       int64  `json:"maxTime"`
}

// TSDBStatus has information of cardinality statistics from postings.
type TSDBStatus struct {
	HeadStats                   HeadStats  `json:"headStats"`
	SeriesCountByMetricName     []TSDBStat `json:"seriesCountByMetricName"`
	LabelValueCountByLabelName  []TSDBStat `json:"labelValueCountByLabelName"`
	MemoryInBytesByLabelName    []TSDBStat `json:"memoryInBytesByLabelName"`
	SeriesCountByLabelValuePair []TSDBStat `json:"seriesCountByLabelValuePair"`
}

// TSDBStatsFromIndexStats converts a index.Stat slice to a TSDBStat slice.
func TSDBStatsFromIndexStats(stats []index.Stat) []TSDBStat {
	result := make([]TSDBStat, 0, len(stats))
	for _, item := range stats {
		item := TSDBStat{Name: item.Name, Value: item.Count}
		result = append(result, item)
	}
	return result
}

func (api *API) serveTSDBBlock(_ *http.Request) apiFuncResult {
	dirs, err := os.ReadDir(api.dbDir)
	if err != nil {
		return apiFuncResult{nil, &apiError{errorInternal, fmt.Errorf("read TSDB dir: %w", err)}, nil, nil}
	}

	var blocks []tsdb.BlockMeta

	for _, entry := range dirs {
		if !entry.IsDir() {
			continue
		}
		_, err := ulid.Parse(entry.Name())
		if err != nil {
			continue
		}

		blockPath := filepath.Join(api.dbDir, entry.Name())
		block, err := tsdb.OpenBlock(api.logger, blockPath, nil, nil)
		if err != nil {
			continue
		}
		meta := block.Meta()
		blocks = append(blocks, meta)
		defer block.Close()
	}

Review comment (suggestion):
```suggestion
func (api *API) serveTSDBBlocks(_ *http.Request) apiFuncResult {
```

Code after:
	NumLabelPairs int    `json:"numLabelPairs"`
	ChunkCount    int64  `json:"chunkCount"`
	MinTime       int64  `json:"minTime"`
	MaxTime       int64  `json:"maxTime"`
}

// TSDBStatus has information of cardinality statistics from postings.
type TSDBStatus struct {
	HeadStats                   HeadStats  `json:"headStats"`
	SeriesCountByMetricName     []TSDBStat `json:"seriesCountByMetricName"`
	LabelValueCountByLabelName  []TSDBStat `json:"labelValueCountByLabelName"`
	MemoryInBytesByLabelName    []TSDBStat `json:"memoryInBytesByLabelName"`
	SeriesCountByLabelValuePair []TSDBStat `json:"seriesCountByLabelValuePair"`
}

// TSDBStatsFromIndexStats converts a index.Stat slice to a TSDBStat slice.
func TSDBStatsFromIndexStats(stats []index.Stat) []TSDBStat {
	result := make([]TSDBStat, 0, len(stats))
	for _, item := range stats {
		item := TSDBStat{Name: item.Name, Value: item.Count}
		result = append(result, item)
	}
	return result
}

func (api *API) serveTSDBBlocks(_ *http.Request) apiFuncResult {
	blockMetas, err := api.db.BlockMetas()
	if err != nil {
		return apiFuncResult{nil, &apiError{errorInternal, fmt.Errorf("error getting block metadata: %w", err)}, nil, nil}
	}

	return apiFuncResult{
		data: map[string][]tsdb.BlockMeta{
			"blocks": blockMetas,
		},
	}
}

func (api *API) serveTSDBStatus(r *http.Request) apiFuncResult {
	limit := 10
	if s := r.FormValue("limit"); s != "" {
		var err error
		if limit, err = strconv.Atoi(s); err != nil || limit < 1 {
			return apiFuncResult{nil, &apiError{errorBadData, errors.New("limit must be a positive number")}, nil, nil}
		}
	}
	s, err := api.db.Stats(labels.MetricName, limit)
	if err != nil {
		return apiFuncResult{nil, &apiError{errorInternal, err}, nil, nil}
	}
	metrics, err := api.gatherer.Gather()