Skip to content

Commit 08d10bb

Browse files
committed
update
1 parent 35bd484 commit 08d10bb

9 files changed

Lines changed: 347 additions & 62 deletions

File tree

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,40 @@ Output:
369369

370370
#### bm2 list
371371

372-
List all managed processes with their status, resource usage, and uptime.
372+
List all managed processes with their status, resource usage, and uptime.
373+
Supports a **live mode** with auto-refresh and interactive keyboard shortcuts.
373374

375+
```bash
376+
bm2 list
377+
```
378+
379+
## Live Mode Keyboard Shortcuts
380+
381+
```
382+
R : Reload table manually
383+
M : Sort by Memory usage
384+
C : Sort by CPU usage
385+
U : Sort by Uptime
386+
Q : Quit live mode
374387
```
388+
389+
## Examples
390+
391+
```bash
392+
# List all processes once
375393
bm2 list
394+
395+
# List processes with live updates
396+
bm2 list --live
397+
376398
```
377399

400+
## Notes
401+
402+
* Live mode automatically refreshes the table every second (default interval).
403+
* Sorting can be changed on the fly using the keyboard shortcuts.
404+
* Press `R` to reload manually, `Q` to quit live mode.
405+
378406
---
379407

380408
#### bm2 signal

src/colors.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
export function color(text: string, type: string) {
3+
const codes: Record<string, string> = {
4+
reset: "\x1b[0m",
5+
bold: "\x1b[1m",
6+
dim: "\x1b[2m",
7+
red: "\x1b[31m",
8+
green: "\x1b[32m",
9+
yellow: "\x1b[33m",
10+
cyan: "\x1b[36m",
11+
magenta: "\x1b[35m",
12+
};
13+
return (codes[type] || "") + text + codes.reset;
14+
}
15+
16+
export function statusColor(status: string): string {
17+
switch (status) {
18+
case "online":
19+
return "green";
20+
case "stopped":
21+
return "gray";
22+
case "errored":
23+
return "red";
24+
case "launching":
25+
case "waiting-restart":
26+
return "yellow";
27+
case "stopping":
28+
return "magenta";
29+
default:
30+
return "white";
31+
}
32+
}

src/dashboard-ui.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@
195195
<td>\${p.pid||'-'}</td>
196196
<td>\${p.monit.cpu.toFixed(1)}%</td>
197197
<td>\${formatBytes(p.monit.memory)}</td>
198-
<td>\${p.pm2_env.restart_time}</td>
199-
<td>\${p.status==='online' ? formatUptime(Date.now()-p.pm2_env.pm_uptime) : '-'}</td>
198+
<td>\${p.bm2_env.restart_time}</td>
199+
<td>\${p.status==='online' ? formatUptime(Date.now()-p.bm2_env.pm_uptime) : '-'}</td>
200200
<td class="actions">
201201
<button class="btn success" onclick="send('restart',{target:'\${p.pm_id}'})">↻</button>
202202
<button class="btn danger" onclick="send('stop',{target:'\${p.pm_id}'})">■</button>

src/hello.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11

2-
console.log("Hello ===>")
2+
let counter = 0;
3+
4+
setInterval(() => {
5+
console.log(`Hello World ${counter++}`)
6+
7+
})

src/index.ts

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import type {
4040
ProcessState,
4141
} from "./types";
4242
import Table from "cli-table3";
43+
import { statusColor } from "./colors";
44+
import { liveWatchProcess, printProcessTable, watchProcesses } from "./process-table";
4345

4446
// ---------------------------------------------------------------------------
4547
// Ensure directory structure exists
@@ -127,23 +129,6 @@ async function sendToDaemon(msg: DaemonMessage): Promise<DaemonResponse> {
127129
// Table rendering
128130
// ---------------------------------------------------------------------------
129131

130-
function statusColor(status: string): string {
131-
switch (status) {
132-
case "online":
133-
return "green";
134-
case "stopped":
135-
return "gray";
136-
case "errored":
137-
return "red";
138-
case "launching":
139-
case "waiting-restart":
140-
return "yellow";
141-
case "stopping":
142-
return "magenta";
143-
default:
144-
return "white";
145-
}
146-
}
147132

148133
function printToCli(data: any) {
149134
console.log()
@@ -188,17 +173,17 @@ function printProcessTable(processes: ProcessState[]) {
188173
189174
for (const p of processes) {
190175
const uptime =
191-
p.status === "online" ? formatUptime(Date.now() - p.pm2_env.pm_uptime) : "0s";
176+
p.status === "online" ? formatUptime(Date.now() - p.bm2_env.pm_uptime) : "0s";
192177
193178
const row = [
194179
padRight(String(p.pm_id), 4),
195180
padRight(p.name, 20),
196181
padRight(p.namespace || "default", 12),
197-
padRight(p.pm2_env.version || "N/A", 10),
198-
padRight(p.pm2_env.execMode, 8),
182+
padRight(p.bm2_env.version || "N/A", 10),
183+
padRight(p.bm2_env.execMode, 8),
199184
padRight(p.pid ? String(p.pid) : "N/A", 8),
200185
padRight(uptime, 10),
201-
padRight(String(p.pm2_env.restart_time), 4),
186+
padRight(String(p.bm2_env.restart_time), 4),
202187
padRight(p.status, 16),
203188
padRight(p.monit.cpu.toFixed(1) + "%", 8),
204189
padRight(formatBytes(p.monit.memory), 10),
@@ -218,7 +203,7 @@ function printProcessTable(processes: ProcessState[]) {
218203
console.log()
219204
console.log()
220205
}
221-
*/
206+
222207
223208
224209
function printProcessTable(processes: ProcessState[]) {
@@ -253,20 +238,23 @@ function printProcessTable(processes: ProcessState[]) {
253238
});
254239
255240
for (const p of processes) {
241+
242+
console.log("p=====>", p)
243+
256244
const uptime =
257245
p.status === "online"
258-
? formatUptime(Date.now() - p.pm2_env.pm_uptime)
246+
? formatUptime(Date.now() - p.bm2_env.pm_uptime)
259247
: "0s";
260248
261249
table.push([
262250
p.pm_id,
263251
p.name,
264252
p.namespace || "default",
265-
p.pm2_env.version || "N/A",
266-
p.pm2_env.execMode,
253+
p.bm2_env?.version || "N/A",
254+
p.bm2_env?.execMode,
267255
p.pid ?? "N/A",
268256
uptime,
269-
p.pm2_env.restart_time,
257+
p.bm2_env.restart_time,
270258
colorize(p.status, statusColor(p.status)),
271259
p.monit.cpu.toFixed(1) + "%",
272260
formatBytes(p.monit.memory),
@@ -276,7 +264,7 @@ function printProcessTable(processes: ProcessState[]) {
276264
console.log(table.toString());
277265
console.log("\n");
278266
}
279-
267+
*/
280268

281269
// ---------------------------------------------------------------------------
282270
// Ecosystem config loader
@@ -545,13 +533,29 @@ async function cmdDelete(args: string[]) {
545533
printProcessTable(res.data);
546534
}
547535

548-
async function cmdList() {
536+
async function cmdList(args: string[]) {
549537
const res = await sendToDaemon({ type: "list" });
550538
if (!res.success) {
551539
console.error(colorize(`Error: ${res.error}`, "red"));
552540
process.exit(1);
553541
}
554-
printProcessTable(res.data);
542+
543+
let liveMode = false;
544+
545+
for (let arg of args) {
546+
switch (arg) {
547+
case "--live":
548+
liveMode = true;
549+
break;
550+
default:
551+
}
552+
}
553+
554+
if (liveMode) {
555+
liveWatchProcess(res.data)
556+
} else {
557+
printProcessTable(res.data);
558+
}
555559
}
556560

557561
async function cmdDescribe(args: string[]) {
@@ -572,37 +576,37 @@ async function cmdDescribe(args: string[]) {
572576
console.log(colorize(`\n─── ${p.name} (id: ${p.pm_id}) ───`, "bold"));
573577
console.log(` Status : ${colorize(p.status, statusColor(p.status))}`);
574578
console.log(` PID : ${p.pid || "N/A"}`);
575-
console.log(` Exec mode : ${p.pm2_env.execMode}`);
576-
console.log(` Instances : ${p.pm2_env.instances}`);
579+
console.log(` Exec mode : ${p.bm2_env.execMode}`);
580+
console.log(` Instances : ${p.bm2_env.instances}`);
577581
console.log(` Namespace : ${p.namespace || "default"}`);
578-
console.log(` Script : ${p.pm2_env.script}`);
579-
console.log(` CWD : ${p.pm2_env.cwd}`);
580-
console.log(` Args : ${p.pm2_env.args.join(" ") || "(none)"}`);
581-
console.log(` Interpreter : ${p.pm2_env.interpreter || "bun"}`);
582-
console.log(` Restarts : ${p.pm2_env.restart_time}`);
583-
console.log(` Unstable : ${p.pm2_env.unstable_restarts}`);
582+
console.log(` Script : ${p.bm2_env.script}`);
583+
console.log(` CWD : ${p.bm2_env.cwd}`);
584+
console.log(` Args : ${p.bm2_env.args.join(" ") || "(none)"}`);
585+
console.log(` Interpreter : ${p.bm2_env.interpreter || "bun"}`);
586+
console.log(` Restarts : ${p.bm2_env.restart_time}`);
587+
console.log(` Unstable : ${p.bm2_env.unstable_restarts}`);
584588
console.log(
585589
` Uptime : ${
586-
p.status === "online" ? formatUptime(Date.now() - p.pm2_env.pm_uptime) : "N/A"
590+
p.status === "online" ? formatUptime(Date.now() - p.bm2_env.pm_uptime) : "N/A"
587591
}`
588592
);
589-
console.log(` Created at : ${new Date(p.pm2_env.created_at).toISOString()}`);
593+
console.log(` Created at : ${new Date(p.bm2_env.created_at).toISOString()}`);
590594
console.log(` CPU : ${p.monit.cpu.toFixed(1)}%`);
591595
console.log(` Memory : ${formatBytes(p.monit.memory)}`);
592596
if (p.monit.handles !== undefined)
593597
console.log(` Handles : ${p.monit.handles}`);
594598
if (p.monit.eventLoopLatency !== undefined)
595599
console.log(` EL Latency : ${p.monit.eventLoopLatency.toFixed(2)} ms`);
596-
console.log(` Watch : ${p.pm2_env.watch}`);
597-
console.log(` Autorestart : ${p.pm2_env.autorestart}`);
598-
console.log(` Max restarts : ${p.pm2_env.maxRestarts}`);
599-
console.log(` Kill timeout : ${p.pm2_env.killTimeout} ms`);
600-
if (p.pm2_env.healthCheckUrl)
601-
console.log(` Health URL : ${p.pm2_env.healthCheckUrl}`);
602-
if (p.pm2_env.cronRestart)
603-
console.log(` Cron restart : ${p.pm2_env.cronRestart}`);
604-
if (p.pm2_env.port)
605-
console.log(` Port : ${p.pm2_env.port}`);
600+
console.log(` Watch : ${p.bm2_env.watch}`);
601+
console.log(` Autorestart : ${p.bm2_env.autorestart}`);
602+
console.log(` Max restarts : ${p.bm2_env.maxRestarts}`);
603+
console.log(` Kill timeout : ${p.bm2_env.killTimeout} ms`);
604+
if (p.bm2_env.healthCheckUrl)
605+
console.log(` Health URL : ${p.bm2_env.healthCheckUrl}`);
606+
if (p.bm2_env.cronRestart)
607+
console.log(` Cron restart : ${p.bm2_env.cronRestart}`);
608+
if (p.bm2_env.port)
609+
console.log(` Port : ${p.bm2_env.port}`);
606610
console.log();
607611
}
608612
}
@@ -990,7 +994,7 @@ async function cmdPrometheus() {
990994

991995
function printHelp() {
992996
console.log(`
993-
${colorize("BM2", "bold")} ${colorize(`v${VERSION}`, "dim")} — Bun Process Manager
997+
${colorize("BM2", "bold")} ${colorize(`v${VERSION}`, "dim")} — Bun Process Manager
994998
995999
${colorize("Usage:", "bold")} bm2 <command> [options]
9961000
@@ -1110,7 +1114,7 @@ function printHelp() {
11101114
case "list":
11111115
case "ls":
11121116
case "status":
1113-
await cmdList();
1117+
await cmdList(commandArgs);
11141118
break;
11151119
case "describe":
11161120
case "show":

src/monitor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ export class Monitor {
9595
eventLoopLatency: p.monit.eventLoopLatency,
9696
handles: p.monit.handles,
9797
status: p.status,
98-
restarts: p.pm2_env.restart_time,
99-
uptime: p.pm2_env.status === "online" ? Date.now() - p.pm2_env.pm_uptime : 0,
98+
restarts: p.bm2_env.restart_time,
99+
uptime: p.bm2_env.status === "online" ? Date.now() - p.bm2_env.pm_uptime : 0,
100100
})),
101101
system: {
102102
totalMemory: system.totalMemory,
@@ -147,14 +147,14 @@ export class Monitor {
147147
lines.push("# HELP bm2_process_restarts_total Total restart count");
148148
lines.push("# TYPE bm2_process_restarts_total counter");
149149
for (const p of processes) {
150-
lines.push(`bm2_process_restarts_total{name="${p.name}",id="${p.pm_id}"} ${p.pm2_env.restart_time}`);
150+
lines.push(`bm2_process_restarts_total{name="${p.name}",id="${p.pm_id}"} ${p.bm2_env.restart_time}`);
151151
}
152152

153153
lines.push("# HELP bm2_process_uptime_seconds Process uptime in seconds");
154154
lines.push("# TYPE bm2_process_uptime_seconds gauge");
155155
for (const p of processes) {
156-
const uptime = p.pm2_env.status === "online"
157-
? (Date.now() - p.pm2_env.pm_uptime) / 1000
156+
const uptime = p.bm2_env.status === "online"
157+
? (Date.now() - p.bm2_env.pm_uptime) / 1000
158158
: 0;
159159
lines.push(`bm2_process_uptime_seconds{name="${p.name}",id="${p.pm_id}"} ${uptime.toFixed(0)}`);
160160
}

src/process-container.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ export class ProcessContainer {
484484
handles: this.handles,
485485
eventLoopLatency: this.eventLoopLatency,
486486
},
487-
pm2_env: {
487+
bm2_env: {
488488
...this.config,
489489
status: this.status,
490490
pm_uptime: this.startedAt,

0 commit comments

Comments
 (0)