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"`
|
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.
|
// TSDBStatus has information of cardinality statistics from postings.
|
||||||
type TSDBStatus struct {
|
type TSDBStatus struct {
|
||||||
HeadStats HeadStats `json:"headStats"`
|
HeadStats HeadStats `json:"headStats"`
|
||||||
|
TSDBStats TSDBStats `json:"tsdbStats"`
|
||||||
SeriesCountByMetricName []TSDBStat `json:"seriesCountByMetricName"`
|
SeriesCountByMetricName []TSDBStat `json:"seriesCountByMetricName"`
|
||||||
LabelValueCountByLabelName []TSDBStat `json:"labelValueCountByLabelName"`
|
LabelValueCountByLabelName []TSDBStat `json:"labelValueCountByLabelName"`
|
||||||
MemoryInBytesByLabelName []TSDBStat `json:"memoryInBytesByLabelName"`
|
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}
|
return apiFuncResult{nil, &apiError{errorInternal, fmt.Errorf("error gathering runtime status: %w", err)}, nil, nil}
|
||||||
}
|
}
|
||||||
chunkCount := int64(math.NaN())
|
chunkCount := int64(math.NaN())
|
||||||
|
lowestTimestamp := int64(math.NaN())
|
||||||
for _, mF := range metrics {
|
for _, mF := range metrics {
|
||||||
if *mF.Name == "prometheus_tsdb_head_chunks" {
|
switch *mF.Name {
|
||||||
|
case "prometheus_tsdb_head_chunks":
|
||||||
m := mF.Metric[0]
|
m := mF.Metric[0]
|
||||||
if m.Gauge != nil {
|
if m.Gauge != nil {
|
||||||
chunkCount = int64(m.Gauge.GetValue())
|
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,
|
MaxTime: s.MaxTime,
|
||||||
NumLabelPairs: s.IndexPostingStats.NumLabelPairs,
|
NumLabelPairs: s.IndexPostingStats.NumLabelPairs,
|
||||||
},
|
},
|
||||||
|
TSDBStats: TSDBStats{MinTime: lowestTimestamp},
|
||||||
SeriesCountByMetricName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityMetricsStats),
|
SeriesCountByMetricName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityMetricsStats),
|
||||||
LabelValueCountByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityLabelStats),
|
LabelValueCountByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.CardinalityLabelStats),
|
||||||
MemoryInBytesByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.LabelValueStats),
|
MemoryInBytesByLabelName: TSDBStatsFromIndexStats(s.IndexPostingStats.LabelValueStats),
|
||||||
|
|
|
@ -20,6 +20,9 @@ const fakeTSDBStatusResponse: {
|
||||||
minTime: 1591516800000,
|
minTime: 1591516800000,
|
||||||
maxTime: 1598896800143,
|
maxTime: 1598896800143,
|
||||||
},
|
},
|
||||||
|
tsdbStats: {
|
||||||
|
minTime: 1591516800000,
|
||||||
|
},
|
||||||
labelValueCountByLabelName: [
|
labelValueCountByLabelName: [
|
||||||
{
|
{
|
||||||
name: '__name__',
|
name: '__name__',
|
||||||
|
@ -64,6 +67,9 @@ const fakeEmptyTSDBStatusResponse: {
|
||||||
minTime: 9223372036854776000,
|
minTime: 9223372036854776000,
|
||||||
maxTime: -9223372036854776000,
|
maxTime: -9223372036854776000,
|
||||||
},
|
},
|
||||||
|
tsdbStats: {
|
||||||
|
minTime: 9223372036854776000,
|
||||||
|
},
|
||||||
labelValueCountByLabelName: [],
|
labelValueCountByLabelName: [],
|
||||||
seriesCountByMetricName: [],
|
seriesCountByMetricName: [],
|
||||||
memoryInBytesByLabelName: [],
|
memoryInBytesByLabelName: [],
|
||||||
|
@ -84,6 +90,9 @@ const fakeInvalidTimestampTSDBStatusResponse: {
|
||||||
minTime: 9223372036854776000,
|
minTime: 9223372036854776000,
|
||||||
maxTime: -9223372036854776000,
|
maxTime: -9223372036854776000,
|
||||||
},
|
},
|
||||||
|
tsdbStats: {
|
||||||
|
minTime: 9223372036854776000,
|
||||||
|
},
|
||||||
labelValueCountByLabelName: [],
|
labelValueCountByLabelName: [],
|
||||||
seriesCountByMetricName: [],
|
seriesCountByMetricName: [],
|
||||||
memoryInBytesByLabelName: [],
|
memoryInBytesByLabelName: [],
|
||||||
|
|
|
@ -19,8 +19,13 @@ interface HeadStats {
|
||||||
maxTime: number;
|
maxTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TSDBStats {
|
||||||
|
minTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TSDBMap {
|
export interface TSDBMap {
|
||||||
headStats: HeadStats;
|
headStats: HeadStats;
|
||||||
|
tsdbStats: TSDBStats;
|
||||||
seriesCountByMetricName: Stats[];
|
seriesCountByMetricName: Stats[];
|
||||||
labelValueCountByLabelName: Stats[];
|
labelValueCountByLabelName: Stats[];
|
||||||
memoryInBytesByLabelName: Stats[];
|
memoryInBytesByLabelName: Stats[];
|
||||||
|
@ -45,29 +50,49 @@ export const TSDBStatusContent: FC<TSDBMap> = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const { chunkCount, numSeries, numLabelPairs, minTime, maxTime } = headStats;
|
const { chunkCount, numSeries, numLabelPairs, minTime, maxTime } = headStats;
|
||||||
const stats = [
|
const headStatsKV = [
|
||||||
{ header: 'Number of Series', value: numSeries },
|
{ header: 'Number of Series', value: numSeries },
|
||||||
{ header: 'Number of Chunks', value: chunkCount },
|
{ header: 'Number of Chunks', value: chunkCount },
|
||||||
{ header: 'Number of Label Pairs', value: numLabelPairs },
|
{ header: 'Number of Label Pairs', value: numLabelPairs },
|
||||||
{ header: 'Current Min Time', value: `${unixToTime(minTime)}` },
|
{ header: 'Current Min Time', value: `${unixToTime(minTime)}` },
|
||||||
{ header: 'Current Max Time', value: `${unixToTime(maxTime)}` },
|
{ header: 'Current Max Time', value: `${unixToTime(maxTime)}` },
|
||||||
];
|
];
|
||||||
|
const tsdbStatsKV = [{ header: 'Current Min Time', value: `${unixToTime(minTime)}` }];
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>TSDB Status</h2>
|
<h2>TSDB Status</h2>
|
||||||
<h3 className="p-2">Head Stats</h3>
|
<h3 className="p-2">TSDB Stats</h3>
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
<Table bordered size="sm" striped>
|
<Table bordered size="sm" striped>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{stats.map(({ header }) => {
|
{tsdbStatsKV.map(({ header }) => {
|
||||||
return <th key={header}>{header}</th>;
|
return <th key={header}>{header}</th>;
|
||||||
})}
|
})}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<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>;
|
return <td key={header}>{value}</td>;
|
||||||
})}
|
})}
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in a new issue