system: information panel and event log; about: download this build's source
System page laid out after 3CX's admin dashboard: a System information panel (version, host name, company, public IP, LAN IPs, ports, telephony, restart needed, copy buttons, how to restart) and an Event log panel (system_events, 90 days: trunk down/up, Asterisk down/up, restart needed, config failed, 911, public IP changed, backups, disk) with Load more and a CSV download. About (/about, no sign-in, linked from the login page, My phone and System): AGPL-3.0 notice, credits, the repository link, and "Code v<version>", which downloads selfphone.tar.gz: the api image now tars its own build context (no .env, data, node_modules, build output or .git) before installing anything. Task: M11-T7
This commit is contained in:
1 parent
a6ba61756c
commit
0ff0f9292b
29 files changed
+5035
-79
No files matched your search
@@ -10,6 +10,7 @@ import type { Db } from './db/client.ts';
|
||||
import {
|
||||
extensions,
|
||||
sessions,
|
||||
systemEvents,
|
||||
trunks,
|
||||
users,
|
||||
voicemailMessages,
|
||||
@@ -21,6 +22,7 @@ import type { LiveState } from './live/state.ts';
|
||||
import { cleanupRecordings } from './routes/recordings.ts';
|
||||
import { audit } from './services/audit.ts';
|
||||
import { backupDue, runBackup } from './services/backup.ts';
|
||||
import { logEvent } from './services/events.ts';
|
||||
import { deliverDue } from './services/webhooks.ts';
|
||||
import type { SendMail } from './services/mail.ts';
|
||||
import { getSetting, setSetting } from './services/settings.ts';
|
||||
@@ -101,6 +103,9 @@ export async function retentionCleanup(d: JobDeps) {
|
||||
await d.db
|
||||
.delete(webhookDeliveries)
|
||||
.where(lt(webhookDeliveries.createdAt, sql`now() - interval '30 days'`));
|
||||
await d.db
|
||||
.delete(systemEvents)
|
||||
.where(lt(systemEvents.createdAt, sql`now() - interval '90 days'`));
|
||||
if (recordings || voicemail) d.log.info({ recordings, voicemail }, 'old messages deleted');
|
||||
}
|
||||
|
||||
@@ -132,7 +137,19 @@ export function createJobs(d: JobDeps) {
|
||||
try {
|
||||
const b = await runBackup(d.config, d.db);
|
||||
d.log.info({ backup: b.name, size: b.size }, 'backup made');
|
||||
await logEvent(d.db, {
|
||||
severity: 'info',
|
||||
code: 'backup.done',
|
||||
source: 'Backup',
|
||||
message: `Daily backup ${b.name} made (${Math.round(b.size / 1e6)} MB)`,
|
||||
});
|
||||
} catch (err) {
|
||||
await logEvent(d.db, {
|
||||
severity: 'error',
|
||||
code: 'backup.failed',
|
||||
source: 'Backup',
|
||||
message: `Daily backup failed: ${(err as Error).message}`,
|
||||
});
|
||||
await mailAdmins(d, 'Backup failed', `Today's backup failed: ${(err as Error).message}`);
|
||||
throw err;
|
||||
}
|
||||
@@ -149,6 +166,12 @@ export function createJobs(d: JobDeps) {
|
||||
summary: `Public IP changed from ${old ?? 'none'} to ${ip}`,
|
||||
diff: { before: old, after: ip },
|
||||
});
|
||||
await logEvent(d.db, {
|
||||
severity: 'warning',
|
||||
code: 'network.publicIpChanged',
|
||||
source: 'Network',
|
||||
message: `Public IP changed from ${old ?? 'none'} to ${ip}`,
|
||||
});
|
||||
await d.generator.apply({ trigger: 'publicIp', force: true }); // sets restartRequired
|
||||
await mailAdmins(
|
||||
d,
|
||||
@@ -198,6 +221,12 @@ export function createJobs(d: JobDeps) {
|
||||
const today = todayIn(await tz(), now());
|
||||
if (free >= 0.1 || diskMailedDay === today) return;
|
||||
diskMailedDay = today;
|
||||
await logEvent(d.db, {
|
||||
severity: 'warning',
|
||||
code: 'disk.low',
|
||||
source: 'Disk',
|
||||
message: `Disk almost full: ${Math.round(free * 100)}% free`,
|
||||
});
|
||||
await mailAdmins(
|
||||
d,
|
||||
`Disk almost full (${Math.round(free * 100)}% free)`,
|
||||
|
||||
Reference in new issue
Block a user