Skip to content

Commit 6aed8bd

Browse files
gibbonjjmjameswh
andauthored
feat(metrics): add UpDownCounter to Buffered Metrics and RuntimeMetricMeter (#2007)
Co-authored-by: James Watkins-Harvey <james.watkinsharvey@temporal.io>
1 parent 505426b commit 6aed8bd

8 files changed

Lines changed: 621 additions & 131 deletions

File tree

packages/common/src/metrics.ts

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ export interface MetricMeter {
4040
*/
4141
createGauge(name: string, valueType?: NumericMetricValueType, unit?: string, description?: string): MetricGauge;
4242

43+
/**
44+
* Create a new up-down counter metric that supports adding signed values.
45+
*
46+
* @param name Name for the up-down counter metric.
47+
* @param unit Unit for the up-down counter metric. Optional.
48+
* @param description Description for the up-down counter metric. Optional.
49+
*/
50+
createUpDownCounter?(name: string, unit?: string, description?: string): MetricUpDownCounter;
51+
4352
/**
4453
* Return a clone of this meter, with additional tags. All metrics created off the meter will
4554
* have the tags.
@@ -104,7 +113,7 @@ export type NumericMetricValueType = 'int' | 'float';
104113
*
105114
* @experimental The Metric API is an experimental feature and may be subject to change.
106115
*/
107-
export type MetricKind = 'counter' | 'histogram' | 'gauge';
116+
export type MetricKind = 'counter' | 'histogram' | 'gauge' | 'up-down-counter';
108117

109118
/**
110119
* A metric that supports adding values as a counter.
@@ -181,6 +190,31 @@ export interface MetricGauge extends Metric {
181190
kind: 'gauge';
182191
}
183192

193+
/**
194+
* A metric that supports adding signed values as an up-down counter.
195+
*
196+
* @experimental The Metric API is an experimental feature and may be subject to change.
197+
*/
198+
export interface MetricUpDownCounter extends Metric {
199+
/**
200+
* Add the given value to the up-down counter. Value may be negative.
201+
*
202+
* @param value Value to add (can be positive or negative).
203+
* @param extraTags Extra tags if any.
204+
*/
205+
add(value: number, extraTags?: MetricTags): void;
206+
207+
/**
208+
* Return a clone of this up-down counter, with additional tags.
209+
*
210+
* @param tags Tags to append to existing tags.
211+
*/
212+
withTags(tags: MetricTags): MetricUpDownCounter;
213+
214+
kind: 'up-down-counter';
215+
valueType: 'int';
216+
}
217+
184218
////////////////////////////////////////////////////////////////////////////////////////////////////
185219

186220
/**
@@ -248,6 +282,23 @@ class NoopMetricMeter implements MetricMeter {
248282
};
249283
}
250284

285+
createUpDownCounter(name: string, unit?: string, description?: string): MetricUpDownCounter {
286+
return {
287+
name,
288+
unit,
289+
description,
290+
291+
kind: 'up-down-counter',
292+
valueType: 'int',
293+
294+
add(_value, _extraTags) {},
295+
296+
withTags(_extraTags) {
297+
return this;
298+
},
299+
};
300+
}
301+
251302
withTags(_extraTags: MetricTags): MetricMeter {
252303
return this;
253304
}
@@ -326,6 +377,16 @@ export class MetricMeterWithComposedTags implements MetricMeter {
326377
return new MetricGaugeWithComposedTags(parentGauge, this.contributors);
327378
}
328379

380+
createUpDownCounter(name: string, unit?: string, description?: string): MetricUpDownCounter {
381+
// FIXME: Remove this guard once up-down-counter support is complete on all MetricMeter
382+
// implementations and `createUpDownCounter` is no longer optional on MetricMeter.
383+
if (!this.parentMeter.createUpDownCounter) {
384+
throw new Error('createUpDownCounter is not supported by the underlying meter');
385+
}
386+
const parentCounter = this.parentMeter.createUpDownCounter(name, unit, description);
387+
return new MetricUpDownCounterWithComposedTags(parentCounter, this.contributors);
388+
}
389+
329390
withTags(tags: MetricTags): MetricMeter {
330391
return MetricMeterWithComposedTags.compose(this, tags);
331392
}
@@ -443,6 +504,42 @@ class MetricGaugeWithComposedTags implements MetricGauge {
443504
}
444505
}
445506

507+
/**
508+
* @internal
509+
* @hidden
510+
*/
511+
class MetricUpDownCounterWithComposedTags implements MetricUpDownCounter {
512+
public readonly kind = 'up-down-counter';
513+
public readonly valueType = 'int';
514+
515+
constructor(
516+
private parentCounter: MetricUpDownCounter,
517+
private contributors: MetricTagsOrFunc[]
518+
) {}
519+
520+
add(value: number, extraTags?: MetricTags | undefined): void {
521+
this.parentCounter.add(value, resolveTags(this.contributors, extraTags));
522+
}
523+
524+
withTags(extraTags: MetricTags): MetricUpDownCounter {
525+
const contributors = appendToChain(this.contributors, extraTags);
526+
if (contributors === undefined) return this;
527+
return new MetricUpDownCounterWithComposedTags(this.parentCounter, contributors);
528+
}
529+
530+
get name(): string {
531+
return this.parentCounter.name;
532+
}
533+
534+
get unit(): string | undefined {
535+
return this.parentCounter.unit;
536+
}
537+
538+
get description(): string | undefined {
539+
return this.parentCounter.description;
540+
}
541+
}
542+
446543
function resolveTags(contributors: MetricTagsOrFunc[], extraTags?: MetricTags): MetricTags {
447544
const resolved = {};
448545
for (const contributor of contributors) {

0 commit comments

Comments
 (0)