api: add blob dir size to storage info (#7605)

closes #7598
This commit is contained in:
Simon Laux
2025-12-12 21:15:12 +01:00
committed by GitHub
parent 49b04e8789
commit 8dfa5fc37e
5 changed files with 27 additions and 11 deletions

2
Cargo.lock generated
View File

@@ -1388,6 +1388,7 @@ dependencies = [
"tracing",
"url",
"uuid",
"walkdir",
"webpki-roots",
]
@@ -1429,7 +1430,6 @@ dependencies = [
"tempfile",
"tokio",
"typescript-type-def",
"walkdir",
"yerpc",
]

View File

@@ -111,6 +111,7 @@ toml = "0.9"
tracing = "0.1.41"
url = "2"
uuid = { version = "1", features = ["serde", "v4"] }
walkdir = "2.5.0"
webpki-roots = "0.26.8"
[dev-dependencies]

View File

@@ -19,7 +19,6 @@ yerpc = { workspace = true, features = ["anyhow_expose", "openrpc"] }
typescript-type-def = { version = "0.5.13", features = ["json_value"] }
tokio = { workspace = true }
sanitize-filename = { workspace = true }
walkdir = "2.5.0"
base64 = { workspace = true }
[dev-dependencies]

View File

@@ -35,14 +35,13 @@ use deltachat::qr_code_generator::{generate_backup_qr, get_securejoin_qr_svg};
use deltachat::reaction::{get_msg_reactions, send_reaction};
use deltachat::securejoin;
use deltachat::stock_str::StockMessage;
use deltachat::storage_usage::get_storage_usage;
use deltachat::storage_usage::{get_blobdir_storage_usage, get_storage_usage};
use deltachat::webxdc::StatusUpdateSerial;
use deltachat::EventEmitter;
use sanitize_filename::is_sanitized;
use tokio::fs;
use tokio::sync::{watch, Mutex, RwLock};
use types::login_param::EnteredLoginParam;
use walkdir::WalkDir;
use yerpc::rpc;
pub mod types;
@@ -330,13 +329,7 @@ impl CommandApi {
async fn get_account_file_size(&self, account_id: u32) -> Result<u64> {
let ctx = self.get_context(account_id).await?;
let dbfile = ctx.get_dbfile().metadata()?.len();
let total_size = WalkDir::new(ctx.get_blobdir())
.max_depth(2)
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| entry.metadata().ok())
.filter(|metadata| metadata.is_file())
.fold(0, |acc, m| acc + m.len());
let total_size = get_blobdir_storage_usage(&ctx);
Ok(dbfile + total_size)
}

View File

@@ -2,6 +2,7 @@
use crate::{context::Context, message::MsgId};
use anyhow::Result;
use humansize::{BINARY, format_size};
use walkdir::WalkDir;
/// Storage Usage Report
/// Useful for debugging space usage problems in the deltachat database.
@@ -14,11 +15,15 @@ pub struct StorageUsage {
/// count and total size of status updates
/// for the 10 webxdc apps with the most size usage in status updates
pub largest_webxdc_data: Vec<(MsgId, u64, u64)>,
/// Total size of all files in the blobdir
pub blobdir_size: u64,
}
impl std::fmt::Display for StorageUsage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Storage Usage:")?;
let blobdir_size = format_size(self.blobdir_size, BINARY);
writeln!(f, "[Blob Directory Size]: {blobdir_size}")?;
let human_db_size = format_size(self.db_size, BINARY);
writeln!(f, "[Database Size]: {human_db_size}")?;
writeln!(f, "[Largest Tables]:")?;
@@ -46,6 +51,10 @@ impl std::fmt::Display for StorageUsage {
/// Get storage usage information for the Context's database
pub async fn get_storage_usage(ctx: &Context) -> Result<StorageUsage> {
let context_clone = ctx.clone();
let blobdir_size =
tokio::task::spawn_blocking(move || get_blobdir_storage_usage(&context_clone));
let page_size: u64 = ctx
.sql
.query_get_value("PRAGMA page_size", ())
@@ -101,9 +110,23 @@ pub async fn get_storage_usage(ctx: &Context) -> Result<StorageUsage> {
)
.await?;
let blobdir_size = blobdir_size.await?;
Ok(StorageUsage {
db_size: page_size * page_count,
largest_tables,
largest_webxdc_data,
blobdir_size,
})
}
/// Returns storage usage of the blob directory
pub fn get_blobdir_storage_usage(ctx: &Context) -> u64 {
WalkDir::new(ctx.get_blobdir())
.max_depth(2)
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| entry.metadata().ok())
.filter(|metadata| metadata.is_file())
.fold(0, |acc, m| acc + m.len())
}