Skip to content

Commit fa8da34

Browse files
authored
feat: add support for /status/tsdb/blocks endpoint (#1896)
Adds a new method to the API interface to support the new TSDB blocks endpoint that was added in prometheus 3.6.0: https://github.com/prometheus/prometheus/releases/tag/v3.6.0 prometheus/prometheus#16695 Signed-off-by: TJ Hoplock <t.hoplock@gmail.com>
1 parent 9358c16 commit fa8da34

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

api/prometheus/v1/api.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ const (
380380
epBuildinfo = apiPrefix + "/status/buildinfo"
381381
epRuntimeinfo = apiPrefix + "/status/runtimeinfo"
382382
epTSDB = apiPrefix + "/status/tsdb"
383+
epTSDBBlocks = apiPrefix + "/status/tsdb/blocks"
383384
epWalReplay = apiPrefix + "/status/walreplay"
384385
epFormatQuery = apiPrefix + "/format_query"
385386
)
@@ -504,6 +505,8 @@ type API interface {
504505
Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error)
505506
// TSDB returns the cardinality statistics.
506507
TSDB(ctx context.Context, opts ...Option) (TSDBResult, error)
508+
// TSDBBlocks returns the list of currently loaded TSDB blocks and their metadata.
509+
TSDBBlocks(ctx context.Context) (TSDBBlocksResult, error)
507510
// WalReplay returns the current replay status of the wal.
508511
WalReplay(ctx context.Context) (WalReplayStatus, error)
509512
// FormatQuery formats a PromQL expression in a prettified way.
@@ -693,6 +696,40 @@ type TSDBHeadStats struct {
693696
MaxTime int `json:"maxTime"`
694697
}
695698

699+
// TSDBBlocksResult contains the results from querying the tsdb blocks endpoint.
700+
type TSDBBlocksResult struct {
701+
Status string `json:"status"`
702+
Data TSDBBlocksData `json:"data"`
703+
}
704+
705+
// TSDBBlocksData contains the metadata for the tsdb blocks.
706+
type TSDBBlocksData struct {
707+
Blocks []TSDBBlocksBlockMetadata `json:"blocks"`
708+
}
709+
710+
// TSDBBlocksBlockMetadata contains the metadata for a single tsdb block.
711+
type TSDBBlocksBlockMetadata struct {
712+
Ulid string `json:"ulid"`
713+
MinTime int64 `json:"minTime"`
714+
MaxTime int64 `json:"maxTime"`
715+
Stats TSDBBlocksStats `json:"stats"`
716+
Compaction TSDBBlocksCompaction `json:"compaction"`
717+
Version int `json:"version"`
718+
}
719+
720+
// TSDBBlocksStats contains block stats for a single tsdb block.
721+
type TSDBBlocksStats struct {
722+
NumSamples int `json:"numSamples"`
723+
NumSeries int `json:"numSeries"`
724+
NumChunks int `json:"numChunks"`
725+
}
726+
727+
// TSDBBlocksCompaction contains block compaction details for a single block.
728+
type TSDBBlocksCompaction struct {
729+
Level int `json:"level"`
730+
Sources []string `json:"sources"`
731+
}
732+
696733
// WalReplayStatus represents the wal replay status.
697734
type WalReplayStatus struct {
698735
Min int `json:"min"`
@@ -1350,6 +1387,24 @@ func (h *httpAPI) TSDB(ctx context.Context, opts ...Option) (TSDBResult, error)
13501387
return res, err
13511388
}
13521389

1390+
func (h *httpAPI) TSDBBlocks(ctx context.Context) (TSDBBlocksResult, error) {
1391+
u := h.client.URL(epTSDBBlocks, nil)
1392+
1393+
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
1394+
if err != nil {
1395+
return TSDBBlocksResult{}, err
1396+
}
1397+
1398+
_, body, _, err := h.client.Do(ctx, req)
1399+
if err != nil {
1400+
return TSDBBlocksResult{}, err
1401+
}
1402+
1403+
var res TSDBBlocksResult
1404+
err = json.Unmarshal(body, &res)
1405+
return res, err
1406+
}
1407+
13531408
func (h *httpAPI) WalReplay(ctx context.Context) (WalReplayStatus, error) {
13541409
u := h.client.URL(epWalReplay, nil)
13551410

api/prometheus/v1/api_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ func TestAPIs(t *testing.T) {
226226
}
227227
}
228228

229+
doTSDBBlocks := func(opts ...Option) func() (interface{}, Warnings, error) {
230+
return func() (interface{}, Warnings, error) {
231+
v, err := promAPI.TSDBBlocks(context.Background())
232+
return v, nil, err
233+
}
234+
}
235+
229236
doWalReply := func() func() (interface{}, Warnings, error) {
230237
return func() (interface{}, Warnings, error) {
231238
v, err := promAPI.WalReplay(context.Background())
@@ -1186,6 +1193,64 @@ func TestAPIs(t *testing.T) {
11861193
},
11871194
},
11881195

1196+
{
1197+
do: doTSDBBlocks(),
1198+
reqMethod: "GET",
1199+
reqPath: "/api/v1/status/tsdb/blocks",
1200+
inErr: errors.New("some error"),
1201+
err: errors.New("some error"),
1202+
},
1203+
1204+
{
1205+
do: doTSDBBlocks(),
1206+
reqMethod: "GET",
1207+
reqPath: "/api/v1/status/tsdb/blocks",
1208+
inRes: map[string]interface{}{
1209+
"status": "success",
1210+
"data": map[string]interface{}{
1211+
"blocks": []interface{}{
1212+
map[string]interface{}{
1213+
"ulid": "01JZ8JKZY6XSK3PTDP9ZKRWT60",
1214+
"minTime": 1750860620060,
1215+
"maxTime": 1750867200000,
1216+
"stats": map[string]interface{}{
1217+
"numSamples": 13701,
1218+
"numSeries": 716,
1219+
"numChunks": 716,
1220+
},
1221+
"compaction": map[string]interface{}{
1222+
"level": 1,
1223+
"sources": []interface{}{
1224+
"01JZ8JKZY6XSK3PTDP9ZKRWT60",
1225+
},
1226+
},
1227+
"version": 1,
1228+
},
1229+
},
1230+
},
1231+
},
1232+
res: TSDBBlocksResult{
1233+
Status: "success",
1234+
Data: TSDBBlocksData{
1235+
Blocks: []TSDBBlocksBlockMetadata{{
1236+
Ulid: "01JZ8JKZY6XSK3PTDP9ZKRWT60",
1237+
MinTime: 1750860620060,
1238+
MaxTime: 1750867200000,
1239+
Version: 1,
1240+
Stats: TSDBBlocksStats{
1241+
NumSamples: 13701,
1242+
NumSeries: 716,
1243+
NumChunks: 716,
1244+
},
1245+
Compaction: TSDBBlocksCompaction{
1246+
Level: 1,
1247+
Sources: []string{"01JZ8JKZY6XSK3PTDP9ZKRWT60"},
1248+
},
1249+
}},
1250+
},
1251+
},
1252+
},
1253+
11891254
{
11901255
do: doWalReply(),
11911256
reqMethod: "GET",

0 commit comments

Comments
 (0)