launchlayer-apm-agent 0.1.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/index.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const config_1 = require("./config");
5
+ const forwarder_1 = require("./forwarder");
6
+ const receiver_1 = require("./receiver");
7
+ const host_1 = require("./collectors/host");
8
+ const docker_1 = require("./collectors/docker");
9
+ const database_1 = require("./collectors/database");
10
+ // Handle subcommands (e.g. "launchlayer-agent init")
11
+ if ((0, config_1.handleCli)())
12
+ process.exit(0);
13
+ const config = (0, config_1.loadConfig)();
14
+ const forwarder = new forwarder_1.Forwarder(config.agent.collector_url, config.agent.api_key);
15
+ console.log(`[bi-agent] Starting for instance "${config.agent.instance_id}"`);
16
+ console.log(`[bi-agent] Collector: ${config.agent.collector_url}`);
17
+ // Start SDK trace receiver
18
+ if (config.receiver.enabled) {
19
+ const receiver = new receiver_1.Receiver(forwarder, config.receiver.bind, config.receiver.port);
20
+ receiver.start();
21
+ }
22
+ // Host metrics collection
23
+ if (config.host.enabled) {
24
+ const hostInterval = (config.host.interval_seconds || 30) * 1000;
25
+ const collectHost = async () => {
26
+ try {
27
+ const metrics = await (0, host_1.collectHostMetrics)(config.host.proc_path);
28
+ await forwarder.sendHost({
29
+ instanceId: config.agent.instance_id,
30
+ hostname: config.agent.hostname,
31
+ ...metrics,
32
+ });
33
+ console.log(`[host] CPU: ${metrics.cpuPct}%, Mem: ${metrics.memUsedMb}/${metrics.memTotalMb} MB`);
34
+ }
35
+ catch (err) {
36
+ console.error('[host] Collection failed:', err.message);
37
+ }
38
+ };
39
+ // Initial collection after 2s (let CPU baseline establish)
40
+ setTimeout(collectHost, 2000);
41
+ setInterval(collectHost, hostInterval);
42
+ }
43
+ // Docker metrics collection
44
+ if (config.docker.enabled) {
45
+ const dockerInterval = (config.docker.interval_seconds || 30) * 1000;
46
+ const collectDocker = async () => {
47
+ try {
48
+ const containers = await (0, docker_1.collectDockerMetrics)(config.docker.socket);
49
+ if (containers.length > 0) {
50
+ await forwarder.sendContainers({
51
+ instanceId: config.agent.instance_id,
52
+ containers,
53
+ });
54
+ console.log(`[docker] Collected ${containers.length} containers`);
55
+ }
56
+ }
57
+ catch (err) {
58
+ console.error('[docker] Collection failed:', err.message);
59
+ }
60
+ };
61
+ setTimeout(collectDocker, 3000);
62
+ setInterval(collectDocker, dockerInterval);
63
+ }
64
+ // Database metrics collection
65
+ if (config.databases && config.databases.length > 0) {
66
+ for (const dbConfig of config.databases) {
67
+ const dbInterval = (dbConfig.interval_seconds || 60) * 1000;
68
+ const collectDb = async () => {
69
+ try {
70
+ const snapshot = await (0, database_1.collectDatabaseMetrics)(dbConfig);
71
+ await forwarder.sendDatabase(snapshot);
72
+ console.log(`[database] ${dbConfig.name}: ${snapshot.slowQueries.length} slow queries, ` +
73
+ `${snapshot.tableStats.length} tables, ${snapshot.indexes.length} indexes, ` +
74
+ `conn: ${snapshot.connections?.utilizationPct}%`);
75
+ }
76
+ catch (err) {
77
+ console.error(`[database] ${dbConfig.name} collection failed:`, err.message);
78
+ }
79
+ };
80
+ setTimeout(collectDb, 5000);
81
+ setInterval(collectDb, dbInterval);
82
+ }
83
+ }
84
+ // Graceful shutdown
85
+ process.on('SIGTERM', () => {
86
+ console.log('[bi-agent] Shutting down...');
87
+ process.exit(0);
88
+ });
89
+ process.on('SIGINT', () => {
90
+ console.log('[bi-agent] Interrupted');
91
+ process.exit(0);
92
+ });
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Forwarder } from './forwarder';
2
+ /**
3
+ * Local HTTP receiver on localhost:9999.
4
+ * Accepts SDK trace payloads and immediately forwards them to the collector.
5
+ */
6
+ export declare class Receiver {
7
+ private forwarder;
8
+ private bind;
9
+ private port;
10
+ private server;
11
+ constructor(forwarder: Forwarder, bind: string, port: number);
12
+ start(): void;
13
+ stop(): void;
14
+ private handleRequest;
15
+ }
16
+ //# sourceMappingURL=receiver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiver.d.ts","sourceRoot":"","sources":["../src/receiver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,qBAAa,QAAQ;IAIjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,IAAI;IALd,OAAO,CAAC,MAAM,CAAc;gBAGlB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAKtB,KAAK;IAML,IAAI;IAIJ,OAAO,CAAC,aAAa;CAsBtB"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Receiver = void 0;
37
+ const http = __importStar(require("http"));
38
+ /**
39
+ * Local HTTP receiver on localhost:9999.
40
+ * Accepts SDK trace payloads and immediately forwards them to the collector.
41
+ */
42
+ class Receiver {
43
+ forwarder;
44
+ bind;
45
+ port;
46
+ server;
47
+ constructor(forwarder, bind, port) {
48
+ this.forwarder = forwarder;
49
+ this.bind = bind;
50
+ this.port = port;
51
+ this.server = http.createServer((req, res) => this.handleRequest(req, res));
52
+ }
53
+ start() {
54
+ this.server.listen(this.port, this.bind, () => {
55
+ console.log(`[receiver] Listening on ${this.bind}:${this.port}`);
56
+ });
57
+ }
58
+ stop() {
59
+ this.server.close();
60
+ }
61
+ handleRequest(req, res) {
62
+ if (req.method !== 'POST' || req.url !== '/ingest/traces') {
63
+ res.writeHead(404);
64
+ res.end();
65
+ return;
66
+ }
67
+ const chunks = [];
68
+ req.on('data', (chunk) => chunks.push(chunk));
69
+ req.on('end', async () => {
70
+ try {
71
+ const body = JSON.parse(Buffer.concat(chunks).toString());
72
+ // Fire and forget — don't block the SDK
73
+ this.forwarder.sendTraces(body);
74
+ res.writeHead(202, { 'Content-Type': 'application/json' });
75
+ res.end(JSON.stringify({ accepted: true }));
76
+ }
77
+ catch {
78
+ res.writeHead(400);
79
+ res.end();
80
+ }
81
+ });
82
+ }
83
+ }
84
+ exports.Receiver = Receiver;
85
+ //# sourceMappingURL=receiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiver.js","sourceRoot":"","sources":["../src/receiver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAG7B;;;GAGG;AACH,MAAa,QAAQ;IAIT;IACA;IACA;IALF,MAAM,CAAc;IAE5B,YACU,SAAoB,EACpB,IAAY,EACZ,IAAY;QAFZ,cAAS,GAAT,SAAS,CAAW;QACpB,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAQ;QAEpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;YAC5C,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAEO,aAAa,CAAC,GAAyB,EAAE,GAAwB;QACvE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,gBAAgB,EAAE,CAAC;YAC1D,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1D,wCAAwC;gBACxC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAChC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA3CD,4BA2CC"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "launchlayer-apm-agent",
3
+ "version": "0.1.0",
4
+ "description": "Infrastructure monitoring agent for LaunchLayer APM — collects host, Docker, and PostgreSQL metrics",
5
+ "license": "MIT",
6
+ "keywords": ["apm", "monitoring", "agent", "infrastructure", "postgres", "docker", "metrics"],
7
+ "homepage": "https://apm.launchlayer.store",
8
+ "bin": {
9
+ "launchlayer-agent": "dist/index.js"
10
+ },
11
+ "files": ["dist", "config.yaml"],
12
+ "scripts": {
13
+ "dev": "tsx watch src/index.ts",
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "dependencies": {
19
+ "axios": "^1.7.7",
20
+ "js-yaml": "^4.1.0",
21
+ "pg": "^8.13.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/js-yaml": "^4.0.9",
25
+ "@types/pg": "^8.11.10",
26
+ "@types/node": "^22.0.0",
27
+ "typescript": "^5.6.0",
28
+ "tsx": "^4.19.0"
29
+ }
30
+ }