@burnguard/agent 1.1.3 → 1.2.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/dist/agent.d.ts +4 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +53 -0
- package/dist/agent.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +5 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +176 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.js +2 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAIA,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAqDjE"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAgent = runAgent;
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
const watcher_1 = require("./watcher");
|
|
6
|
+
const sender_1 = require("./sender");
|
|
7
|
+
function runAgent(options) {
|
|
8
|
+
const foreground = options?.foreground ?? false;
|
|
9
|
+
console.log("=================================");
|
|
10
|
+
console.log(" BurnGuard Agent v1.2.0");
|
|
11
|
+
console.log(" Real-Time Cost Monitoring");
|
|
12
|
+
console.log("=================================");
|
|
13
|
+
console.log();
|
|
14
|
+
const config = (0, config_1.loadConfig)();
|
|
15
|
+
console.log(`[agent] Backend URL: ${config.backendUrl}`);
|
|
16
|
+
console.log(`[agent] Log directory: ${config.logDirectory}`);
|
|
17
|
+
console.log(`[agent] Batch size: ${config.batchSize}, interval: ${config.batchInterval}ms`);
|
|
18
|
+
console.log();
|
|
19
|
+
const sender = (0, sender_1.createSender)(config);
|
|
20
|
+
const watcher = (0, watcher_1.createWatcher)(config.logDirectory, (metrics) => {
|
|
21
|
+
console.log(`[agent] Parsed ${metrics.length} metric(s), sending to backend...`);
|
|
22
|
+
sender.send(metrics);
|
|
23
|
+
});
|
|
24
|
+
console.log(`[agent] Watching for JSONL files in: ${config.logDirectory}`);
|
|
25
|
+
if (foreground) {
|
|
26
|
+
console.log("[agent] Press Ctrl+C to stop.");
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.log("[agent] Agent is running in the background.");
|
|
30
|
+
}
|
|
31
|
+
console.log();
|
|
32
|
+
function shutdown() {
|
|
33
|
+
console.log("\n[agent] Shutting down...");
|
|
34
|
+
watcher.close();
|
|
35
|
+
sender.close();
|
|
36
|
+
console.log("[agent] Goodbye.");
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
process.on("SIGINT", shutdown);
|
|
40
|
+
process.on("SIGTERM", shutdown);
|
|
41
|
+
// In daemon mode, catch unhandled errors so they get logged before dying
|
|
42
|
+
if (!foreground) {
|
|
43
|
+
process.on("uncaughtException", (err) => {
|
|
44
|
+
console.error("[agent] Uncaught exception:", err);
|
|
45
|
+
shutdown();
|
|
46
|
+
});
|
|
47
|
+
process.on("unhandledRejection", (reason) => {
|
|
48
|
+
console.error("[agent] Unhandled rejection:", reason);
|
|
49
|
+
shutdown();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";;AAIA,4BAqDC;AAzDD,qCAAsC;AACtC,uCAA0C;AAC1C,qCAAwC;AAExC,SAAgB,QAAQ,CAAC,OAAkC;IACzD,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,KAAK,CAAC;IAEhD,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE5B,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,SAAS,eAAe,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,OAAO,GAAG,IAAA,uBAAa,EAAC,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;QAC7D,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,MAAM,mCAAmC,CAAC,CAAC;QACjF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3E,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,SAAS,QAAQ;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,yEAAyE;IACzE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;YACtC,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YAClD,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1C,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;YACtD,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA6BA,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0CxC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.run = run;
|
|
4
|
+
const daemon_1 = require("./daemon");
|
|
5
|
+
const agent_1 = require("./agent");
|
|
6
|
+
function printUsage() {
|
|
7
|
+
console.log(`
|
|
8
|
+
BurnGuard Agent - Real-Time Cost Monitoring
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
burnguard start [--foreground] Start the agent (daemon by default)
|
|
12
|
+
burnguard stop Stop the running agent
|
|
13
|
+
burnguard status Check if the agent is running
|
|
14
|
+
burnguard logs [-f|--follow] View agent logs (last 50 lines)
|
|
15
|
+
burnguard help Show this help message
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
--api-key=<key> API key (or set BURNGUARD_API_KEY env var)
|
|
19
|
+
--backend-url=<url> Backend WebSocket URL
|
|
20
|
+
--log-dir=<path> OpenClaw log directory (default: ~/.openclaw)
|
|
21
|
+
--foreground, -f Run in foreground (don't daemonize)
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
burnguard start # Start as background daemon
|
|
25
|
+
burnguard start --foreground # Run in foreground
|
|
26
|
+
burnguard start --api-key=bg_xxx # Start with explicit API key
|
|
27
|
+
burnguard stop # Stop the daemon
|
|
28
|
+
burnguard logs -f # Tail logs in real time
|
|
29
|
+
`);
|
|
30
|
+
}
|
|
31
|
+
function run(args) {
|
|
32
|
+
const command = args[0];
|
|
33
|
+
// Internal daemon entry point (hidden from help)
|
|
34
|
+
if (command === "--_daemon") {
|
|
35
|
+
(0, agent_1.runAgent)();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Backward compatibility: if first arg starts with -- (e.g. --api-key=bg_xxx),
|
|
39
|
+
// treat it as a foreground start (old behavior before subcommands)
|
|
40
|
+
if (command && command.startsWith("--")) {
|
|
41
|
+
(0, agent_1.runAgent)({ foreground: true });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
switch (command) {
|
|
45
|
+
case "start":
|
|
46
|
+
(0, daemon_1.startCommand)(args.slice(1));
|
|
47
|
+
break;
|
|
48
|
+
case "stop":
|
|
49
|
+
(0, daemon_1.stopCommand)();
|
|
50
|
+
break;
|
|
51
|
+
case "status":
|
|
52
|
+
(0, daemon_1.statusCommand)();
|
|
53
|
+
break;
|
|
54
|
+
case "logs":
|
|
55
|
+
(0, daemon_1.logsCommand)(args.slice(1));
|
|
56
|
+
break;
|
|
57
|
+
case "help":
|
|
58
|
+
case "--help":
|
|
59
|
+
case "-h":
|
|
60
|
+
printUsage();
|
|
61
|
+
break;
|
|
62
|
+
case undefined:
|
|
63
|
+
printUsage();
|
|
64
|
+
break;
|
|
65
|
+
default:
|
|
66
|
+
console.error(`Unknown command: ${command}`);
|
|
67
|
+
console.error('Run "burnguard help" for usage information.');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AA6BA,kBA0CC;AAvED,qCAAiF;AACjF,mCAAmC;AAEnC,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBb,CAAC,CAAC;AACH,CAAC;AAED,SAAgB,GAAG,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,iDAAiD;IACjD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAC5B,IAAA,gBAAQ,GAAE,CAAC;QACX,OAAO;IACT,CAAC;IAED,+EAA+E;IAC/E,mEAAmE;IACnE,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAA,gBAAQ,EAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,IAAA,qBAAY,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM;QACR,KAAK,MAAM;YACT,IAAA,oBAAW,GAAE,CAAC;YACd,MAAM;QACR,KAAK,QAAQ;YACX,IAAA,sBAAa,GAAE,CAAC;YAChB,MAAM;QACR,KAAK,MAAM;YACT,IAAA,oBAAW,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM;QACR,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,UAAU,EAAE,CAAC;YACb,MAAM;QACR,KAAK,SAAS;YACZ,UAAU,EAAE,CAAC;YACb,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AASD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI1D;AAED,wBAAgB,UAAU,IAAI,WAAW,CA8CxC"}
|
package/dist/config.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getCliArg = getCliArg;
|
|
6
7
|
exports.loadConfig = loadConfig;
|
|
7
8
|
const os_1 = __importDefault(require("os"));
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;AAoBA,8BAIC;AAED,gCA8CC;AAxED,4CAAoB;AACpB,gDAAwB;AAYxB,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAgB,SAAS,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,CAAC;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,SAAgB,UAAU;IACxB,MAAM,MAAM,GACV,SAAS,CAAC,SAAS,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,EAAE,CAAC;IAEL,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,2EAA2E,CAC5E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GACd,SAAS,CAAC,aAAa,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,qBAAqB;QACjC,gCAAgC,CAAC;IAEnC,MAAM,YAAY,GAAG,WAAW,CAC9B,SAAS,CAAC,SAAS,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,aAAa,CACd,CAAC;IAEF,MAAM,iBAAiB,GAAG,QAAQ,CAChC,SAAS,CAAC,oBAAoB,CAAC,IAAI,MAAM,EACzC,EAAE,CACH,CAAC;IAEF,MAAM,oBAAoB,GAAG,QAAQ,CACnC,SAAS,CAAC,eAAe,CAAC,IAAI,IAAI,EAClC,EAAE,CACH,CAAC;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,MAAM;QACN,UAAU;QACV,YAAY;QACZ,iBAAiB;QACjB,oBAAoB;QACpB,SAAS;QACT,aAAa;KACd,CAAC;AACJ,CAAC"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AA4CA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoEjD;AAED,wBAAgB,WAAW,IAAI,IAAI,CA4BlC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAcpC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkChD"}
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startCommand = startCommand;
|
|
7
|
+
exports.stopCommand = stopCommand;
|
|
8
|
+
exports.statusCommand = statusCommand;
|
|
9
|
+
exports.logsCommand = logsCommand;
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const agent_1 = require("./agent");
|
|
16
|
+
const BURNGUARD_DIR = path_1.default.join(os_1.default.homedir(), ".burnguard");
|
|
17
|
+
const PID_FILE = path_1.default.join(BURNGUARD_DIR, "agent.pid");
|
|
18
|
+
const LOG_FILE = path_1.default.join(BURNGUARD_DIR, "agent.log");
|
|
19
|
+
function ensureDir() {
|
|
20
|
+
if (!fs_1.default.existsSync(BURNGUARD_DIR)) {
|
|
21
|
+
fs_1.default.mkdirSync(BURNGUARD_DIR, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function readPid() {
|
|
25
|
+
try {
|
|
26
|
+
const content = fs_1.default.readFileSync(PID_FILE, "utf-8").trim();
|
|
27
|
+
const pid = parseInt(content, 10);
|
|
28
|
+
return isNaN(pid) ? null : pid;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isProcessAlive(pid) {
|
|
35
|
+
try {
|
|
36
|
+
process.kill(pid, 0);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function cleanStalePid() {
|
|
44
|
+
try {
|
|
45
|
+
fs_1.default.unlinkSync(PID_FILE);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function startCommand(args) {
|
|
52
|
+
// Foreground mode — run directly
|
|
53
|
+
if (args.includes("--foreground") || args.includes("-f")) {
|
|
54
|
+
(0, agent_1.runAgent)({ foreground: true });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Pre-validate API key before spawning daemon
|
|
58
|
+
const apiKey = (0, config_1.getCliArg)("api-key") ?? process.env.BURNGUARD_API_KEY ?? "";
|
|
59
|
+
if (!apiKey) {
|
|
60
|
+
console.error("Error: API key is required. Set BURNGUARD_API_KEY or pass --api-key=<key>");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
ensureDir();
|
|
64
|
+
// Check if already running
|
|
65
|
+
const existingPid = readPid();
|
|
66
|
+
if (existingPid !== null && isProcessAlive(existingPid)) {
|
|
67
|
+
console.log(`BurnGuard agent is already running (PID: ${existingPid})`);
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
// Clean stale PID file
|
|
71
|
+
if (existingPid !== null) {
|
|
72
|
+
cleanStalePid();
|
|
73
|
+
}
|
|
74
|
+
// Open log file for append
|
|
75
|
+
const logFd = fs_1.default.openSync(LOG_FILE, "a");
|
|
76
|
+
// Build args to pass through to daemon child
|
|
77
|
+
const passthroughArgs = [];
|
|
78
|
+
for (const arg of args) {
|
|
79
|
+
if (arg === "--foreground" || arg === "-f")
|
|
80
|
+
continue;
|
|
81
|
+
passthroughArgs.push(arg);
|
|
82
|
+
}
|
|
83
|
+
// Ensure --api-key is passed through if set via env
|
|
84
|
+
if (!passthroughArgs.some((a) => a.startsWith("--api-key="))) {
|
|
85
|
+
passthroughArgs.push(`--api-key=${apiKey}`);
|
|
86
|
+
}
|
|
87
|
+
// Resolve the script path — this file compiled to dist/daemon.js,
|
|
88
|
+
// but we need to invoke dist/index.js (the bin entry point)
|
|
89
|
+
const scriptPath = path_1.default.join(__dirname, "index.js");
|
|
90
|
+
const child = (0, child_process_1.spawn)(process.execPath, [scriptPath, "--_daemon", ...passthroughArgs], {
|
|
91
|
+
detached: true,
|
|
92
|
+
stdio: ["ignore", logFd, logFd],
|
|
93
|
+
});
|
|
94
|
+
// Write PID file
|
|
95
|
+
fs_1.default.writeFileSync(PID_FILE, String(child.pid));
|
|
96
|
+
console.log(`BurnGuard agent started (PID: ${child.pid})`);
|
|
97
|
+
console.log(`Logs: ${LOG_FILE}`);
|
|
98
|
+
child.unref();
|
|
99
|
+
fs_1.default.closeSync(logFd);
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
function stopCommand() {
|
|
103
|
+
const pid = readPid();
|
|
104
|
+
if (pid === null || !isProcessAlive(pid)) {
|
|
105
|
+
console.log("BurnGuard agent is not running.");
|
|
106
|
+
cleanStalePid();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const isWindows = process.platform === "win32";
|
|
110
|
+
try {
|
|
111
|
+
if (isWindows) {
|
|
112
|
+
// On Windows, SIGTERM doesn't work reliably — use taskkill
|
|
113
|
+
const pidStr = String(pid);
|
|
114
|
+
try {
|
|
115
|
+
(0, child_process_1.execFileSync)("taskkill", ["/PID", pidStr], { stdio: "ignore" });
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Graceful kill failed, force kill
|
|
119
|
+
(0, child_process_1.execFileSync)("taskkill", ["/F", "/PID", pidStr], { stdio: "ignore" });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
process.kill(pid, "SIGTERM");
|
|
124
|
+
}
|
|
125
|
+
console.log(`BurnGuard agent stopped (PID: ${pid})`);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
console.log("BurnGuard agent is not running.");
|
|
129
|
+
}
|
|
130
|
+
cleanStalePid();
|
|
131
|
+
}
|
|
132
|
+
function statusCommand() {
|
|
133
|
+
const pid = readPid();
|
|
134
|
+
if (pid === null) {
|
|
135
|
+
console.log("BurnGuard agent is not running.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (isProcessAlive(pid)) {
|
|
139
|
+
console.log(`BurnGuard agent is running (PID: ${pid})`);
|
|
140
|
+
console.log(`Logs: ${LOG_FILE}`);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log("BurnGuard agent is not running (stale PID file cleaned).");
|
|
144
|
+
cleanStalePid();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function logsCommand(args) {
|
|
148
|
+
ensureDir();
|
|
149
|
+
if (!fs_1.default.existsSync(LOG_FILE)) {
|
|
150
|
+
console.log("No log file found. Has the agent been started?");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const follow = args.includes("-f") || args.includes("--follow");
|
|
154
|
+
const content = fs_1.default.readFileSync(LOG_FILE, "utf-8");
|
|
155
|
+
const lines = content.split("\n");
|
|
156
|
+
// Print last 50 lines
|
|
157
|
+
const tail = lines.slice(-50);
|
|
158
|
+
console.log(tail.join("\n"));
|
|
159
|
+
if (follow) {
|
|
160
|
+
// Watch for new content
|
|
161
|
+
let position = fs_1.default.statSync(LOG_FILE).size;
|
|
162
|
+
console.log("\n--- Following log output (Ctrl+C to stop) ---\n");
|
|
163
|
+
fs_1.default.watchFile(LOG_FILE, { interval: 500 }, () => {
|
|
164
|
+
const stat = fs_1.default.statSync(LOG_FILE);
|
|
165
|
+
if (stat.size > position) {
|
|
166
|
+
const fd = fs_1.default.openSync(LOG_FILE, "r");
|
|
167
|
+
const buffer = Buffer.alloc(stat.size - position);
|
|
168
|
+
fs_1.default.readSync(fd, buffer, 0, buffer.length, position);
|
|
169
|
+
fs_1.default.closeSync(fd);
|
|
170
|
+
process.stdout.write(buffer.toString("utf-8"));
|
|
171
|
+
position = stat.size;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const sender_1 = require("./sender");
|
|
7
|
-
console.log("=================================");
|
|
8
|
-
console.log(" BurnGuard Agent v1.2.0");
|
|
9
|
-
console.log(" Real-Time Cost Monitoring");
|
|
10
|
-
console.log("=================================");
|
|
11
|
-
console.log();
|
|
12
|
-
const config = (0, config_1.loadConfig)();
|
|
13
|
-
console.log(`[agent] Backend URL: ${config.backendUrl}`);
|
|
14
|
-
console.log(`[agent] Log directory: ${config.logDirectory}`);
|
|
15
|
-
console.log(`[agent] Batch size: ${config.batchSize}, interval: ${config.batchInterval}ms`);
|
|
16
|
-
console.log();
|
|
17
|
-
const sender = (0, sender_1.createSender)(config);
|
|
18
|
-
const watcher = (0, watcher_1.createWatcher)(config.logDirectory, (metrics) => {
|
|
19
|
-
console.log(`[agent] Parsed ${metrics.length} metric(s), sending to backend...`);
|
|
20
|
-
sender.send(metrics);
|
|
21
|
-
});
|
|
22
|
-
console.log(`[agent] Watching for JSONL files in: ${config.logDirectory}`);
|
|
23
|
-
console.log("[agent] Press Ctrl+C to stop.");
|
|
24
|
-
console.log();
|
|
25
|
-
function shutdown() {
|
|
26
|
-
console.log("\n[agent] Shutting down...");
|
|
27
|
-
watcher.close();
|
|
28
|
-
sender.close();
|
|
29
|
-
console.log("[agent] Goodbye.");
|
|
30
|
-
process.exit(0);
|
|
31
|
-
}
|
|
32
|
-
process.on("SIGINT", shutdown);
|
|
33
|
-
process.on("SIGTERM", shutdown);
|
|
4
|
+
const cli_1 = require("./cli");
|
|
5
|
+
(0, cli_1.run)(process.argv.slice(2));
|
|
34
6
|
//# 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":";;;AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,+BAA4B;AAE5B,IAAA,SAAG,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
|