Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79db79de96 | |||
| a01e21663f | |||
| ed05c01abc | |||
| 8fd8b9a915 | |||
| 56757e1c71 | |||
| d2ee396cf7 |
20
changelog.md
20
changelog.md
@@ -1,5 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-03-23 - 3.0.3 - fix(prometheus)
|
||||
clean up default Prometheus metric collectors on stop
|
||||
|
||||
- Return cleanup handlers from default metric registration for event loop and GC observers.
|
||||
- Dispose registered Prometheus default metric collectors when stopping Smartmetrics to prevent lingering observers.
|
||||
|
||||
## 2026-03-02 - 3.0.2 - fix(pidusage)
|
||||
prune history entries for PIDs not present in the requested set to avoid stale data and memory growth
|
||||
|
||||
- Deletes entries from the history map when a PID is not included in the current pids array
|
||||
- Prevents accumulation of stale PID histories and potential memory growth
|
||||
- Change implemented in ts/smartmetrics.pidusage.ts alongside the metrics result construction
|
||||
|
||||
## 2026-02-19 - 3.0.1 - fix(smartmetrics)
|
||||
no code changes detected; no version bump or release required
|
||||
|
||||
- git diff contained no modifications
|
||||
- current package.json version is 3.0.0
|
||||
- no dependency or file changes to warrant a release
|
||||
|
||||
## 2026-02-19 - 3.0.0 - BREAKING CHANGE(smartmetrics)
|
||||
add system-wide metrics collection, Prometheus gauges, and normalized CPU reporting
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@push.rocks/smartmetrics",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.3",
|
||||
"private": false,
|
||||
"description": "A package for easy collection and reporting of system and process metrics.",
|
||||
"main": "dist_ts/index.js",
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartmetrics',
|
||||
version: '3.0.0',
|
||||
version: '3.0.3',
|
||||
description: 'A package for easy collection and reporting of system and process metrics.'
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ export class SmartMetrics {
|
||||
// HTTP server for Prometheus endpoint
|
||||
private prometheusServer?: plugins.http.Server;
|
||||
private prometheusPort?: number;
|
||||
private cleanupDefaultMetrics?: () => void;
|
||||
|
||||
public setup() {
|
||||
this.registry = new plugins.prom.Registry();
|
||||
plugins.prom.collectDefaultMetrics(this.registry);
|
||||
this.cleanupDefaultMetrics = plugins.prom.collectDefaultMetrics(this.registry);
|
||||
|
||||
// Initialize custom gauges
|
||||
this.cpuPercentageGauge = new plugins.prom.Gauge({
|
||||
@@ -295,5 +296,9 @@ export class SmartMetrics {
|
||||
public stop() {
|
||||
this.started = false;
|
||||
this.disablePrometheusEndpoint();
|
||||
if (this.cleanupDefaultMetrics) {
|
||||
this.cleanupDefaultMetrics();
|
||||
this.cleanupDefaultMetrics = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,5 +125,12 @@ export async function getPidUsage(
|
||||
});
|
||||
}
|
||||
|
||||
// Prune history entries for PIDs no longer in the requested set
|
||||
for (const histPid of history.keys()) {
|
||||
if (!pids.includes(histPid)) {
|
||||
history.delete(histPid);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -288,20 +288,25 @@ export class Histogram implements IMetric {
|
||||
|
||||
// ── Default Metrics Collectors ──────────────────────────────────────────────
|
||||
|
||||
export function collectDefaultMetrics(registry: Registry): void {
|
||||
export function collectDefaultMetrics(registry: Registry): () => void {
|
||||
registerProcessCpuTotal(registry);
|
||||
registerProcessStartTime(registry);
|
||||
registerProcessMemory(registry);
|
||||
registerProcessOpenFds(registry);
|
||||
registerProcessMaxFds(registry);
|
||||
registerEventLoopLag(registry);
|
||||
const cleanupEventLoop = registerEventLoopLag(registry);
|
||||
registerProcessHandles(registry);
|
||||
registerProcessRequests(registry);
|
||||
registerProcessResources(registry);
|
||||
registerHeapSizeAndUsed(registry);
|
||||
registerHeapSpaces(registry);
|
||||
registerVersion(registry);
|
||||
registerGc(registry);
|
||||
const cleanupGc = registerGc(registry);
|
||||
|
||||
return () => {
|
||||
cleanupEventLoop();
|
||||
cleanupGc();
|
||||
};
|
||||
}
|
||||
|
||||
function registerProcessCpuTotal(registry: Registry): void {
|
||||
@@ -420,7 +425,7 @@ function registerProcessMaxFds(registry: Registry): void {
|
||||
});
|
||||
}
|
||||
|
||||
function registerEventLoopLag(registry: Registry): void {
|
||||
function registerEventLoopLag(registry: Registry): () => void {
|
||||
let histogram: ReturnType<typeof monitorEventLoopDelay> | null = null;
|
||||
try {
|
||||
histogram = monitorEventLoopDelay({ resolution: 10 });
|
||||
@@ -496,6 +501,13 @@ function registerEventLoopLag(registry: Registry): void {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (histogram) {
|
||||
histogram.disable();
|
||||
histogram = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function registerProcessHandles(registry: Registry): void {
|
||||
@@ -632,7 +644,7 @@ function registerVersion(registry: Registry): void {
|
||||
});
|
||||
}
|
||||
|
||||
function registerGc(registry: Registry): void {
|
||||
function registerGc(registry: Registry): () => void {
|
||||
const gcHistogram = new Histogram({
|
||||
name: 'nodejs_gc_duration_seconds',
|
||||
help: 'Garbage collection duration by kind, in seconds.',
|
||||
@@ -649,8 +661,9 @@ function registerGc(registry: Registry): void {
|
||||
15: 'All',
|
||||
};
|
||||
|
||||
let obs: PerformanceObserver | null = null;
|
||||
try {
|
||||
const obs = new PerformanceObserver((list) => {
|
||||
obs = new PerformanceObserver((list) => {
|
||||
for (const entry of list.getEntries()) {
|
||||
const gcEntry = entry as any;
|
||||
const kind = kindLabels[gcEntry.detail?.kind ?? gcEntry.kind] || 'Unknown';
|
||||
@@ -661,6 +674,13 @@ function registerGc(registry: Registry): void {
|
||||
} catch {
|
||||
// GC observation not available
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (obs) {
|
||||
obs.disconnect();
|
||||
obs = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user