Skip to content

Commit 2f25924

Browse files
committed
lib: replace periodic gauge with a pull gauge
1 parent 2ca7cac commit 2f25924

3 files changed

Lines changed: 45 additions & 210 deletions

File tree

doc/api/metrics.md

Lines changed: 24 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -140,30 +140,29 @@ const t = dbQueryTimer.create({ query: 'SELECT * FROM users' });
140140
const duration = t.stop(); // Returns duration in milliseconds
141141
```
142142

143-
### `metrics.periodicGauge(name, interval, fn[, meta])`
143+
### `metrics.pullGauge(name, fn[, meta])`
144144

145145
<!-- YAML
146146
added: REPLACEME
147147
-->
148148

149-
* `name` {string} The name of the periodic gauge metric.
150-
* `interval` {number} The interval in milliseconds between samples.
149+
* `name` {string} The name of the pull gauge metric.
151150
* `fn` {Function} A function that returns the current value.
152151
* `meta` {Object} Optional metadata to attach to all reports.
153-
* Returns: {metrics.PeriodicGauge}
152+
* Returns: {metrics.PullGauge}
154153

155-
Creates a gauge that automatically samples a value at regular intervals.
154+
Creates a gauge that samples a value on-demand by calling the provided function.
156155

157156
```mjs
158-
import { periodicGauge } from 'node:metrics';
157+
import { pullGauge } from 'node:metrics';
159158
import { cpuUsage } from 'node:process';
160159

161-
const cpu = periodicGauge('cpu.usage', 5000, () => {
160+
const cpu = pullGauge('cpu.usage', () => {
162161
return cpuUsage().user;
163162
});
164163

165-
// Stop sampling when no longer needed
166-
cpu.stop();
164+
// Sample the gauge when needed
165+
cpu.sample();
167166
```
168167

169168
## Classes
@@ -184,7 +183,7 @@ added: REPLACEME
184183

185184
* {string}
186185

187-
The type of the metric (e.g., 'counter', 'gauge', 'periodicGauge',
186+
The type of the metric (e.g., 'counter', 'gauge', 'pullGauge',
188187
'timer').
189188

190189
#### `metricReport.name`
@@ -301,7 +300,7 @@ added: REPLACEME
301300

302301
* {string}
303302

304-
The type of the metric (e.g., 'counter', 'gauge', 'periodicGauge',
303+
The type of the metric (e.g., 'counter', 'gauge', 'pullGauge',
305304
'timer').
306305

307306
#### `metric.name`
@@ -659,17 +658,17 @@ const dbQueryTimer = timer('db.query.duration');
659658
const t = dbQueryTimer.create({ query: 'SELECT * FROM users' });
660659
```
661660

662-
### Class: `PeriodicGauge`
661+
### Class: `PullGauge`
663662

664663
* Extends: {metrics.Gauge}
665664

666665
<!-- YAML
667666
added: REPLACEME
668667
-->
669668

670-
A gauge that automatically samples values at regular intervals.
669+
A gauge that samples values on-demand when the `sample()` method is called.
671670

672-
#### `periodicGauge.metric`
671+
#### `pullGauge.metric`
673672

674673
<!-- YAML
675674
added: REPLACEME
@@ -679,81 +678,31 @@ added: REPLACEME
679678

680679
The underlying metric instance used for reporting.
681680

682-
#### `periodicGauge.interval`
681+
#### `pullGauge.sample([meta])`
683682

684683
<!-- YAML
685684
added: REPLACEME
686685
-->
687686

688-
* {number}
689-
690-
The sampling interval in milliseconds. Setting this property reschedules the timer.
691-
692-
#### `periodicGauge.schedule()`
693-
694-
<!-- YAML
695-
added: REPLACEME
696-
-->
697-
698-
Schedules the periodic sampling based on the configured interval. This is called
699-
automatically when the gauge is created, but can be called again to reschedule
700-
after it has been stopped.
701-
702-
```mjs
703-
import { periodicGauge } from 'node:metrics';
704-
import { cpuUsage } from 'node:process';
705-
706-
const cpu = periodicGauge('cpu.usage', 5000, () => {
707-
return cpuUsage().user;
708-
});
709-
710-
cpu.stop();
711-
712-
// Reschedule sampling
713-
cpu.schedule();
714-
```
715-
716-
#### `periodicGauge.stop()`
687+
* `meta` {Object} Additional metadata for this specific sample.
688+
* Returns: {number} The sampled value.
717689

718-
<!-- YAML
719-
added: REPLACEME
720-
-->
721-
722-
Stops the periodic sampling.
690+
Calls the configured function to get the current value and reports it.
723691

724692
```mjs
725-
import { periodicGauge } from 'node:metrics';
693+
import { pullGauge } from 'node:metrics';
726694
import { cpuUsage } from 'node:process';
727695

728-
const cpu = periodicGauge('cpu.usage', 5000, () => {
696+
const cpu = pullGauge('cpu.usage', () => {
729697
return cpuUsage().user;
730698
});
731699

732-
// Stop sampling when no longer needed
733-
cpu.stop();
734-
```
735-
736-
#### `periodicGauge[Symbol.dispose]()`
737-
738-
<!-- YAML
739-
added: REPLACEME
740-
-->
741-
742-
Allows `using` syntax to automatically stop the periodic gauge when done.
743-
744-
```mjs
745-
import { periodicGauge } from 'node:metrics';
746-
import { cpuUsage } from 'node:process';
700+
// Sample the gauge when needed
701+
const value = cpu.sample();
702+
console.log(`Current CPU usage: ${value}`);
747703

748-
{
749-
using cpu = periodicGauge('cpu.usage', 1000, () => {
750-
return cpuUsage().user;
751-
});
752-
753-
// Perform operations that require periodic sampling...
754-
755-
// Sampling is automatically stopped here
756-
}
704+
// Sample with additional metadata
705+
cpu.sample({ threshold: 'high' });
757706
```
758707

759708

lib/metrics.js

Lines changed: 21 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* - Counter: An increasing or decreasing value.
77
* - Gauge: A snapshot of a single value in time.
88
* - Timer: A duration in milliseconds.
9-
* - PeriodicGauge: A gauge which periodically updates its value by calling a function.
9+
* - PullGauge: A gauge which updates its value by calling a function when sampled.
1010
* # TODO(qard):
1111
* - Histograms
1212
* - Distributions/Summaries
@@ -32,7 +32,6 @@ const {
3232
ERR_INVALID_ARG_VALUE,
3333
},
3434
} = require('internal/errors');
35-
const { setInterval, clearInterval } = require('internal/timers');
3635

3736
const {
3837
channel,
@@ -117,7 +116,7 @@ class MetricReport {
117116
return {
118117
counter: 'c',
119118
gauge: 'g',
120-
periodicGauge: 'g',
119+
pullGauge: 'g',
121120
timer: 'ms',
122121
}[type];
123122
}
@@ -421,96 +420,34 @@ class Timer extends Gauge {
421420
}
422421

423422
/**
424-
* A gauge which periodically updates its value by calling a function and
425-
* setting the value to the result.
423+
* A gauge which updates its value by calling a function when sampled.
426424
*/
427-
class PeriodicGauge extends Gauge {
428-
#timer;
429-
#interval;
425+
class PullGauge extends Gauge {
430426
#fn;
431427

432428
/**
433-
* Construct a new periodic gauge.
429+
* Construct a new pull gauge.
434430
* @param {Metric} metric The metric to report to.
435-
* @param {number} interval The interval in milliseconds to update the gauge.
436-
* @param {Function} fn The function to call to update the gauge.
431+
* @param {Function} fn The function to call to get the gauge value.
437432
*/
438-
constructor(metric, interval, fn) {
433+
constructor(metric, fn) {
439434
super(metric);
440435

441-
if (typeof interval !== 'number' || interval <= 0) {
442-
throw new ERR_INVALID_ARG_TYPE('interval', ['number'], interval);
443-
}
444436
if (typeof fn !== 'function') {
445437
throw new ERR_INVALID_ARG_TYPE('fn', ['function'], fn);
446438
}
447439

448-
this.#timer = undefined;
449-
this.#interval = interval;
450440
this.#fn = fn;
451-
452-
this.schedule();
453-
}
454-
455-
/**
456-
* Schedule the update timer.
457-
*/
458-
schedule() {
459-
this.stop();
460-
461-
this.#timer = setInterval(() => {
462-
this.reset(this.#fn());
463-
}, this.interval);
464-
465-
// Don't keep the process alive just for this timer.
466-
this.#timer.unref();
467-
}
468-
469-
/**
470-
* The interval in milliseconds at which to update the value. If changed,
471-
* the timer will be rescheduled.
472-
* @property {number} interval
473-
*/
474-
set interval(interval) {
475-
if (typeof interval !== 'number' || interval <= 0) {
476-
throw new ERR_INVALID_ARG_TYPE('interval', ['number'], interval);
477-
}
478-
this.#interval = interval;
479-
this.schedule();
480-
}
481-
get interval() {
482-
return this.#interval;
483441
}
484442

485443
/**
486-
* Stop the periodic gauge.
487-
*/
488-
stop() {
489-
if (this.#timer !== undefined) {
490-
clearInterval(this.#timer);
491-
this.#timer = undefined;
492-
}
493-
}
494-
495-
/**
496-
* Reference the timer to prevent to loop from exiting.
497-
*/
498-
ref() {
499-
this.#timer?.ref();
500-
}
501-
502-
/**
503-
* Unreference the timer to allow the loop to exit.
504-
*/
505-
unref() {
506-
this.#timer?.unref();
507-
}
508-
509-
/**
510-
* Support `using` syntax to automatically stop the periodic gauge when done.
444+
* Sample the gauge by calling the function and reporting the value.
445+
* @param {object} [meta] Additional metadata to include with the report.
511446
*/
512-
[SymbolDispose]() {
513-
this.stop();
447+
sample(meta) {
448+
const value = this.#fn();
449+
this.reset(value, meta);
450+
return value;
514451
}
515452
}
516453

@@ -561,7 +498,7 @@ function timer(name, meta) {
561498
const metricTypes = {
562499
counter: Counter,
563500
gauge: Gauge,
564-
periodicGauge: PeriodicGauge,
501+
pullGauge: PullGauge,
565502
timer: Timer,
566503
};
567504

@@ -619,28 +556,27 @@ function metric(type, name, meta) {
619556
}
620557

621558
/**
622-
* Create a periodic gauge metric.
623-
* @param {string} name The name of the periodic gauge.
624-
* @param {number} interval The interval in milliseconds to update the gauge.
625-
* @param {Function} fn The function to call to update the gauge.
559+
* Create a pull gauge metric.
560+
* @param {string} name The name of the pull gauge.
561+
* @param {Function} fn The function to call to get the gauge value.
626562
* @param {object} [meta] Additional metadata to include with the report.
627-
* @returns {PeriodicGauge} The periodic gauge metric.
563+
* @returns {PullGauge} The pull gauge metric.
628564
*/
629-
const periodicGauge = direct('periodicGauge');
565+
const pullGauge = direct('pullGauge');
630566

631567
module.exports = {
632568
MetricReport,
633569
Metric,
634570
Gauge,
635571
Counter,
636572
Timer,
637-
PeriodicGauge,
573+
PullGauge,
638574
TimerFactory,
639575

640576

641577
counter,
642578
gauge,
643579
metric,
644-
periodicGauge,
580+
pullGauge,
645581
timer,
646582
};

0 commit comments

Comments
 (0)