@ceon-oy/monitor-sdk 1.3.0 → 1.4.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 +92 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +40 -5
- package/dist/index.mjs +40 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Ceon Monitor SDK
|
|
2
2
|
|
|
3
|
-
Lightweight client SDK for integrating with the Ceon Monitor service. Provides error reporting, technology tracking, vulnerability auditing, and security event monitoring.
|
|
3
|
+
Lightweight client SDK for integrating with the Ceon Monitor service. Provides error reporting, technology tracking, vulnerability auditing, system metrics collection (CPU, RAM, disk), and security event monitoring.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
@@ -12,6 +12,7 @@ Lightweight client SDK for integrating with the Ceon Monitor service. Provides e
|
|
|
12
12
|
- [Technology Tracking](#technology-tracking)
|
|
13
13
|
- [Vulnerability Auditing](#vulnerability-auditing)
|
|
14
14
|
- [SDK-Based Health Checks](#sdk-based-health-checks)
|
|
15
|
+
- [System Metrics](#system-metrics)
|
|
15
16
|
- [Security Events](#security-events)
|
|
16
17
|
- [Framework Examples](#framework-examples)
|
|
17
18
|
- [Express.js](#expressjs)
|
|
@@ -490,6 +491,75 @@ const results = [
|
|
|
490
491
|
await monitor.submitHealthResults(results);
|
|
491
492
|
```
|
|
492
493
|
|
|
494
|
+
### System Metrics
|
|
495
|
+
|
|
496
|
+
The SDK automatically collects and reports server resource usage — CPU, RAM, and disk — to Ceon Monitor. No SDK configuration flag is needed; the feature activates based on the project settings configured in the Ceon Monitor dashboard.
|
|
497
|
+
|
|
498
|
+
#### How It Works
|
|
499
|
+
|
|
500
|
+
When the `MonitorClient` is created, it fetches your project settings from the server. If the project has **Enable Metric Collection** turned on, the SDK:
|
|
501
|
+
|
|
502
|
+
1. Reads `metricsIntervalSeconds` from project settings (configured in the dashboard)
|
|
503
|
+
2. Reads `metricsDiskPaths` from project settings (e.g. `["/", "/data"]`)
|
|
504
|
+
3. Starts collecting metrics at that interval automatically
|
|
505
|
+
4. POSTs metrics to the server — no manual calls needed
|
|
506
|
+
|
|
507
|
+
#### What Is Collected
|
|
508
|
+
|
|
509
|
+
| Metric | Method | Notes |
|
|
510
|
+
|--------|--------|-------|
|
|
511
|
+
| CPU usage % | Dual `os.cpus()` sample with 500 ms gap | Accurate active-cycle average |
|
|
512
|
+
| RAM total | `os.totalmem()` | Bytes |
|
|
513
|
+
| RAM used | `os.totalmem() - os.freemem()` | Bytes |
|
|
514
|
+
| RAM % | `usedMemory / totalMemory * 100` | |
|
|
515
|
+
| Disk total / used / free per path | `fs.statfs(path)` | Node.js 18.15+ built-in, zero external deps |
|
|
516
|
+
|
|
517
|
+
Hostname is automatically set via `os.hostname()` and included with every report.
|
|
518
|
+
|
|
519
|
+
#### Enable in Dashboard
|
|
520
|
+
|
|
521
|
+
1. Open the **Ceon Monitor** dashboard
|
|
522
|
+
2. Go to **Projects** and click **Edit** on your project
|
|
523
|
+
3. Enable the **System Metrics** widget
|
|
524
|
+
4. Click **Enable Metric Collection**
|
|
525
|
+
5. Set the collection interval (e.g. every 60 seconds)
|
|
526
|
+
6. Add disk paths to monitor (e.g. `/` for root, `/data` for a data volume)
|
|
527
|
+
7. Configure CPU / RAM / disk alert thresholds
|
|
528
|
+
8. Save
|
|
529
|
+
|
|
530
|
+
The SDK will pick up the new settings on its next startup.
|
|
531
|
+
|
|
532
|
+
#### Notifications
|
|
533
|
+
|
|
534
|
+
When a metric exceeds a configured threshold, Ceon Monitor sends a `SYSTEM_METRIC_CRITICAL` notification to any user who has subscribed to **System Metric Alerts** for that project. Subscribe in **Settings → Subscriptions**.
|
|
535
|
+
|
|
536
|
+
#### Node.js Version Requirement
|
|
537
|
+
|
|
538
|
+
`fs.statfs()` (used for disk monitoring) requires **Node.js 18.15 or later**. No external packages are needed.
|
|
539
|
+
|
|
540
|
+
#### Manual Metric Submission
|
|
541
|
+
|
|
542
|
+
You can also submit a metric reading manually:
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
await monitor.submitSystemMetric({
|
|
546
|
+
hostname: os.hostname(),
|
|
547
|
+
cpuPercent: 72.5,
|
|
548
|
+
memoryTotal: 8 * 1024 ** 3, // 8 GB in bytes
|
|
549
|
+
memoryUsed: 5 * 1024 ** 3, // 5 GB in bytes
|
|
550
|
+
memoryPercent: 62.5,
|
|
551
|
+
disks: [
|
|
552
|
+
{
|
|
553
|
+
path: '/',
|
|
554
|
+
total: 100 * 1024 ** 3, // 100 GB
|
|
555
|
+
used: 60 * 1024 ** 3, // 60 GB
|
|
556
|
+
free: 40 * 1024 ** 3, // 40 GB
|
|
557
|
+
usedPercent: 60,
|
|
558
|
+
},
|
|
559
|
+
],
|
|
560
|
+
});
|
|
561
|
+
```
|
|
562
|
+
|
|
493
563
|
### Security Events
|
|
494
564
|
|
|
495
565
|
#### Report Security Event
|
|
@@ -1092,6 +1162,10 @@ Runs npm audit and sends results to the server.
|
|
|
1092
1162
|
|
|
1093
1163
|
Runs npm audit on all directories configured in `auditPaths` and returns a combined summary.
|
|
1094
1164
|
|
|
1165
|
+
#### `submitSystemMetric(metric: SystemMetric): Promise<void>`
|
|
1166
|
+
|
|
1167
|
+
Manually submits a system metric reading. Under normal usage this is called automatically by the SDK's internal collection loop — use this only if you need custom collection logic.
|
|
1168
|
+
|
|
1095
1169
|
#### `flush(): Promise<void>`
|
|
1096
1170
|
|
|
1097
1171
|
Immediately sends all queued errors.
|
|
@@ -1160,6 +1234,23 @@ interface AuditPath {
|
|
|
1160
1234
|
environment: string; // Environment label (e.g., 'server', 'client')
|
|
1161
1235
|
}
|
|
1162
1236
|
|
|
1237
|
+
interface DiskMetric {
|
|
1238
|
+
path: string; // Mount path (e.g. '/', '/data')
|
|
1239
|
+
total: number; // Total bytes
|
|
1240
|
+
used: number; // Used bytes
|
|
1241
|
+
free: number; // Free bytes
|
|
1242
|
+
usedPercent: number; // 0–100
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
interface SystemMetric {
|
|
1246
|
+
hostname: string;
|
|
1247
|
+
cpuPercent: number;
|
|
1248
|
+
memoryTotal: number;
|
|
1249
|
+
memoryUsed: number;
|
|
1250
|
+
memoryPercent: number;
|
|
1251
|
+
disks: DiskMetric[];
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1163
1254
|
interface MultiAuditSummary {
|
|
1164
1255
|
results: Array<{
|
|
1165
1256
|
environment: string;
|
package/dist/index.d.mts
CHANGED
|
@@ -166,6 +166,7 @@ interface SdkHealthEndpoint {
|
|
|
166
166
|
intervalMs: number;
|
|
167
167
|
timeoutMs: number;
|
|
168
168
|
expectedStatus: number;
|
|
169
|
+
allowInsecureTls?: boolean;
|
|
169
170
|
}
|
|
170
171
|
interface SdkHealthResult {
|
|
171
172
|
endpointId: string;
|
|
@@ -231,6 +232,7 @@ declare class MonitorClient {
|
|
|
231
232
|
private sdkErrorsInCurrentWindow;
|
|
232
233
|
private sdkErrorWindowResetTimer;
|
|
233
234
|
private metricsCollectionTimer;
|
|
235
|
+
private metricsSettingsCheckTimer;
|
|
234
236
|
constructor(config: MonitorClientConfig);
|
|
235
237
|
/**
|
|
236
238
|
* Security: Validate and sanitize metadata to prevent oversized payloads
|
|
@@ -491,6 +493,7 @@ declare class MonitorClient {
|
|
|
491
493
|
* Collects CPU, RAM, and disk usage using built-in Node.js modules.
|
|
492
494
|
*/
|
|
493
495
|
setupSystemMetricsCollection(): Promise<void>;
|
|
496
|
+
private startMetricsCollection;
|
|
494
497
|
private stopMetricsCollection;
|
|
495
498
|
/**
|
|
496
499
|
* Collect system metrics (CPU, RAM, disk) using built-in Node.js modules
|
package/dist/index.d.ts
CHANGED
|
@@ -166,6 +166,7 @@ interface SdkHealthEndpoint {
|
|
|
166
166
|
intervalMs: number;
|
|
167
167
|
timeoutMs: number;
|
|
168
168
|
expectedStatus: number;
|
|
169
|
+
allowInsecureTls?: boolean;
|
|
169
170
|
}
|
|
170
171
|
interface SdkHealthResult {
|
|
171
172
|
endpointId: string;
|
|
@@ -231,6 +232,7 @@ declare class MonitorClient {
|
|
|
231
232
|
private sdkErrorsInCurrentWindow;
|
|
232
233
|
private sdkErrorWindowResetTimer;
|
|
233
234
|
private metricsCollectionTimer;
|
|
235
|
+
private metricsSettingsCheckTimer;
|
|
234
236
|
constructor(config: MonitorClientConfig);
|
|
235
237
|
/**
|
|
236
238
|
* Security: Validate and sanitize metadata to prevent oversized payloads
|
|
@@ -491,6 +493,7 @@ declare class MonitorClient {
|
|
|
491
493
|
* Collects CPU, RAM, and disk usage using built-in Node.js modules.
|
|
492
494
|
*/
|
|
493
495
|
setupSystemMetricsCollection(): Promise<void>;
|
|
496
|
+
private startMetricsCollection;
|
|
494
497
|
private stopMetricsCollection;
|
|
495
498
|
/**
|
|
496
499
|
* Collect system metrics (CPU, RAM, disk) using built-in Node.js modules
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,7 @@ var MonitorClient = class {
|
|
|
101
101
|
this.sdkErrorWindowResetTimer = null;
|
|
102
102
|
// System metrics collection (on-premise only, opt-in)
|
|
103
103
|
this.metricsCollectionTimer = null;
|
|
104
|
+
this.metricsSettingsCheckTimer = null;
|
|
104
105
|
if (!config.apiKey || config.apiKey.trim().length === 0) {
|
|
105
106
|
throw new Error("[MonitorClient] API key is required");
|
|
106
107
|
}
|
|
@@ -1347,6 +1348,19 @@ var MonitorClient = class {
|
|
|
1347
1348
|
"Content-Type": "application/json"
|
|
1348
1349
|
};
|
|
1349
1350
|
}
|
|
1351
|
+
if (endpoint.allowInsecureTls) {
|
|
1352
|
+
try {
|
|
1353
|
+
const undici = await import(
|
|
1354
|
+
/* webpackIgnore: true */
|
|
1355
|
+
"undici"
|
|
1356
|
+
);
|
|
1357
|
+
const Agent = undici.Agent;
|
|
1358
|
+
requestOptions.dispatcher = new Agent({
|
|
1359
|
+
connect: { rejectUnauthorized: false }
|
|
1360
|
+
});
|
|
1361
|
+
} catch {
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1350
1364
|
const response = await this.fetchWithTimeout(
|
|
1351
1365
|
endpoint.url,
|
|
1352
1366
|
requestOptions,
|
|
@@ -1487,16 +1501,33 @@ var MonitorClient = class {
|
|
|
1487
1501
|
async setupSystemMetricsCollection() {
|
|
1488
1502
|
const settings = await this.fetchProjectSettings();
|
|
1489
1503
|
if (!settings?.metricsEnabled) {
|
|
1504
|
+
this.metricsSettingsCheckTimer = setInterval(() => {
|
|
1505
|
+
this.fetchProjectSettings().then((latestSettings) => {
|
|
1506
|
+
if (latestSettings?.metricsEnabled) {
|
|
1507
|
+
clearInterval(this.metricsSettingsCheckTimer);
|
|
1508
|
+
this.metricsSettingsCheckTimer = null;
|
|
1509
|
+
this.startMetricsCollection(latestSettings);
|
|
1510
|
+
}
|
|
1511
|
+
}).catch(() => {
|
|
1512
|
+
});
|
|
1513
|
+
}, 3e5);
|
|
1490
1514
|
return;
|
|
1491
1515
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1516
|
+
this.startMetricsCollection(settings);
|
|
1517
|
+
}
|
|
1518
|
+
startMetricsCollection(settings) {
|
|
1519
|
+
const intervalMs = Math.max(3e4, (settings.metricsIntervalSeconds ?? 3600) * 1e3);
|
|
1520
|
+
console.log(`[MonitorClient] System metrics collection enabled (every ${intervalMs / 1e3}s)`);
|
|
1521
|
+
const initialDiskPaths = settings.metricsDiskPaths ?? ["/"];
|
|
1522
|
+
this.collectAndSubmitMetrics(initialDiskPaths).catch((err) => {
|
|
1496
1523
|
this.reportError("SYSTEM_METRICS", "Initial system metrics collection failed", err);
|
|
1497
1524
|
});
|
|
1498
1525
|
this.metricsCollectionTimer = setInterval(() => {
|
|
1499
|
-
this.
|
|
1526
|
+
this.fetchProjectSettings().then((latestSettings) => {
|
|
1527
|
+
if (!latestSettings?.metricsEnabled) return;
|
|
1528
|
+
const diskPaths = latestSettings.metricsDiskPaths ?? ["/"];
|
|
1529
|
+
return this.collectAndSubmitMetrics(diskPaths);
|
|
1530
|
+
}).catch((err) => {
|
|
1500
1531
|
this.reportError("SYSTEM_METRICS", "Scheduled system metrics collection failed", err);
|
|
1501
1532
|
});
|
|
1502
1533
|
}, intervalMs);
|
|
@@ -1506,6 +1537,10 @@ var MonitorClient = class {
|
|
|
1506
1537
|
clearInterval(this.metricsCollectionTimer);
|
|
1507
1538
|
this.metricsCollectionTimer = null;
|
|
1508
1539
|
}
|
|
1540
|
+
if (this.metricsSettingsCheckTimer) {
|
|
1541
|
+
clearInterval(this.metricsSettingsCheckTimer);
|
|
1542
|
+
this.metricsSettingsCheckTimer = null;
|
|
1543
|
+
}
|
|
1509
1544
|
}
|
|
1510
1545
|
/**
|
|
1511
1546
|
* Collect system metrics (CPU, RAM, disk) using built-in Node.js modules
|
package/dist/index.mjs
CHANGED
|
@@ -65,6 +65,7 @@ var MonitorClient = class {
|
|
|
65
65
|
this.sdkErrorWindowResetTimer = null;
|
|
66
66
|
// System metrics collection (on-premise only, opt-in)
|
|
67
67
|
this.metricsCollectionTimer = null;
|
|
68
|
+
this.metricsSettingsCheckTimer = null;
|
|
68
69
|
if (!config.apiKey || config.apiKey.trim().length === 0) {
|
|
69
70
|
throw new Error("[MonitorClient] API key is required");
|
|
70
71
|
}
|
|
@@ -1311,6 +1312,19 @@ var MonitorClient = class {
|
|
|
1311
1312
|
"Content-Type": "application/json"
|
|
1312
1313
|
};
|
|
1313
1314
|
}
|
|
1315
|
+
if (endpoint.allowInsecureTls) {
|
|
1316
|
+
try {
|
|
1317
|
+
const undici = await import(
|
|
1318
|
+
/* webpackIgnore: true */
|
|
1319
|
+
"undici"
|
|
1320
|
+
);
|
|
1321
|
+
const Agent = undici.Agent;
|
|
1322
|
+
requestOptions.dispatcher = new Agent({
|
|
1323
|
+
connect: { rejectUnauthorized: false }
|
|
1324
|
+
});
|
|
1325
|
+
} catch {
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1314
1328
|
const response = await this.fetchWithTimeout(
|
|
1315
1329
|
endpoint.url,
|
|
1316
1330
|
requestOptions,
|
|
@@ -1451,16 +1465,33 @@ var MonitorClient = class {
|
|
|
1451
1465
|
async setupSystemMetricsCollection() {
|
|
1452
1466
|
const settings = await this.fetchProjectSettings();
|
|
1453
1467
|
if (!settings?.metricsEnabled) {
|
|
1468
|
+
this.metricsSettingsCheckTimer = setInterval(() => {
|
|
1469
|
+
this.fetchProjectSettings().then((latestSettings) => {
|
|
1470
|
+
if (latestSettings?.metricsEnabled) {
|
|
1471
|
+
clearInterval(this.metricsSettingsCheckTimer);
|
|
1472
|
+
this.metricsSettingsCheckTimer = null;
|
|
1473
|
+
this.startMetricsCollection(latestSettings);
|
|
1474
|
+
}
|
|
1475
|
+
}).catch(() => {
|
|
1476
|
+
});
|
|
1477
|
+
}, 3e5);
|
|
1454
1478
|
return;
|
|
1455
1479
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1480
|
+
this.startMetricsCollection(settings);
|
|
1481
|
+
}
|
|
1482
|
+
startMetricsCollection(settings) {
|
|
1483
|
+
const intervalMs = Math.max(3e4, (settings.metricsIntervalSeconds ?? 3600) * 1e3);
|
|
1484
|
+
console.log(`[MonitorClient] System metrics collection enabled (every ${intervalMs / 1e3}s)`);
|
|
1485
|
+
const initialDiskPaths = settings.metricsDiskPaths ?? ["/"];
|
|
1486
|
+
this.collectAndSubmitMetrics(initialDiskPaths).catch((err) => {
|
|
1460
1487
|
this.reportError("SYSTEM_METRICS", "Initial system metrics collection failed", err);
|
|
1461
1488
|
});
|
|
1462
1489
|
this.metricsCollectionTimer = setInterval(() => {
|
|
1463
|
-
this.
|
|
1490
|
+
this.fetchProjectSettings().then((latestSettings) => {
|
|
1491
|
+
if (!latestSettings?.metricsEnabled) return;
|
|
1492
|
+
const diskPaths = latestSettings.metricsDiskPaths ?? ["/"];
|
|
1493
|
+
return this.collectAndSubmitMetrics(diskPaths);
|
|
1494
|
+
}).catch((err) => {
|
|
1464
1495
|
this.reportError("SYSTEM_METRICS", "Scheduled system metrics collection failed", err);
|
|
1465
1496
|
});
|
|
1466
1497
|
}, intervalMs);
|
|
@@ -1470,6 +1501,10 @@ var MonitorClient = class {
|
|
|
1470
1501
|
clearInterval(this.metricsCollectionTimer);
|
|
1471
1502
|
this.metricsCollectionTimer = null;
|
|
1472
1503
|
}
|
|
1504
|
+
if (this.metricsSettingsCheckTimer) {
|
|
1505
|
+
clearInterval(this.metricsSettingsCheckTimer);
|
|
1506
|
+
this.metricsSettingsCheckTimer = null;
|
|
1507
|
+
}
|
|
1473
1508
|
}
|
|
1474
1509
|
/**
|
|
1475
1510
|
* Collect system metrics (CPU, RAM, disk) using built-in Node.js modules
|
package/package.json
CHANGED