mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
API: expose lowest TSDB timestamp in /api/v1/status/tsdb
Add information about the lowest timestamp in the TSDB to /api/v1/status/tsdb. This feature would be useful to have in Thanos so that the Thanos Sidecar can adjust its advertised range so we can more precisely prune endpoints during fan-out. Signed-off-by: Michael Hoffmann <mhoffm@posteo.de>
This commit is contained in:
parent
d1ea6eb35d
commit
2dcaa1511c
|
@ -1577,9 +1577,15 @@ type HeadStats struct {
|
|||
MaxTime int64 `json:"maxTime"`
|
||||
}
|
||||
|
||||
// TSDBStats has information about the TSDB.
|
||||
type TSDBStats struct {
|
||||
MinTime int64 `json:"minTime"`
|
||||
}
|
||||
|
||||
// TSDBStatus has information of cardinality statistics from postings.
|
||||
type TSDBStatus struct {
|
||||
HeadStats HeadStats `json:"headStats"`
|
||||
TSDBStats TSDBStats `json:"tsdbStats"`
|
||||
SeriesCountByMetricName []TSDBStat `json:"seriesCountByMetricName"`
|
||||
LabelValueCountByLabelName []TSDBStat `json:"labelValueCountByLabelName"`
|
||||
MemoryInBytesByLabelName []TSDBStat `json:"memoryInBytesByLabelName"`
|
||||
|
@ -1613,12 +1619,18 @@ func (api *API) serveTSDBStatus(r *http.Request) apiFuncResult {
|
|||
return apiFuncResult{nil, &apiError{errorInternal, fmt.Errorf("error gathering runtime status: %w", err)}, nil, nil}
|
||||
}
|
||||
chunkCount := int64(math.NaN())
|
||||
lowestTimestamp := int64(math.NaN())
|
||||
for _, mF := range metrics {
|
||||
if *mF.Name == "prometheus_tsdb_head_chunks" {
|
||||
switch *mF.Name {
|
||||
case "prometheus_tsdb_head_chunks":
|
||||
m := mF.Metric[0]
|
||||
if m.Gauge != nil {
|
||||
chunkCount = int64(m.Gauge.GetValue())
|
||||
break
|
||||
}
|
||||
case "prometheus_tsdb_lowest_timestamp":
|
||||
m := mF.Metric[0]
|
||||
if m.Gauge != nil {
|
||||
lowestTimestamp = int64(m.Gauge.GetValue())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1630,6 +1642,7 @@ func (api *API) serveTSDBStatus(r *http.Request) apiFuncResult {
|
|||
MaxTime: s.MaxTime,
|
||||
NumLabelPairs: s.IndexPostingStats.NumLabelPairs,
|
||||
},
|
||||
TSDBStats: TSDBStats{MinTime: lowestTimestamp},
|
||||
SeriesCountByMetricName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityMetricsStats),
|
||||
LabelValueCountByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityLabelStats),
|
||||
MemoryInBytesByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.LabelValueStats),
|
||||
|
|
|
@ -20,6 +20,9 @@ const fakeTSDBStatusResponse: {
|
|||
minTime: 1591516800000,
|
||||
maxTime: 1598896800143,
|
||||
},
|
||||
tsdbStats: {
|
||||
minTime: 1591516800000,
|
||||
},
|
||||
labelValueCountByLabelName: [
|
||||
{
|
||||
name: '__name__',
|
||||
|
@ -64,6 +67,9 @@ const fakeEmptyTSDBStatusResponse: {
|
|||
minTime: 9223372036854776000,
|
||||
maxTime: -9223372036854776000,
|
||||
},
|
||||
tsdbStats: {
|
||||
minTime: 9223372036854776000,
|
||||
},
|
||||
labelValueCountByLabelName: [],
|
||||
seriesCountByMetricName: [],
|
||||
memoryInBytesByLabelName: [],
|
||||
|
@ -84,6 +90,9 @@ const fakeInvalidTimestampTSDBStatusResponse: {
|
|||
minTime: 9223372036854776000,
|
||||
maxTime: -9223372036854776000,
|
||||
},
|
||||
tsdbStats: {
|
||||
minTime: 9223372036854776000,
|
||||
},
|
||||
labelValueCountByLabelName: [],
|
||||
seriesCountByMetricName: [],
|
||||
memoryInBytesByLabelName: [],
|
||||
|
|
|
@ -19,8 +19,13 @@ interface HeadStats {
|
|||
maxTime: number;
|
||||
}
|
||||
|
||||
interface TSDBStats {
|
||||
minTime: number;
|
||||
}
|
||||
|
||||
export interface TSDBMap {
|
||||
headStats: HeadStats;
|
||||
tsdbStats: TSDBStats;
|
||||
seriesCountByMetricName: Stats[];
|
||||
labelValueCountByLabelName: Stats[];
|
||||
memoryInBytesByLabelName: Stats[];
|
||||
|
@ -45,29 +50,49 @@ export const TSDBStatusContent: FC<TSDBMap> = ({
|
|||
}
|
||||
};
|
||||
const { chunkCount, numSeries, numLabelPairs, minTime, maxTime } = headStats;
|
||||
const stats = [
|
||||
const headStatsKV = [
|
||||
{ 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)}` },
|
||||
{ header: 'Current Max Time', value: `${unixToTime(maxTime)}` },
|
||||
];
|
||||
const tsdbStatsKV = [{ header: 'Current Min Time', value: `${unixToTime(minTime)}` }];
|
||||
return (
|
||||
<div>
|
||||
<h2>TSDB Status</h2>
|
||||
<h3 className="p-2">Head Stats</h3>
|
||||
<h3 className="p-2">TSDB Stats</h3>
|
||||
<div className="p-2">
|
||||
<Table bordered size="sm" striped>
|
||||
<thead>
|
||||
<tr>
|
||||
{stats.map(({ header }) => {
|
||||
{tsdbStatsKV.map(({ header }) => {
|
||||
return <th key={header}>{header}</th>;
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{stats.map(({ header, value }) => {
|
||||
{tsdbStatsKV.map(({ header, value }) => {
|
||||
return <td key={header}>{value}</td>;
|
||||
})}
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
<h3 className="p-2">Head Stats</h3>
|
||||
<div className="p-2">
|
||||
<Table bordered size="sm" striped>
|
||||
<thead>
|
||||
<tr>
|
||||
{headStatsKV.map(({ header }) => {
|
||||
return <th key={header}>{header}</th>;
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{headStatsKV.map(({ header, value }) => {
|
||||
return <td key={header}>{value}</td>;
|
||||
})}
|
||||
</tr>
|
||||
|
|
Loading…
Reference in a new issue