diff --git a/pageserver/src/http/openapi_spec.yml b/pageserver/src/http/openapi_spec.yml
index f9b8a81dad..23faff7ace 100644
--- a/pageserver/src/http/openapi_spec.yml
+++ b/pageserver/src/http/openapi_spec.yml
@@ -430,6 +430,13 @@ paths:
schema:
type: string
format: hex
+ - name: inputs_only
+ in: query
+ required: false
+ schema:
+ type: boolean
+ description: |
+ When true, skip calculation and only provide the model inputs (for debugging). Defaults to false.
get:
description: |
Calculate tenant's size, which is a mixture of WAL (bytes) and logical_size (bytes).
@@ -449,8 +456,9 @@ paths:
format: hex
size:
type: integer
+ nullable: true
description: |
- Size metric in bytes.
+ Size metric in bytes or null if inputs_only=true was given.
"401":
description: Unauthorized Error
content:
diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs
index ebb454b4de..3ce239e090 100644
--- a/pageserver/src/http/routes.rs
+++ b/pageserver/src/http/routes.rs
@@ -453,21 +453,39 @@ async fn tenant_status(request: Request
) -> Result, ApiErro
json_response(StatusCode::OK, tenant_info)
}
+/// HTTP endpoint to query the current tenant_size of a tenant.
+///
+/// This is not used by consumption metrics under [`crate::consumption_metrics`], but can be used
+/// to debug any of the calculations. Requires `tenant_id` request parameter, supports
+/// `inputs_only=true|false` (default false) which supports debugging failure to calculate model
+/// values.
async fn tenant_size_handler(request: Request) -> Result, ApiError> {
let tenant_id: TenantId = parse_request_param(&request, "tenant_id")?;
check_permission(&request, Some(tenant_id))?;
+ let inputs_only = if query_param_present(&request, "inputs_only") {
+ get_query_param(&request, "inputs_only")?
+ .parse()
+ .map_err(|_| ApiError::BadRequest(anyhow!("failed to parse inputs_only")))?
+ } else {
+ false
+ };
+
let tenant = mgr::get_tenant(tenant_id, true)
.await
.map_err(ApiError::InternalServerError)?;
- // this can be long operation, it currently is not backed by any request coalescing or similar
+ // this can be long operation
let inputs = tenant
.gather_size_inputs()
.await
.map_err(ApiError::InternalServerError)?;
- let size = inputs.calculate().map_err(ApiError::InternalServerError)?;
+ let size = if !inputs_only {
+ Some(inputs.calculate().map_err(ApiError::InternalServerError)?)
+ } else {
+ None
+ };
/// Private response type with the additional "unstable" `inputs` field.
///
@@ -479,7 +497,9 @@ async fn tenant_size_handler(request: Request) -> Result, A
#[serde_as(as = "serde_with::DisplayFromStr")]
id: TenantId,
/// Size is a mixture of WAL and logical size, so the unit is bytes.
- size: u64,
+ ///
+ /// Will be none if `?inputs_only=true` was given.
+ size: Option,
inputs: crate::tenant::size::ModelInputs,
}