@calltelemetry/cli 0.7.5 → 0.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -2
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +13 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +33 -0
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/diag.d.ts.map +1 -1
- package/dist/commands/diag.js +3 -0
- package/dist/commands/diag.js.map +1 -1
- package/dist/commands/health.d.ts +3 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +34 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +7 -0
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +1 -0
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/syslog.d.ts +3 -0
- package/dist/commands/syslog.d.ts.map +1 -0
- package/dist/commands/syslog.js +159 -0
- package/dist/commands/syslog.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +143 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/bundle.d.ts +3 -1
- package/dist/lib/bundle.d.ts.map +1 -1
- package/dist/lib/bundle.js +90 -15
- package/dist/lib/bundle.js.map +1 -1
- package/dist/lib/compose.d.ts +10 -0
- package/dist/lib/compose.d.ts.map +1 -1
- package/dist/lib/compose.js +251 -13
- package/dist/lib/compose.js.map +1 -1
- package/dist/lib/db-backup.d.ts +23 -0
- package/dist/lib/db-backup.d.ts.map +1 -0
- package/dist/lib/db-backup.js +80 -0
- package/dist/lib/db-backup.js.map +1 -0
- package/dist/lib/health-report.d.ts +93 -0
- package/dist/lib/health-report.d.ts.map +1 -0
- package/dist/lib/health-report.js +391 -0
- package/dist/lib/health-report.js.map +1 -0
- package/dist/lib/migration-003-nm-heal.js +5 -5
- package/dist/lib/migration-003-nm-heal.js.map +1 -1
- package/dist/lib/migration-009-bind-mount-files.d.ts +5 -4
- package/dist/lib/migration-009-bind-mount-files.d.ts.map +1 -1
- package/dist/lib/migration-009-bind-mount-files.js +15 -7
- package/dist/lib/migration-009-bind-mount-files.js.map +1 -1
- package/dist/lib/migration-010-jtapi-state.js +2 -2
- package/dist/lib/migration-010-jtapi-state.js.map +1 -1
- package/dist/lib/migration-011-docker-memory-limit.js +2 -2
- package/dist/lib/migration-011-docker-memory-limit.js.map +1 -1
- package/dist/lib/migration-012-db-pool-sizes.d.ts.map +1 -1
- package/dist/lib/migration-012-db-pool-sizes.js +5 -14
- package/dist/lib/migration-012-db-pool-sizes.js.map +1 -1
- package/dist/lib/migration-013-grafana-password.d.ts.map +1 -1
- package/dist/lib/migration-013-grafana-password.js +5 -13
- package/dist/lib/migration-013-grafana-password.js.map +1 -1
- package/dist/lib/postgres-performance.d.ts +51 -0
- package/dist/lib/postgres-performance.d.ts.map +1 -0
- package/dist/lib/postgres-performance.js +279 -0
- package/dist/lib/postgres-performance.js.map +1 -0
- package/dist/lib/release-migration-progress.d.ts +48 -0
- package/dist/lib/release-migration-progress.d.ts.map +1 -0
- package/dist/lib/release-migration-progress.js +223 -0
- package/dist/lib/release-migration-progress.js.map +1 -0
- package/dist/lib/services.d.ts.map +1 -1
- package/dist/lib/services.js +70 -1
- package/dist/lib/services.js.map +1 -1
- package/dist/lib/showtech-steps.d.ts +5 -1
- package/dist/lib/showtech-steps.d.ts.map +1 -1
- package/dist/lib/showtech-steps.js +44 -13
- package/dist/lib/showtech-steps.js.map +1 -1
- package/dist/lib/syslog.d.ts +5 -0
- package/dist/lib/syslog.d.ts.map +1 -0
- package/dist/lib/syslog.js +21 -0
- package/dist/lib/syslog.js.map +1 -0
- package/dist/lib/update-steps.d.ts.map +1 -1
- package/dist/lib/update-steps.js +119 -1
- package/dist/lib/update-steps.js.map +1 -1
- package/dist/lib/update.d.ts +8 -0
- package/dist/lib/update.d.ts.map +1 -1
- package/dist/lib/update.js +36 -4
- package/dist/lib/update.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/shell/commands/db.d.ts +1 -0
- package/dist/shell/commands/db.d.ts.map +1 -1
- package/dist/shell/commands/db.js +18 -0
- package/dist/shell/commands/db.js.map +1 -1
- package/dist/shell/commands/registry.d.ts.map +1 -1
- package/dist/shell/commands/registry.js +3 -1
- package/dist/shell/commands/registry.js.map +1 -1
- package/dist/shell/commands/show.d.ts +1 -0
- package/dist/shell/commands/show.d.ts.map +1 -1
- package/dist/shell/commands/show.js +37 -1
- package/dist/shell/commands/show.js.map +1 -1
- package/dist/ui/components/PostgresPerformanceLines.d.ts +7 -0
- package/dist/ui/components/PostgresPerformanceLines.d.ts.map +1 -0
- package/dist/ui/components/PostgresPerformanceLines.js +7 -0
- package/dist/ui/components/PostgresPerformanceLines.js.map +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/views/DbBackupView.d.ts.map +1 -1
- package/dist/ui/views/DbBackupView.js +11 -27
- package/dist/ui/views/DbBackupView.js.map +1 -1
- package/dist/ui/views/DbHealthView.d.ts.map +1 -1
- package/dist/ui/views/DbHealthView.js +10 -3
- package/dist/ui/views/DbHealthView.js.map +1 -1
- package/dist/ui/views/DbStatusView.d.ts.map +1 -1
- package/dist/ui/views/DbStatusView.js +5 -3
- package/dist/ui/views/DbStatusView.js.map +1 -1
- package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
- package/dist/ui/views/DiagDatabaseView.js +3 -1
- package/dist/ui/views/DiagDatabaseView.js.map +1 -1
- package/dist/ui/views/DiagShowTechView.d.ts +3 -1
- package/dist/ui/views/DiagShowTechView.d.ts.map +1 -1
- package/dist/ui/views/DiagShowTechView.js +3 -3
- package/dist/ui/views/DiagShowTechView.js.map +1 -1
- package/dist/ui/views/HealthReportView.d.ts +6 -0
- package/dist/ui/views/HealthReportView.d.ts.map +1 -0
- package/dist/ui/views/HealthReportView.js +82 -0
- package/dist/ui/views/HealthReportView.js.map +1 -0
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +4 -1
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/MigrateDrainView.d.ts +6 -0
- package/dist/ui/views/MigrateDrainView.d.ts.map +1 -0
- package/dist/ui/views/MigrateDrainView.js +77 -0
- package/dist/ui/views/MigrateDrainView.js.map +1 -0
- package/dist/ui/views/MigrateStatusView.d.ts.map +1 -1
- package/dist/ui/views/MigrateStatusView.js +16 -7
- package/dist/ui/views/MigrateStatusView.js.map +1 -1
- package/dist/ui/views/MigrateWatchView.d.ts.map +1 -1
- package/dist/ui/views/MigrateWatchView.js +17 -12
- package/dist/ui/views/MigrateWatchView.js.map +1 -1
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Previously a self-healing check in cli.sh that ran on every invocation.
|
|
9
9
|
* Now a one-time migration.
|
|
10
10
|
*/
|
|
11
|
-
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
12
12
|
import { spawnSync } from 'node:child_process';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
const NM_CONNECTIONS_DIR = '/etc/NetworkManager/system-connections';
|
|
@@ -38,11 +38,11 @@ export async function migrateNmHeal() {
|
|
|
38
38
|
.replace(/autoconnect=false/g, 'autoconnect=true');
|
|
39
39
|
// Write via sudo
|
|
40
40
|
const tmp = `/tmp/ct-nm-fix-${Date.now()}.nmconnection`;
|
|
41
|
-
|
|
41
|
+
writeFileSync(tmp, patched);
|
|
42
42
|
spawnSync('sudo', ['cp', tmp, path], { stdio: 'pipe' });
|
|
43
43
|
spawnSync('sudo', ['chmod', '600', path], { stdio: 'pipe' });
|
|
44
44
|
try {
|
|
45
|
-
|
|
45
|
+
unlinkSync(tmp);
|
|
46
46
|
}
|
|
47
47
|
catch { /* ignore */ }
|
|
48
48
|
changed = true;
|
|
@@ -57,11 +57,11 @@ export async function migrateNmHeal() {
|
|
|
57
57
|
if (!existsSync(NM_DOCKER_CONF)) {
|
|
58
58
|
const content = '[keyfile]\nunmanaged-devices=interface-name:docker*;interface-name:br-*;interface-name:veth*\n';
|
|
59
59
|
const tmp = `/tmp/ct-nm-docker-${Date.now()}.conf`;
|
|
60
|
-
|
|
60
|
+
writeFileSync(tmp, content);
|
|
61
61
|
spawnSync('sudo', ['mkdir', '-p', '/etc/NetworkManager/conf.d'], { stdio: 'pipe' });
|
|
62
62
|
spawnSync('sudo', ['cp', tmp, NM_DOCKER_CONF], { stdio: 'pipe' });
|
|
63
63
|
try {
|
|
64
|
-
|
|
64
|
+
unlinkSync(tmp);
|
|
65
65
|
}
|
|
66
66
|
catch { /* ignore */ }
|
|
67
67
|
changed = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-003-nm-heal.js","sourceRoot":"","sources":["../../src/lib/migration-003-nm-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"migration-003-nm-heal.js","sourceRoot":"","sources":["../../src/lib/migration-003-nm-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAY,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,kBAAkB,GAAG,wCAAwC,CAAC;AACpE,MAAM,cAAc,GAAG,kDAAkD,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,yCAAyC;IACzC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,sEAAsE;IACtE,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;YAEvF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;gBAC5C,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBAE5C,IAAI,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;wBACzF,IAAI,OAAO,GAAG,OAAO;6BAClB,OAAO,CAAC,6BAA6B,EAAE,EAAE,CAAC;6BAC1C,OAAO,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;wBAErD,iBAAiB;wBACjB,MAAM,GAAG,GAAG,kBAAkB,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC;wBACxD,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;wBAC5B,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;wBACxD,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;wBAC7D,IAAI,CAAC;4BAAC,UAAU,CAAC,GAAG,CAAC,CAAC;wBAAC,CAAC;wBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;wBAC/C,OAAO,GAAG,IAAI,CAAC;oBACjB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC;IACpC,CAAC;IAED,kDAAkD;IAClD,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,gGAAgG,CAAC;QACjH,MAAM,GAAG,GAAG,qBAAqB,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;QACnD,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,4BAA4B,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpF,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC;YAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC/C,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,gCAAgC;IAChC,IAAI,OAAO,EAAE,CAAC;QACZ,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Migration 009: Fix Docker bind-mount directory-vs-file confusion.
|
|
3
3
|
*
|
|
4
4
|
* Docker auto-creates missing bind-mount targets as DIRECTORIES.
|
|
5
|
-
* If alertmanager.yml
|
|
6
|
-
* (from a `docker compose up` before the files
|
|
7
|
-
* fail to start
|
|
8
|
-
* creates the correct
|
|
5
|
+
* If alertmanager.yml, tempo.yaml, or prometheus config files were
|
|
6
|
+
* created as directories (from a `docker compose up` before the files
|
|
7
|
+
* existed), the services fail to start or use wrong config. This
|
|
8
|
+
* migration removes the bogus directories and creates the correct
|
|
9
|
+
* stub config files.
|
|
9
10
|
*/
|
|
10
11
|
export declare function migrateBindMountFiles(): Promise<boolean>;
|
|
11
12
|
//# sourceMappingURL=migration-009-bind-mount-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-009-bind-mount-files.d.ts","sourceRoot":"","sources":["../../src/lib/migration-009-bind-mount-files.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"migration-009-bind-mount-files.d.ts","sourceRoot":"","sources":["../../src/lib/migration-009-bind-mount-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwFH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM9D"}
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
* Migration 009: Fix Docker bind-mount directory-vs-file confusion.
|
|
3
3
|
*
|
|
4
4
|
* Docker auto-creates missing bind-mount targets as DIRECTORIES.
|
|
5
|
-
* If alertmanager.yml
|
|
6
|
-
* (from a `docker compose up` before the files
|
|
7
|
-
* fail to start
|
|
8
|
-
* creates the correct
|
|
5
|
+
* If alertmanager.yml, tempo.yaml, or prometheus config files were
|
|
6
|
+
* created as directories (from a `docker compose up` before the files
|
|
7
|
+
* existed), the services fail to start or use wrong config. This
|
|
8
|
+
* migration removes the bogus directories and creates the correct
|
|
9
|
+
* stub config files.
|
|
9
10
|
*/
|
|
10
11
|
import { existsSync, statSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
11
12
|
import { join } from 'node:path';
|
|
12
|
-
import {
|
|
13
|
-
const INSTALL_DIR =
|
|
13
|
+
import { getPaths } from './paths.js';
|
|
14
|
+
const INSTALL_DIR = getPaths().installDir;
|
|
14
15
|
const ALERTMANAGER_DIR = join(INSTALL_DIR, 'alertmanager');
|
|
15
16
|
const ALERTMANAGER_FILE = join(ALERTMANAGER_DIR, 'alertmanager.yml');
|
|
16
17
|
const ALERTMANAGER_CONTENT = `global:
|
|
@@ -23,6 +24,11 @@ route:
|
|
|
23
24
|
receivers:
|
|
24
25
|
- name: 'default'
|
|
25
26
|
`;
|
|
27
|
+
const PROMETHEUS_DIR = join(INSTALL_DIR, 'prometheus');
|
|
28
|
+
const PROMETHEUS_CUSTOM_RULES_FILE = join(PROMETHEUS_DIR, 'custom_rules.yml');
|
|
29
|
+
const PROMETHEUS_CUSTOM_RULES_CONTENT = `groups: []\n`;
|
|
30
|
+
const PROMETHEUS_POSTGRES_QUERIES_FILE = join(PROMETHEUS_DIR, 'postgres-queries.yaml');
|
|
31
|
+
const PROMETHEUS_POSTGRES_QUERIES_CONTENT = `{}\n`;
|
|
26
32
|
const TEMPO_DIR = join(INSTALL_DIR, 'tempo');
|
|
27
33
|
const TEMPO_FILE = join(TEMPO_DIR, 'tempo.yaml');
|
|
28
34
|
const TEMPO_CONTENT = `server:
|
|
@@ -81,6 +87,8 @@ function fixBindMount(dir, filePath, content) {
|
|
|
81
87
|
export async function migrateBindMountFiles() {
|
|
82
88
|
const a = fixBindMount(ALERTMANAGER_DIR, ALERTMANAGER_FILE, ALERTMANAGER_CONTENT);
|
|
83
89
|
const b = fixBindMount(TEMPO_DIR, TEMPO_FILE, TEMPO_CONTENT);
|
|
84
|
-
|
|
90
|
+
const c = fixBindMount(PROMETHEUS_DIR, PROMETHEUS_CUSTOM_RULES_FILE, PROMETHEUS_CUSTOM_RULES_CONTENT);
|
|
91
|
+
const d = fixBindMount(PROMETHEUS_DIR, PROMETHEUS_POSTGRES_QUERIES_FILE, PROMETHEUS_POSTGRES_QUERIES_CONTENT);
|
|
92
|
+
return a || b || c || d;
|
|
85
93
|
}
|
|
86
94
|
//# sourceMappingURL=migration-009-bind-mount-files.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-009-bind-mount-files.js","sourceRoot":"","sources":["../../src/lib/migration-009-bind-mount-files.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"migration-009-bind-mount-files.js","sourceRoot":"","sources":["../../src/lib/migration-009-bind-mount-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,WAAW,GAAG,QAAQ,EAAE,CAAC,UAAU,CAAC;AAE1C,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;AAC3D,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;AACrE,MAAM,oBAAoB,GAAG;;;;;;;;;CAS5B,CAAC;AAEF,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AACvD,MAAM,4BAA4B,GAAG,IAAI,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;AAC9E,MAAM,+BAA+B,GAAG,cAAc,CAAC;AACvD,MAAM,gCAAgC,GAAG,IAAI,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;AACvF,MAAM,mCAAmC,GAAG,MAAM,CAAC;AAEnD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACjD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCrB,CAAC;AAEF,SAAS,YAAY,CAAC,GAAW,EAAE,QAAgB,EAAE,OAAe;IAClE,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,qEAAqE;IACrE,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7D,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,iCAAiC;IACjC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpC,sCAAsC;IACtC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,CAAC,GAAG,YAAY,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,CAAC,CAAC;IAClF,MAAM,CAAC,GAAG,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,YAAY,CAAC,cAAc,EAAE,4BAA4B,EAAE,+BAA+B,CAAC,CAAC;IACtG,MAAM,CAAC,GAAG,YAAY,CAAC,cAAc,EAAE,gCAAgC,EAAE,mCAAmC,CAAC,CAAC;IAC9G,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
11
11
|
import { join } from 'node:path';
|
|
12
|
-
import {
|
|
13
|
-
const INSTALL_DIR =
|
|
12
|
+
import { getPaths } from './paths.js';
|
|
13
|
+
const INSTALL_DIR = getPaths().installDir;
|
|
14
14
|
const ENV_FILE = join(INSTALL_DIR, '.env');
|
|
15
15
|
const JTAPI_STATE_FILE = join(INSTALL_DIR, '.jtapi-enabled');
|
|
16
16
|
function envGet(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-010-jtapi-state.js","sourceRoot":"","sources":["../../src/lib/migration-010-jtapi-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"migration-010-jtapi-state.js","sourceRoot":"","sources":["../../src/lib/migration-010-jtapi-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Also updates existing 80% limit to 90% (previous default was too conservative).
|
|
11
11
|
*/
|
|
12
|
-
import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
12
|
+
import { existsSync, writeFileSync, readFileSync, unlinkSync } from 'node:fs';
|
|
13
13
|
import { spawnSync } from 'node:child_process';
|
|
14
14
|
const DROPIN_DIR = '/etc/systemd/system/docker.service.d';
|
|
15
15
|
const DROPIN_FILE = `${DROPIN_DIR}/memory-limit.conf`;
|
|
@@ -28,7 +28,7 @@ export async function migrateDockerMemoryLimit() {
|
|
|
28
28
|
spawnSync('sudo', ['mkdir', '-p', DROPIN_DIR], { stdio: 'pipe' });
|
|
29
29
|
spawnSync('sudo', ['cp', tmp, DROPIN_FILE], { stdio: 'pipe' });
|
|
30
30
|
try {
|
|
31
|
-
|
|
31
|
+
unlinkSync(tmp);
|
|
32
32
|
}
|
|
33
33
|
catch { /* ignore */ }
|
|
34
34
|
const reload = spawnSync('sudo', ['systemctl', 'daemon-reload'], { stdio: 'pipe' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-011-docker-memory-limit.js","sourceRoot":"","sources":["../../src/lib/migration-011-docker-memory-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"migration-011-docker-memory-limit.js","sourceRoot":"","sources":["../../src/lib/migration-011-docker-memory-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,WAAW,GAAG,GAAG,UAAU,oBAAoB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,yBAAyB;IACzB,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,+CAA+C;IACjD,CAAC;IAED,MAAM,OAAO,GAAG,4BAA4B,CAAC;IAC7C,MAAM,GAAG,GAAG,yBAAyB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAClD,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAE5B,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC;QAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2CAA2C;IAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACzF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-012-db-pool-sizes.d.ts","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"migration-012-db-pool-sizes.d.ts","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CA6C3D"}
|
|
@@ -8,21 +8,12 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Does NOT override if connection sizing is already set — respects user choice.
|
|
10
10
|
*/
|
|
11
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
12
12
|
import { spawnSync } from 'node:child_process';
|
|
13
|
-
import { homedir } from 'node:os';
|
|
14
13
|
import { join } from 'node:path';
|
|
15
|
-
|
|
16
|
-
function getInstallDir() {
|
|
17
|
-
const known = ['/home/calltelemetry', '/opt/calltelemetry'];
|
|
18
|
-
for (const p of known) {
|
|
19
|
-
if (existsSync(join(p, 'docker-compose.yml')))
|
|
20
|
-
return p;
|
|
21
|
-
}
|
|
22
|
-
return homedir();
|
|
23
|
-
}
|
|
14
|
+
import { getPaths } from './paths.js';
|
|
24
15
|
export async function migrateDbPoolSizes() {
|
|
25
|
-
const installDir =
|
|
16
|
+
const { installDir } = getPaths();
|
|
26
17
|
const envFile = join(installDir, '.env');
|
|
27
18
|
// If any connection sizing is already set, user has chosen values — don't override
|
|
28
19
|
if (existsSync(envFile)) {
|
|
@@ -49,11 +40,11 @@ export async function migrateDbPoolSizes() {
|
|
|
49
40
|
const block = '\n# DB connection sizing: small (auto-applied by migration 012)\n' +
|
|
50
41
|
settings.join('\n') + '\n';
|
|
51
42
|
const tmp = `/tmp/ct-env-append-${Date.now()}`;
|
|
52
|
-
|
|
43
|
+
writeFileSync(tmp, block);
|
|
53
44
|
// Append via sudo
|
|
54
45
|
const result = spawnSync('sudo', ['bash', '-c', `cat ${tmp} >> ${envFile}`], { stdio: 'pipe' });
|
|
55
46
|
try {
|
|
56
|
-
|
|
47
|
+
unlinkSync(tmp);
|
|
57
48
|
}
|
|
58
49
|
catch { /* ignore */ }
|
|
59
50
|
if (result.status !== 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-012-db-pool-sizes.js","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"migration-012-db-pool-sizes.js","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEzC,mFAAmF;IACnF,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,IACE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;YACjC,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC9C,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC5C,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAC3C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EACtC,CAAC;YACD,OAAO,KAAK,CAAC,CAAC,qBAAqB;QACrC,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,MAAM,QAAQ,GAAG;QACf,wBAAwB;QACxB,iBAAiB;QACjB,8BAA8B;QAC9B,4BAA4B;QAC5B,2BAA2B;QAC3B,sBAAsB;KACvB,CAAC;IAEF,gCAAgC;IAChC,MAAM,KAAK,GAAG,mEAAmE;QAC/E,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE7B,MAAM,GAAG,GAAG,sBAAsB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC/C,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE1B,kBAAkB;IAClB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC;QAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAE/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-013-grafana-password.d.ts","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"migration-013-grafana-password.d.ts","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAoE/D"}
|
|
@@ -11,21 +11,13 @@
|
|
|
11
11
|
* 3. Removes stale GRAFANA_TOKEN if present
|
|
12
12
|
* 4. Resets Grafana admin password via grafana-cli (for existing volumes)
|
|
13
13
|
*/
|
|
14
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
14
|
+
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
15
15
|
import { randomBytes } from 'node:crypto';
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
|
-
import { homedir } from 'node:os';
|
|
18
17
|
import { join } from 'node:path';
|
|
19
|
-
|
|
20
|
-
const known = ['/home/calltelemetry', '/opt/calltelemetry'];
|
|
21
|
-
for (const p of known) {
|
|
22
|
-
if (existsSync(join(p, 'docker-compose.yml')))
|
|
23
|
-
return p;
|
|
24
|
-
}
|
|
25
|
-
return homedir();
|
|
26
|
-
}
|
|
18
|
+
import { getPaths } from './paths.js';
|
|
27
19
|
export async function migrateGrafanaPassword() {
|
|
28
|
-
const installDir =
|
|
20
|
+
const { installDir } = getPaths();
|
|
29
21
|
const envFile = join(installDir, '.env');
|
|
30
22
|
// If GRAFANA_PASSWORD is already set, nothing to do
|
|
31
23
|
if (existsSync(envFile)) {
|
|
@@ -40,13 +32,13 @@ export async function migrateGrafanaPassword() {
|
|
|
40
32
|
const block = '\n# Grafana auth password (auto-generated by migration 013)\n' +
|
|
41
33
|
`GRAFANA_PASSWORD=${password}\n`;
|
|
42
34
|
const tmp = `/tmp/ct-grafana-pw-${Date.now()}`;
|
|
43
|
-
|
|
35
|
+
writeFileSync(tmp, block);
|
|
44
36
|
// Append to .env
|
|
45
37
|
const appendResult = spawnSync('sudo', ['bash', '-c', `cat ${tmp} >> ${envFile}`], {
|
|
46
38
|
stdio: 'pipe',
|
|
47
39
|
});
|
|
48
40
|
try {
|
|
49
|
-
|
|
41
|
+
unlinkSync(tmp);
|
|
50
42
|
}
|
|
51
43
|
catch {
|
|
52
44
|
/* ignore */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-013-grafana-password.js","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"migration-013-grafana-password.js","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type PerformanceStatus = 'ok' | 'warn' | 'fail' | 'info';
|
|
2
|
+
export interface PostgresSetting {
|
|
3
|
+
setting: string | null;
|
|
4
|
+
source: string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface PostgresWalStats {
|
|
7
|
+
walRecords: number | null;
|
|
8
|
+
walFpi: number | null;
|
|
9
|
+
walBytes: number | null;
|
|
10
|
+
walWrites: number | null;
|
|
11
|
+
walSyncs: number | null;
|
|
12
|
+
walWriteTimeMs: number | null;
|
|
13
|
+
walSyncTimeMs: number | null;
|
|
14
|
+
avgWalWriteMs: number | null;
|
|
15
|
+
avgWalSyncMs: number | null;
|
|
16
|
+
statsReset: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface PostgresDatabaseIoStats {
|
|
19
|
+
blocksRead: number | null;
|
|
20
|
+
blocksHit: number | null;
|
|
21
|
+
cacheHitPct: number | null;
|
|
22
|
+
blockReadTimeMs: number | null;
|
|
23
|
+
blockWriteTimeMs: number | null;
|
|
24
|
+
tempBytes: number | null;
|
|
25
|
+
}
|
|
26
|
+
export interface PgmetricsSnapshot {
|
|
27
|
+
available: boolean;
|
|
28
|
+
reason?: string;
|
|
29
|
+
collectedAt?: string;
|
|
30
|
+
walRateBytesSec: number | null;
|
|
31
|
+
walSyncLatencyMs5m: number | null;
|
|
32
|
+
}
|
|
33
|
+
export interface PostgresPerformance {
|
|
34
|
+
trackIoTiming: PostgresSetting;
|
|
35
|
+
trackWalIoTiming: PostgresSetting;
|
|
36
|
+
wal: PostgresWalStats | null;
|
|
37
|
+
databaseIo: PostgresDatabaseIoStats | null;
|
|
38
|
+
snapshot: PgmetricsSnapshot;
|
|
39
|
+
}
|
|
40
|
+
export interface PostgresPerformanceLine {
|
|
41
|
+
label: string;
|
|
42
|
+
value: string;
|
|
43
|
+
status: PerformanceStatus;
|
|
44
|
+
}
|
|
45
|
+
export declare function fetchPostgresPerformance(): Promise<PostgresPerformance>;
|
|
46
|
+
export declare function formatBytes(bytes: number | null): string;
|
|
47
|
+
export declare function formatRate(bytesPerSecond: number | null): string;
|
|
48
|
+
export declare function formatMs(ms: number | null): string;
|
|
49
|
+
export declare function walLatencyStatus(ms: number | null): PerformanceStatus;
|
|
50
|
+
export declare function postgresPerformanceLines(perf: PostgresPerformance): PostgresPerformanceLine[];
|
|
51
|
+
//# sourceMappingURL=postgres-performance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-performance.d.ts","sourceRoot":"","sources":["../../src/lib/postgres-performance.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,eAAe,CAAC;IAC/B,gBAAgB,EAAE,eAAe,CAAC;IAClC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAuLD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAc7E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAOxD;AAED,wBAAgB,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGhE;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKlD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,CAKrE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB,EAAE,CAmE7F"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { composeExec } from './compose.js';
|
|
2
|
+
import { DB_NAME, DB_USER, PG_ENV } from './db.js';
|
|
3
|
+
function parseNumber(value) {
|
|
4
|
+
if (value === undefined || value.trim() === '')
|
|
5
|
+
return null;
|
|
6
|
+
const parsed = Number(value);
|
|
7
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
8
|
+
}
|
|
9
|
+
function isOn(setting) {
|
|
10
|
+
return setting.setting === 'on';
|
|
11
|
+
}
|
|
12
|
+
function sourceSuffix(setting) {
|
|
13
|
+
return setting.source ? ` (${setting.source})` : '';
|
|
14
|
+
}
|
|
15
|
+
async function psqlRows(sql) {
|
|
16
|
+
const result = await composeExec('db', ['psql', '-U', DB_USER, '-d', DB_NAME, '-t', '-A', '-F', '|', '-c', sql], { env: PG_ENV, pipe: true });
|
|
17
|
+
return (result.stdout ?? '')
|
|
18
|
+
.trim()
|
|
19
|
+
.split('\n')
|
|
20
|
+
.map((line) => line.trim())
|
|
21
|
+
.filter(Boolean)
|
|
22
|
+
.map((line) => line.split('|').map((part) => part.trim()));
|
|
23
|
+
}
|
|
24
|
+
async function fetchTimingSettings() {
|
|
25
|
+
const rows = await psqlRows(`
|
|
26
|
+
SELECT name, setting, source
|
|
27
|
+
FROM pg_settings
|
|
28
|
+
WHERE name IN ('track_io_timing', 'track_wal_io_timing')
|
|
29
|
+
ORDER BY name;
|
|
30
|
+
`);
|
|
31
|
+
const settings = new Map(rows.map((row) => [row[0], { setting: row[1] ?? null, source: row[2] ?? null }]));
|
|
32
|
+
return {
|
|
33
|
+
trackIoTiming: settings.get('track_io_timing') ?? { setting: null, source: null },
|
|
34
|
+
trackWalIoTiming: settings.get('track_wal_io_timing') ?? { setting: null, source: null },
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function fetchWalStats(trackWalIoTiming) {
|
|
38
|
+
try {
|
|
39
|
+
const rows = await psqlRows(`
|
|
40
|
+
SELECT
|
|
41
|
+
wal_records,
|
|
42
|
+
wal_fpi,
|
|
43
|
+
wal_bytes,
|
|
44
|
+
wal_write,
|
|
45
|
+
wal_sync,
|
|
46
|
+
wal_write_time,
|
|
47
|
+
wal_sync_time,
|
|
48
|
+
COALESCE(to_char(stats_reset, 'YYYY-MM-DD HH24:MI:SS TZ'), '')
|
|
49
|
+
FROM pg_stat_wal;
|
|
50
|
+
`);
|
|
51
|
+
const row = rows[0];
|
|
52
|
+
if (!row)
|
|
53
|
+
return null;
|
|
54
|
+
const walWrites = parseNumber(row[3]);
|
|
55
|
+
const walSyncs = parseNumber(row[4]);
|
|
56
|
+
const walWriteTimeMs = parseNumber(row[5]);
|
|
57
|
+
const walSyncTimeMs = parseNumber(row[6]);
|
|
58
|
+
const timingEnabled = isOn(trackWalIoTiming);
|
|
59
|
+
return {
|
|
60
|
+
walRecords: parseNumber(row[0]),
|
|
61
|
+
walFpi: parseNumber(row[1]),
|
|
62
|
+
walBytes: parseNumber(row[2]),
|
|
63
|
+
walWrites,
|
|
64
|
+
walSyncs,
|
|
65
|
+
walWriteTimeMs,
|
|
66
|
+
walSyncTimeMs,
|
|
67
|
+
avgWalWriteMs: timingEnabled && walWrites && walWrites > 0 && walWriteTimeMs !== null
|
|
68
|
+
? walWriteTimeMs / walWrites
|
|
69
|
+
: null,
|
|
70
|
+
avgWalSyncMs: timingEnabled && walSyncs && walSyncs > 0 && walSyncTimeMs !== null
|
|
71
|
+
? walSyncTimeMs / walSyncs
|
|
72
|
+
: null,
|
|
73
|
+
statsReset: row[7] || null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function fetchDatabaseIoStats() {
|
|
81
|
+
try {
|
|
82
|
+
const rows = await psqlRows(`
|
|
83
|
+
SELECT
|
|
84
|
+
blks_read,
|
|
85
|
+
blks_hit,
|
|
86
|
+
CASE
|
|
87
|
+
WHEN (blks_hit + blks_read) = 0 THEN NULL
|
|
88
|
+
ELSE round((blks_hit::numeric * 100.0) / (blks_hit + blks_read), 2)
|
|
89
|
+
END,
|
|
90
|
+
blk_read_time,
|
|
91
|
+
blk_write_time,
|
|
92
|
+
temp_bytes
|
|
93
|
+
FROM pg_stat_database
|
|
94
|
+
WHERE datname = current_database();
|
|
95
|
+
`);
|
|
96
|
+
const row = rows[0];
|
|
97
|
+
if (!row)
|
|
98
|
+
return null;
|
|
99
|
+
return {
|
|
100
|
+
blocksRead: parseNumber(row[0]),
|
|
101
|
+
blocksHit: parseNumber(row[1]),
|
|
102
|
+
cacheHitPct: parseNumber(row[2]),
|
|
103
|
+
blockReadTimeMs: parseNumber(row[3]),
|
|
104
|
+
blockWriteTimeMs: parseNumber(row[4]),
|
|
105
|
+
tempBytes: parseNumber(row[5]),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function fetchPgmetricsSnapshot() {
|
|
113
|
+
try {
|
|
114
|
+
const availability = await psqlRows(`
|
|
115
|
+
SELECT EXISTS (
|
|
116
|
+
SELECT 1
|
|
117
|
+
FROM information_schema.columns
|
|
118
|
+
WHERE table_schema = 'public'
|
|
119
|
+
AND table_name = 'pgmetrics_snapshots'
|
|
120
|
+
AND column_name = 'wal_sync_latency_ms_5m'
|
|
121
|
+
);
|
|
122
|
+
`);
|
|
123
|
+
if (availability[0]?.[0] !== 't') {
|
|
124
|
+
return {
|
|
125
|
+
available: false,
|
|
126
|
+
reason: 'pgmetrics WAL latency column unavailable',
|
|
127
|
+
walRateBytesSec: null,
|
|
128
|
+
walSyncLatencyMs5m: null,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const rows = await psqlRows(`
|
|
132
|
+
SELECT
|
|
133
|
+
COALESCE(to_char(collected_at, 'YYYY-MM-DD HH24:MI:SS TZ'), ''),
|
|
134
|
+
COALESCE(wal_rate_bytes_sec::text, ''),
|
|
135
|
+
COALESCE(wal_sync_latency_ms_5m::text, '')
|
|
136
|
+
FROM pgmetrics_snapshots
|
|
137
|
+
ORDER BY collected_at DESC
|
|
138
|
+
LIMIT 1;
|
|
139
|
+
`);
|
|
140
|
+
const row = rows[0];
|
|
141
|
+
if (!row) {
|
|
142
|
+
return {
|
|
143
|
+
available: false,
|
|
144
|
+
reason: 'no pgmetrics snapshot yet',
|
|
145
|
+
walRateBytesSec: null,
|
|
146
|
+
walSyncLatencyMs5m: null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
available: true,
|
|
151
|
+
collectedAt: row[0] || undefined,
|
|
152
|
+
walRateBytesSec: parseNumber(row[1]),
|
|
153
|
+
walSyncLatencyMs5m: parseNumber(row[2]),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return {
|
|
158
|
+
available: false,
|
|
159
|
+
reason: 'pgmetrics snapshot query failed',
|
|
160
|
+
walRateBytesSec: null,
|
|
161
|
+
walSyncLatencyMs5m: null,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export async function fetchPostgresPerformance() {
|
|
166
|
+
const settings = await fetchTimingSettings();
|
|
167
|
+
const [wal, databaseIo, snapshot] = await Promise.all([
|
|
168
|
+
fetchWalStats(settings.trackWalIoTiming),
|
|
169
|
+
fetchDatabaseIoStats(),
|
|
170
|
+
fetchPgmetricsSnapshot(),
|
|
171
|
+
]);
|
|
172
|
+
return {
|
|
173
|
+
...settings,
|
|
174
|
+
wal,
|
|
175
|
+
databaseIo,
|
|
176
|
+
snapshot,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
export function formatBytes(bytes) {
|
|
180
|
+
if (bytes === null)
|
|
181
|
+
return 'unavailable';
|
|
182
|
+
if (bytes >= 1024 ** 4)
|
|
183
|
+
return `${(bytes / 1024 ** 4).toFixed(1)} TB`;
|
|
184
|
+
if (bytes >= 1024 ** 3)
|
|
185
|
+
return `${(bytes / 1024 ** 3).toFixed(1)} GB`;
|
|
186
|
+
if (bytes >= 1024 ** 2)
|
|
187
|
+
return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
|
|
188
|
+
if (bytes >= 1024)
|
|
189
|
+
return `${(bytes / 1024).toFixed(1)} kB`;
|
|
190
|
+
return `${bytes.toFixed(0)} B`;
|
|
191
|
+
}
|
|
192
|
+
export function formatRate(bytesPerSecond) {
|
|
193
|
+
if (bytesPerSecond === null)
|
|
194
|
+
return 'unavailable';
|
|
195
|
+
return `${formatBytes(bytesPerSecond)}/s`;
|
|
196
|
+
}
|
|
197
|
+
export function formatMs(ms) {
|
|
198
|
+
if (ms === null)
|
|
199
|
+
return 'unavailable';
|
|
200
|
+
if (ms >= 100)
|
|
201
|
+
return `${ms.toFixed(0)} ms`;
|
|
202
|
+
if (ms >= 10)
|
|
203
|
+
return `${ms.toFixed(1)} ms`;
|
|
204
|
+
return `${ms.toFixed(2)} ms`;
|
|
205
|
+
}
|
|
206
|
+
export function walLatencyStatus(ms) {
|
|
207
|
+
if (ms === null)
|
|
208
|
+
return 'info';
|
|
209
|
+
if (ms >= 200)
|
|
210
|
+
return 'fail';
|
|
211
|
+
if (ms >= 50)
|
|
212
|
+
return 'warn';
|
|
213
|
+
return 'ok';
|
|
214
|
+
}
|
|
215
|
+
export function postgresPerformanceLines(perf) {
|
|
216
|
+
const lines = [
|
|
217
|
+
{
|
|
218
|
+
label: 'track_io_timing',
|
|
219
|
+
value: `${perf.trackIoTiming.setting ?? 'unavailable'}${sourceSuffix(perf.trackIoTiming)}`,
|
|
220
|
+
status: isOn(perf.trackIoTiming) ? 'ok' : 'warn',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
label: 'track_wal_io_timing',
|
|
224
|
+
value: `${perf.trackWalIoTiming.setting ?? 'unavailable'}${sourceSuffix(perf.trackWalIoTiming)}`,
|
|
225
|
+
status: isOn(perf.trackWalIoTiming) ? 'ok' : 'fail',
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
if (perf.snapshot.available) {
|
|
229
|
+
const latency = perf.snapshot.walSyncLatencyMs5m;
|
|
230
|
+
lines.push({
|
|
231
|
+
label: 'WAL sync latency 5m',
|
|
232
|
+
value: latency === null
|
|
233
|
+
? 'unavailable'
|
|
234
|
+
: `${formatMs(latency)}${perf.snapshot.collectedAt ? ` at ${perf.snapshot.collectedAt}` : ''}`,
|
|
235
|
+
status: walLatencyStatus(latency),
|
|
236
|
+
});
|
|
237
|
+
lines.push({
|
|
238
|
+
label: 'WAL throughput 5m',
|
|
239
|
+
value: formatRate(perf.snapshot.walRateBytesSec),
|
|
240
|
+
status: 'info',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
lines.push({
|
|
245
|
+
label: 'WAL sync latency 5m',
|
|
246
|
+
value: perf.snapshot.reason ?? 'unavailable',
|
|
247
|
+
status: isOn(perf.trackWalIoTiming) ? 'info' : 'fail',
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (perf.wal) {
|
|
251
|
+
lines.push({
|
|
252
|
+
label: 'WAL sync average',
|
|
253
|
+
value: `${formatMs(perf.wal.avgWalSyncMs)} since stats reset`,
|
|
254
|
+
status: isOn(perf.trackWalIoTiming) ? walLatencyStatus(perf.wal.avgWalSyncMs) : 'fail',
|
|
255
|
+
});
|
|
256
|
+
lines.push({
|
|
257
|
+
label: 'WAL generated',
|
|
258
|
+
value: formatBytes(perf.wal.walBytes),
|
|
259
|
+
status: 'info',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (perf.databaseIo?.cacheHitPct !== null && perf.databaseIo?.cacheHitPct !== undefined) {
|
|
263
|
+
const cacheHitPct = perf.databaseIo.cacheHitPct;
|
|
264
|
+
lines.push({
|
|
265
|
+
label: 'DB cache hit rate',
|
|
266
|
+
value: `${cacheHitPct.toFixed(2)}%`,
|
|
267
|
+
status: cacheHitPct >= 99 ? 'ok' : cacheHitPct >= 95 ? 'warn' : 'fail',
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
if (perf.databaseIo) {
|
|
271
|
+
lines.push({
|
|
272
|
+
label: 'DB read/write timing',
|
|
273
|
+
value: `read ${formatMs(perf.databaseIo.blockReadTimeMs)}, write ${formatMs(perf.databaseIo.blockWriteTimeMs)}`,
|
|
274
|
+
status: isOn(perf.trackIoTiming) ? 'info' : 'warn',
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return lines;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=postgres-performance.js.map
|