quicklify 0.5.0 → 0.6.0
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 +47 -2
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +92 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/health.d.ts +9 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +56 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/logs.d.ts +8 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +53 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/monitor.d.ts +13 -0
- package/dist/commands/monitor.d.ts.map +1 -0
- package/dist/commands/monitor.js +94 -0
- package/dist/commands/monitor.js.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/ssh.d.ts +1 -0
- package/dist/utils/ssh.d.ts.map +1 -1
- package/dist/utils/ssh.js +7 -0
- package/dist/utils/ssh.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,6 +50,10 @@ npx quicklify init
|
|
|
50
50
|
- 🔑 **SSH Access** - Connect to servers or run remote commands
|
|
51
51
|
- 🔄 **Coolify Update** - Update Coolify with one command
|
|
52
52
|
- 🏥 **Health Check Polling** - Detects when Coolify is ready (no more blind waiting)
|
|
53
|
+
- 📊 **Server Monitoring** - CPU/RAM/Disk usage and Docker container status
|
|
54
|
+
- 📜 **Log Viewer** - View Coolify, Docker, or system logs with follow mode
|
|
55
|
+
- 🩺 **Environment Doctor** - Diagnose local setup issues
|
|
56
|
+
- 🫀 **Bulk Health Check** - Check all servers at once
|
|
53
57
|
- 🤖 **Non-Interactive Mode** - CI/CD friendly with `--provider --token --region --size --name` flags
|
|
54
58
|
|
|
55
59
|
## 📦 Installation
|
|
@@ -162,6 +166,14 @@ For production use, we recommend setting up a domain instead of using the IP add
|
|
|
162
166
|
|
|
163
167
|
## 📋 Recent Updates
|
|
164
168
|
|
|
169
|
+
### v0.6.0 (2026-02-20)
|
|
170
|
+
- **New commands:** `quicklify logs`, `quicklify monitor`, `quicklify health`, `quicklify doctor`
|
|
171
|
+
- **Log viewer:** View Coolify/Docker/system logs with `--follow` real-time streaming
|
|
172
|
+
- **Server monitoring:** CPU/RAM/Disk usage and Docker container list
|
|
173
|
+
- **Bulk health check:** Check all registered servers at once with response times
|
|
174
|
+
- **Environment doctor:** Diagnose Node.js, SSH, config issues locally
|
|
175
|
+
- Zero new dependencies, 354 tests with 97%+ statement coverage
|
|
176
|
+
|
|
165
177
|
### v0.5.0 (2026-02-20)
|
|
166
178
|
- **New commands:** `quicklify config`, `quicklify ssh`, `quicklify update`, `quicklify restart`
|
|
167
179
|
- **Default config:** Set defaults for provider, region, size with `quicklify config set`
|
|
@@ -238,12 +250,19 @@ For production use, we recommend setting up a domain instead of using the IP add
|
|
|
238
250
|
- [x] Server restart via provider API (`quicklify restart`)
|
|
239
251
|
- [x] Shared server selection and token utilities (DRY refactor)
|
|
240
252
|
|
|
253
|
+
### v0.6.0 (Completed)
|
|
254
|
+
|
|
255
|
+
- [x] Server monitoring - CPU/RAM/Disk usage (`quicklify monitor`)
|
|
256
|
+
- [x] Log viewer - Coolify/Docker/system logs (`quicklify logs`)
|
|
257
|
+
- [x] Bulk health check for all servers (`quicklify health`)
|
|
258
|
+
- [x] Environment diagnostics (`quicklify doctor`)
|
|
259
|
+
- [x] SSH streaming for real-time log following
|
|
260
|
+
|
|
241
261
|
### Future
|
|
242
262
|
- [ ] Vultr support
|
|
243
263
|
- [ ] Linode / AWS Lightsail support
|
|
244
264
|
- [ ] Domain + SSL configuration helper
|
|
245
265
|
- [ ] Backup/restore commands
|
|
246
|
-
- [ ] Server monitoring (CPU/RAM/Disk)
|
|
247
266
|
- [ ] Interactive TUI dashboard
|
|
248
267
|
- [ ] Firewall management
|
|
249
268
|
|
|
@@ -298,6 +317,28 @@ quicklify update my-server
|
|
|
298
317
|
# Restart a server
|
|
299
318
|
quicklify restart my-server
|
|
300
319
|
|
|
320
|
+
# View Coolify logs (last 50 lines)
|
|
321
|
+
quicklify logs my-server
|
|
322
|
+
|
|
323
|
+
# Follow Coolify logs in real-time
|
|
324
|
+
quicklify logs my-server --follow
|
|
325
|
+
|
|
326
|
+
# View Docker or system logs
|
|
327
|
+
quicklify logs my-server --service docker --lines 100
|
|
328
|
+
quicklify logs my-server --service system
|
|
329
|
+
|
|
330
|
+
# Show CPU/RAM/Disk usage
|
|
331
|
+
quicklify monitor my-server
|
|
332
|
+
|
|
333
|
+
# Show usage with Docker containers
|
|
334
|
+
quicklify monitor my-server --containers
|
|
335
|
+
|
|
336
|
+
# Check health of all servers
|
|
337
|
+
quicklify health
|
|
338
|
+
|
|
339
|
+
# Run environment diagnostics
|
|
340
|
+
quicklify doctor
|
|
341
|
+
|
|
301
342
|
# Show version
|
|
302
343
|
quicklify --version
|
|
303
344
|
|
|
@@ -378,10 +419,14 @@ tests/
|
|
|
378
419
|
│ ├── config-command.test.ts # Config command subcommands
|
|
379
420
|
│ ├── defaults.test.ts # Default config CRUD
|
|
380
421
|
│ ├── destroy.test.ts # Destroy command unit tests
|
|
422
|
+
│ ├── doctor.test.ts # Doctor command tests
|
|
423
|
+
│ ├── health-command.test.ts # Health command tests
|
|
381
424
|
│ ├── healthCheck.test.ts # Health check polling tests
|
|
382
425
|
│ ├── healthCheck-edge.test.ts # Health check edge cases (302, 401, 500)
|
|
383
426
|
│ ├── list.test.ts # List command unit tests
|
|
384
427
|
│ ├── logger.test.ts
|
|
428
|
+
│ ├── logs.test.ts # Logs command tests
|
|
429
|
+
│ ├── monitor.test.ts # Monitor command tests
|
|
385
430
|
│ ├── prompts.test.ts
|
|
386
431
|
│ ├── providerFactory.test.ts # Provider factory tests
|
|
387
432
|
│ ├── restart.test.ts # Restart command tests
|
|
@@ -410,7 +455,7 @@ Tests run automatically on every push/PR via GitHub Actions across:
|
|
|
410
455
|
|
|
411
456
|
### Coverage
|
|
412
457
|
|
|
413
|
-
Current coverage: **97%+ statements/lines**, **
|
|
458
|
+
Current coverage: **97%+ statements/lines**, **87%+ branches**, **96%+ functions**. 354 tests across 29 test suites.
|
|
414
459
|
|
|
415
460
|
## 🔧 Troubleshooting
|
|
416
461
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CheckResult {
|
|
2
|
+
name: string;
|
|
3
|
+
status: "pass" | "fail" | "warn";
|
|
4
|
+
detail: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function runDoctorChecks(version?: string): CheckResult[];
|
|
7
|
+
export declare function doctorCommand(options?: {
|
|
8
|
+
checkTokens?: boolean;
|
|
9
|
+
}, version?: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAsDD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAS/D;AAED,wBAAsB,aAAa,CACjC,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,EACnC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { existsSync, accessSync, constants } from "fs";
|
|
3
|
+
import { getServers } from "../utils/config.js";
|
|
4
|
+
import { checkSshAvailable } from "../utils/ssh.js";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { CONFIG_DIR } from "../utils/config.js";
|
|
7
|
+
function checkNodeVersion() {
|
|
8
|
+
const version = process.version;
|
|
9
|
+
const major = parseInt(version.slice(1).split(".")[0], 10);
|
|
10
|
+
if (major >= 20) {
|
|
11
|
+
return { name: "Node.js", status: "pass", detail: version };
|
|
12
|
+
}
|
|
13
|
+
return { name: "Node.js", status: "fail", detail: `${version} (requires >= 20)` };
|
|
14
|
+
}
|
|
15
|
+
function checkNpmVersion() {
|
|
16
|
+
try {
|
|
17
|
+
const version = execSync("npm --version", { stdio: "pipe" }).toString().trim();
|
|
18
|
+
return { name: "npm", status: "pass", detail: `v${version}` };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { name: "npm", status: "fail", detail: "not found" };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function checkSsh() {
|
|
25
|
+
if (checkSshAvailable()) {
|
|
26
|
+
return { name: "SSH Client", status: "pass", detail: "available" };
|
|
27
|
+
}
|
|
28
|
+
return { name: "SSH Client", status: "warn", detail: "not found (needed for ssh/logs/monitor/update)" };
|
|
29
|
+
}
|
|
30
|
+
function checkQuicklifyVersion(version) {
|
|
31
|
+
if (version) {
|
|
32
|
+
return { name: "quicklify", status: "pass", detail: `v${version}` };
|
|
33
|
+
}
|
|
34
|
+
return { name: "quicklify", status: "warn", detail: "version unknown" };
|
|
35
|
+
}
|
|
36
|
+
function checkConfigDir() {
|
|
37
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
38
|
+
return { name: "Config Dir", status: "warn", detail: `${CONFIG_DIR} (not created yet)` };
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
accessSync(CONFIG_DIR, constants.R_OK | constants.W_OK);
|
|
42
|
+
return { name: "Config Dir", status: "pass", detail: CONFIG_DIR };
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { name: "Config Dir", status: "fail", detail: `${CONFIG_DIR} (not writable)` };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function checkRegisteredServers() {
|
|
49
|
+
const servers = getServers();
|
|
50
|
+
if (servers.length === 0) {
|
|
51
|
+
return { name: "Servers", status: "warn", detail: "0 registered (run quicklify init)" };
|
|
52
|
+
}
|
|
53
|
+
return { name: "Servers", status: "pass", detail: `${servers.length} registered` };
|
|
54
|
+
}
|
|
55
|
+
export function runDoctorChecks(version) {
|
|
56
|
+
return [
|
|
57
|
+
checkNodeVersion(),
|
|
58
|
+
checkNpmVersion(),
|
|
59
|
+
checkSsh(),
|
|
60
|
+
checkQuicklifyVersion(version),
|
|
61
|
+
checkConfigDir(),
|
|
62
|
+
checkRegisteredServers(),
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
export async function doctorCommand(options, version) {
|
|
66
|
+
logger.title("Quicklify Doctor");
|
|
67
|
+
const results = runDoctorChecks(version);
|
|
68
|
+
for (const result of results) {
|
|
69
|
+
const colorFn = result.status === "pass"
|
|
70
|
+
? logger.success
|
|
71
|
+
: result.status === "warn"
|
|
72
|
+
? logger.warning
|
|
73
|
+
: logger.error;
|
|
74
|
+
colorFn(`${result.name}: ${result.detail}`);
|
|
75
|
+
}
|
|
76
|
+
const failures = results.filter((r) => r.status === "fail");
|
|
77
|
+
const warnings = results.filter((r) => r.status === "warn");
|
|
78
|
+
console.log();
|
|
79
|
+
if (failures.length > 0) {
|
|
80
|
+
logger.error(`${failures.length} check(s) failed. Please fix the issues above.`);
|
|
81
|
+
}
|
|
82
|
+
else if (warnings.length > 0) {
|
|
83
|
+
logger.warning(`All checks passed with ${warnings.length} warning(s).`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
logger.success("All checks passed! Your environment is ready.");
|
|
87
|
+
}
|
|
88
|
+
if (options?.checkTokens) {
|
|
89
|
+
logger.info("Token validation is not yet implemented.");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ServerRecord } from "../types/index.js";
|
|
2
|
+
export interface HealthResult {
|
|
3
|
+
server: ServerRecord;
|
|
4
|
+
status: "healthy" | "unhealthy" | "unreachable";
|
|
5
|
+
responseTime: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function checkServerHealth(server: ServerRecord): Promise<HealthResult>;
|
|
8
|
+
export declare function healthCommand(): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAcnF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA+CnD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { getServers } from "../utils/config.js";
|
|
3
|
+
import { logger, createSpinner } from "../utils/logger.js";
|
|
4
|
+
export async function checkServerHealth(server) {
|
|
5
|
+
const start = Date.now();
|
|
6
|
+
try {
|
|
7
|
+
const response = await axios.get(`http://${server.ip}:8000`, {
|
|
8
|
+
timeout: 5000,
|
|
9
|
+
validateStatus: () => true,
|
|
10
|
+
});
|
|
11
|
+
const responseTime = Date.now() - start;
|
|
12
|
+
const status = response.status < 500 ? "healthy" : "unhealthy";
|
|
13
|
+
return { server, status, responseTime };
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
const responseTime = Date.now() - start;
|
|
17
|
+
return { server, status: "unreachable", responseTime };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function healthCommand() {
|
|
21
|
+
const servers = getServers();
|
|
22
|
+
if (servers.length === 0) {
|
|
23
|
+
logger.info("No servers found. Deploy one with: quicklify init");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const spinner = createSpinner(`Checking health of ${servers.length} server(s)...`);
|
|
27
|
+
spinner.start();
|
|
28
|
+
const results = await Promise.all(servers.map(checkServerHealth));
|
|
29
|
+
spinner.succeed("Health check complete");
|
|
30
|
+
console.log();
|
|
31
|
+
// Table header
|
|
32
|
+
const header = `${"Name".padEnd(20)} ${"IP".padEnd(16)} ${"Status".padEnd(14)} ${"Response".padEnd(10)}`;
|
|
33
|
+
console.log(header);
|
|
34
|
+
console.log("─".repeat(header.length));
|
|
35
|
+
// Table rows
|
|
36
|
+
for (const result of results) {
|
|
37
|
+
const statusStr = result.status === "healthy"
|
|
38
|
+
? "✔ healthy"
|
|
39
|
+
: result.status === "unhealthy"
|
|
40
|
+
? "⚠ unhealthy"
|
|
41
|
+
: "✖ unreachable";
|
|
42
|
+
const timeStr = result.status === "unreachable" ? "timeout" : `${result.responseTime}ms`;
|
|
43
|
+
console.log(`${result.server.name.padEnd(20)} ${result.server.ip.padEnd(16)} ${statusStr.padEnd(14)} ${timeStr.padEnd(10)}`);
|
|
44
|
+
}
|
|
45
|
+
console.log();
|
|
46
|
+
const healthy = results.filter((r) => r.status === "healthy").length;
|
|
47
|
+
const unhealthy = results.filter((r) => r.status === "unhealthy").length;
|
|
48
|
+
const unreachable = results.filter((r) => r.status === "unreachable").length;
|
|
49
|
+
if (unreachable > 0 || unhealthy > 0) {
|
|
50
|
+
logger.warning(`${healthy} healthy, ${unhealthy} unhealthy, ${unreachable} unreachable`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
logger.success(`All ${healthy} server(s) are healthy`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type LogService = "coolify" | "docker" | "system";
|
|
2
|
+
export declare function buildLogCommand(service: LogService, lines: number, follow: boolean): string;
|
|
3
|
+
export declare function logsCommand(query?: string, options?: {
|
|
4
|
+
lines?: string;
|
|
5
|
+
follow?: boolean;
|
|
6
|
+
service?: string;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzD,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAS3F;AAED,wBAAsB,WAAW,CAC/B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAwCf"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { resolveServer } from "../utils/serverSelect.js";
|
|
2
|
+
import { checkSshAvailable, sshExec, sshStream } from "../utils/ssh.js";
|
|
3
|
+
import { logger } from "../utils/logger.js";
|
|
4
|
+
export function buildLogCommand(service, lines, follow) {
|
|
5
|
+
switch (service) {
|
|
6
|
+
case "coolify":
|
|
7
|
+
return `docker logs coolify --tail ${lines}${follow ? " --follow" : ""}`;
|
|
8
|
+
case "docker":
|
|
9
|
+
return `journalctl -u docker --no-pager -n ${lines}${follow ? " -f" : ""}`;
|
|
10
|
+
case "system":
|
|
11
|
+
return `journalctl --no-pager -n ${lines}${follow ? " -f" : ""}`;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function logsCommand(query, options) {
|
|
15
|
+
if (!checkSshAvailable()) {
|
|
16
|
+
logger.error("SSH client not found. Please install OpenSSH.");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const server = await resolveServer(query, "Select a server to view logs:");
|
|
20
|
+
if (!server)
|
|
21
|
+
return;
|
|
22
|
+
const lines = parseInt(options?.lines || "50", 10);
|
|
23
|
+
if (isNaN(lines) || lines <= 0) {
|
|
24
|
+
logger.error("Invalid --lines value. Must be a positive number.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const service = options?.service || "coolify";
|
|
28
|
+
const validServices = ["coolify", "docker", "system"];
|
|
29
|
+
if (!validServices.includes(service)) {
|
|
30
|
+
logger.error(`Invalid service: ${service}. Choose from: ${validServices.join(", ")}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const follow = options?.follow || false;
|
|
34
|
+
const command = buildLogCommand(service, lines, follow);
|
|
35
|
+
logger.info(`Fetching ${service} logs from ${server.name} (${server.ip})...`);
|
|
36
|
+
if (follow) {
|
|
37
|
+
const exitCode = await sshStream(server.ip, command);
|
|
38
|
+
if (exitCode !== 0) {
|
|
39
|
+
logger.error(`Log stream ended with code ${exitCode}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const result = await sshExec(server.ip, command);
|
|
44
|
+
if (result.stdout)
|
|
45
|
+
console.log(result.stdout);
|
|
46
|
+
if (result.stderr)
|
|
47
|
+
console.error(result.stderr);
|
|
48
|
+
if (result.code !== 0) {
|
|
49
|
+
logger.error(`Failed to fetch logs (exit code ${result.code})`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SystemMetrics {
|
|
2
|
+
cpu: string;
|
|
3
|
+
ramUsed: string;
|
|
4
|
+
ramTotal: string;
|
|
5
|
+
diskUsed: string;
|
|
6
|
+
diskTotal: string;
|
|
7
|
+
diskPercent: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseMetrics(stdout: string): SystemMetrics;
|
|
10
|
+
export declare function monitorCommand(query?: string, options?: {
|
|
11
|
+
containers?: boolean;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAiD1D;AAED,wBAAsB,cAAc,CAClC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAiDf"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { resolveServer } from "../utils/serverSelect.js";
|
|
2
|
+
import { checkSshAvailable, sshExec } from "../utils/ssh.js";
|
|
3
|
+
import { logger, createSpinner } from "../utils/logger.js";
|
|
4
|
+
export function parseMetrics(stdout) {
|
|
5
|
+
const lines = stdout.split("\n");
|
|
6
|
+
// Parse CPU from top output - look for %Cpu(s) line
|
|
7
|
+
let cpu = "N/A";
|
|
8
|
+
for (const line of lines) {
|
|
9
|
+
if (line.includes("Cpu") || line.includes("cpu")) {
|
|
10
|
+
// Match patterns like "0.0 us" or "0.0%us"
|
|
11
|
+
const idleMatch = line.match(/([\d.]+)\s*(?:%?\s*)?id/);
|
|
12
|
+
if (idleMatch) {
|
|
13
|
+
const idle = parseFloat(idleMatch[1]);
|
|
14
|
+
cpu = `${(100 - idle).toFixed(1)}%`;
|
|
15
|
+
}
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Parse RAM from free -h output
|
|
20
|
+
let ramUsed = "N/A";
|
|
21
|
+
let ramTotal = "N/A";
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
if (line.startsWith("Mem:")) {
|
|
24
|
+
const parts = line.split(/\s+/);
|
|
25
|
+
if (parts.length >= 3) {
|
|
26
|
+
ramTotal = parts[1];
|
|
27
|
+
ramUsed = parts[2];
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Parse Disk from df -h output - look for "total" line
|
|
33
|
+
let diskUsed = "N/A";
|
|
34
|
+
let diskTotal = "N/A";
|
|
35
|
+
let diskPercent = "N/A";
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
if (line.startsWith("total") || line.includes("/dev/")) {
|
|
38
|
+
const parts = line.split(/\s+/);
|
|
39
|
+
if (parts.length >= 5) {
|
|
40
|
+
diskTotal = parts[1];
|
|
41
|
+
diskUsed = parts[2];
|
|
42
|
+
diskPercent = parts[4];
|
|
43
|
+
}
|
|
44
|
+
// Prefer "total" line over individual disk lines
|
|
45
|
+
if (line.startsWith("total"))
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { cpu, ramUsed, ramTotal, diskUsed, diskTotal, diskPercent };
|
|
50
|
+
}
|
|
51
|
+
export async function monitorCommand(query, options) {
|
|
52
|
+
if (!checkSshAvailable()) {
|
|
53
|
+
logger.error("SSH client not found. Please install OpenSSH.");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const server = await resolveServer(query, "Select a server to monitor:");
|
|
57
|
+
if (!server)
|
|
58
|
+
return;
|
|
59
|
+
const spinner = createSpinner(`Fetching metrics from ${server.name}...`);
|
|
60
|
+
spinner.start();
|
|
61
|
+
try {
|
|
62
|
+
// Gather all metrics in a single SSH command
|
|
63
|
+
let command = "top -bn1 | head -5 && echo '---SEPARATOR---' && free -h && echo '---SEPARATOR---' && df -h --total | grep -E '(Filesystem|total)'";
|
|
64
|
+
if (options?.containers) {
|
|
65
|
+
command += " && echo '---SEPARATOR---' && docker ps --format 'table {{.Names}}\\t{{.Status}}\\t{{.Ports}}'";
|
|
66
|
+
}
|
|
67
|
+
const result = await sshExec(server.ip, command);
|
|
68
|
+
if (result.code !== 0) {
|
|
69
|
+
spinner.fail("Failed to fetch metrics");
|
|
70
|
+
if (result.stderr)
|
|
71
|
+
logger.error(result.stderr);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
spinner.succeed(`Metrics for ${server.name} (${server.ip})`);
|
|
75
|
+
const metrics = parseMetrics(result.stdout);
|
|
76
|
+
console.log();
|
|
77
|
+
logger.info(`CPU Usage: ${metrics.cpu}`);
|
|
78
|
+
logger.info(`RAM Usage: ${metrics.ramUsed} / ${metrics.ramTotal}`);
|
|
79
|
+
logger.info(`Disk Usage: ${metrics.diskUsed} / ${metrics.diskTotal} (${metrics.diskPercent})`);
|
|
80
|
+
if (options?.containers) {
|
|
81
|
+
const sections = result.stdout.split("---SEPARATOR---");
|
|
82
|
+
if (sections.length >= 4) {
|
|
83
|
+
console.log();
|
|
84
|
+
logger.title("Docker Containers");
|
|
85
|
+
console.log(sections[3].trim());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
spinner.fail("Failed to fetch metrics");
|
|
91
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../src/commands/monitor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,10 @@ import { configCommand } from "./commands/config.js";
|
|
|
11
11
|
import { sshCommand } from "./commands/ssh.js";
|
|
12
12
|
import { updateCommand } from "./commands/update.js";
|
|
13
13
|
import { restartCommand } from "./commands/restart.js";
|
|
14
|
+
import { logsCommand } from "./commands/logs.js";
|
|
15
|
+
import { monitorCommand } from "./commands/monitor.js";
|
|
16
|
+
import { healthCommand } from "./commands/health.js";
|
|
17
|
+
import { doctorCommand } from "./commands/doctor.js";
|
|
14
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
19
|
const __dirname = dirname(__filename);
|
|
16
20
|
const pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
|
@@ -54,5 +58,23 @@ program
|
|
|
54
58
|
.command("restart [query]")
|
|
55
59
|
.description("Restart a registered server")
|
|
56
60
|
.action(restartCommand);
|
|
61
|
+
program
|
|
62
|
+
.command("logs [query]")
|
|
63
|
+
.description("View server logs (Coolify, Docker, or system)")
|
|
64
|
+
.option("-n, --lines <lines>", "Number of log lines to show", "50")
|
|
65
|
+
.option("-f, --follow", "Follow log output in real-time")
|
|
66
|
+
.option("-s, --service <service>", "Log service: coolify, docker, system", "coolify")
|
|
67
|
+
.action((query, options) => logsCommand(query, options));
|
|
68
|
+
program
|
|
69
|
+
.command("monitor [query]")
|
|
70
|
+
.description("Show server resource usage (CPU, RAM, Disk)")
|
|
71
|
+
.option("--containers", "Show Docker container list")
|
|
72
|
+
.action((query, options) => monitorCommand(query, options));
|
|
73
|
+
program.command("health").description("Check health of all registered servers").action(healthCommand);
|
|
74
|
+
program
|
|
75
|
+
.command("doctor")
|
|
76
|
+
.description("Check your local environment and configuration")
|
|
77
|
+
.option("--check-tokens", "Validate provider API tokens")
|
|
78
|
+
.action((options) => doctorCommand(options, pkg.version));
|
|
57
79
|
program.parse();
|
|
58
80
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/ssh.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function checkSshAvailable(): boolean;
|
|
2
2
|
export declare function sshConnect(ip: string): Promise<number>;
|
|
3
|
+
export declare function sshStream(ip: string, command: string): Promise<number>;
|
|
3
4
|
export declare function sshExec(ip: string, command: string): Promise<{
|
|
4
5
|
code: number;
|
|
5
6
|
stdout: string;
|
package/dist/utils/ssh.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/utils/ssh.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtD;AAED,wBAAgB,OAAO,CACrB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB3D"}
|
|
1
|
+
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/utils/ssh.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtD;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUtE;AAED,wBAAgB,OAAO,CACrB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB3D"}
|
package/dist/utils/ssh.js
CHANGED
|
@@ -17,6 +17,13 @@ export function sshConnect(ip) {
|
|
|
17
17
|
child.on("error", () => resolve(1));
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
+
export function sshStream(ip, command) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const child = spawn("ssh", ["-o", "StrictHostKeyChecking=accept-new", `root@${ip}`, command], { stdio: "inherit" });
|
|
23
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
24
|
+
child.on("error", () => resolve(1));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
20
27
|
export function sshExec(ip, command) {
|
|
21
28
|
return new Promise((resolve) => {
|
|
22
29
|
const child = spawn("ssh", ["-o", "StrictHostKeyChecking=accept-new", `root@${ip}`, command], {
|
package/dist/utils/ssh.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/utils/ssh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE;YACzC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,EAAU,EACV,OAAe;IAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;YAC5F,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/utils/ssh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE;YACzC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAU,EAAE,OAAe;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CACjB,KAAK,EACL,CAAC,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EACjE,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,EAAU,EACV,OAAe;IAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;YAC5F,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC"}
|