Backup Diagnostics

9 vues Markdown

The six endpoints that hold the backup settings and measure what the server can back up.

Overview

These six endpoints answer two questions. Two of them hold the settings: is the system on, and what stays out of a backup. The other four measure: can this server take a backup, is there room, and how much space each folder and table takes.

The four that measure are read-only and change nothing. They also feed the exclusion screen in the panel: an operator walks the tree, sees the tables by size, and decides.

The diagnostics are the real question to ask before taking a backup. They show today what would otherwise surface on the night of the run: a critical gap makes a backup impossible, while a warning leaves one weaker.

Reference

Reading the Backup Settings

get/api/v1/admin/settings/backup/settings
Settings/GetBackupSettings admin

Returns the backup system's main switch and what it leaves out.

Response fields data — 3
statusintWhether the backup system is on.
excluded_pathsstringThe paths kept out of backups. A single string rather than a list.
excluded_tablesstringThe tables kept out of backups. A single string rather than a list.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/settings/backup/settings' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/backup/settings', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// With the main switch OFF the schedules stop and taking one by hand is refused.
$live = Api::Settings()->GetBackupSettings()['data']['status'] === 1;

Writing the Backup Settings

put/api/v1/admin/settings/backup/settings
Settings/UpdateBackupSettings admin

Switches the system on and writes the paths and tables to leave out.

Body 3
statusintSwitches the backup system on or off.
excluded_pathsstringThe paths to keep out. What you send replaces what was there.
excluded_tablesstringThe tables to keep out. What you send replaces what was there.
Response fields data — 3
dataobjectThe settings as they now stand. Same shape as the read endpoint.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/settings/backup/settings' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"status":1,"excluded_tables":"api_logs,mail_logs"}'
const res = await fetch('https://panel.example.com/api/v1/admin/settings/backup/settings', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    status: 1,
    excluded_tables: 'api_logs,mail_logs',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'status'          => 1,
        'excluded_tables' => 'api_logs,mail_logs',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The list is REPLACED, not added to: read the old one first or the earlier entries go.
$cur = Api::Settings()->GetBackupSettings()['data']['excluded_tables'];

Api::Settings()->UpdateBackupSettings([
    'excluded_tables' => $cur . ',mail_logs',
]);

Reading the Diagnostics

get/api/v1/admin/settings/backup/diagnostics
Settings/GetBackupDiagnostics admin

Tells you whether the server can actually take a backup.

Response fields data — 4
criticalstring[]What makes a backup impossible: phar for archiving, zlib for compression, spl for walking directories.
warningstring[]What leaves a backup weaker: disk-monitor for space measuring, exec for child processes, streaming-pipe for streaming.
infostring[]What is merely worth knowing: mysqldump-cli, the external dump tool.
okboolWhether all is well. True when the critical and warning lists are empty, and the info lines do not count.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/settings/backup/diagnostics' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/backup/diagnostics', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/diagnostics');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A full critical list means NO backup can run; the warning list only weakens one.
$d = Api::Settings()->GetBackupDiagnostics()['data'];
if ($d['critical']) throw new Exception('Backups cannot run on this server.');

Reading the Disk Information

get/api/v1/admin/settings/backup/disk
Settings/GetBackupDisk admin

Returns how much room is left on the disk the installation sits on.

Response fields data — 4
freeintThe free space.
totalintThe total space.
usedintThe space in use.
sourcestringWhere the measurement came from. Either a direct system call or the disk tool read from a shell.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/settings/backup/disk' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/backup/disk', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();

if (data.total === undefined) console.warn('disk measurement unavailable');
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/disk');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// When the server allows no measurement the fields DO NOT arrive, so check before reading.
$disk = Api::Settings()->GetBackupDisk()['data'];
$free = $disk['free'] ?? null;

Walking the Directory Tree

get/api/v1/admin/settings/backup/directory-listing
Settings/GetBackupDirectoryListing admin

Returns the files and folders under the installation root.

Query 1
pathstringA path below the root. Left empty, the root comes back.
Response fields data — 2 + entries[] — 6
pathstringThe path asked for.
entries[]object[]What that folder holds. Folders first, then files, each group sorted by name.
entries[].namestringThe entry name.
entries[].pathstringIts path below the root.
entries[].typestringWhether it is a folder or a file.
entries[].sizeint | nullThe file size. Empty for folders.
entries[].has_childrenboolWhether it holds anything.
entries[].has_subdirsboolWhether it holds further folders. Lets you show it as expandable without opening it.
Errors 2
invalid_path422The path is not valid, or not a folder.
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/settings/backup/directory-listing?path=templates' \
  -H "Authorization: Bearer $API_KEY"
const url = new URL('https://panel.example.com/api/v1/admin/settings/backup/directory-listing');
url.searchParams.set('path', 'templates');

const res  = await fetch(url, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/directory-listing?' . http_build_query(['path' => 'templates']));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The tree cannot leave the root; a path climbing upward comes back as a 422.
$tree = Api::Settings()->GetBackupDirectoryListing([], ['path' => 'templates'])['data'];

Measuring the Tables

get/api/v1/admin/settings/backup/tables
Settings/GetBackupTables admin

Returns the database tables with their row counts and sizes.

Response fields data[] — 3
namestringThe table name. The list arrives sorted by name.
rowsintThe row count. An estimate from the engine rather than a count.
sizeintThe room the table takes. Data and index added together.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/settings/backup/tables' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/backup/tables', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/backup/tables');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Feeding the exclusion screen with the fattest tables: size is NOT the archive size.
$tables = Api::Settings()->GetBackupTables()['data'];
usort($tables, fn ($a, $b) => $b['size'] <=> $a['size']);

Pitfalls

The main switch comes before everything

While the backup system is off, schedules do not run and the take-by-hand call is refused. The schedules stay in the list, the targets stay put, and none of them raises an error. When no backup appears on an installation, look at this field before you go hunting through the schedules.

The exclusion lists are replaced, not added to

The path and table lists are strings, and what you send replaces what was there. Sending only the one table you meant to add drops every earlier line. Read the current value first and append to it.

The disk information may not arrive at all

When the server allows no space measurement this endpoint returns an empty object and raises nothing. Check the fields exist before reading them, or an absent value reads as zero and you warn that the disk is full. The same gap also shows in the diagnostics warning list.

The directory tree does not show everything

Whatever is excluded by default is filtered out of the tree and never appears in the listing. The backup folder itself is one of those, and it keeps being filtered even after an operator renames it. That is deliberate: were the backups themselves included, every run would carry the one before it.

The row count is an estimate and the size is not the archive

A table's row count is the engine's estimate. It can be tens of percent off, so keep it out of billing and reporting figures. The size adds data and index together, while a compressed dump comes out far smaller. Both are good enough for deciding what to exclude and no more than that.

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Besoin d'aide supplémentaire ?

Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.