|
17 | 17 | import * as types from '@opentelemetry/types'; |
18 | 18 | import { TimeSeries } from './export/types'; |
19 | 19 |
|
| 20 | +/** |
| 21 | + * This class represent the base to handle, which is responsible for generating |
| 22 | + * the TimeSeries. |
| 23 | + */ |
| 24 | +export class BaseHandle { |
| 25 | + protected _data = 0; |
| 26 | + |
| 27 | + constructor(private readonly _labels: string[]) {} |
| 28 | + |
| 29 | + /** |
| 30 | + * Returns the TimeSeries with one or more Point. |
| 31 | + * |
| 32 | + * @param timestamp The time at which the handle is recorded. |
| 33 | + * @returns The TimeSeries. |
| 34 | + */ |
| 35 | + getTimeSeries(timestamp: types.HrTime): TimeSeries { |
| 36 | + return { |
| 37 | + labelValues: this._labels.map(value => ({ value })), |
| 38 | + points: [{ value: this._data, timestamp }], |
| 39 | + }; |
| 40 | + } |
| 41 | +} |
| 42 | + |
20 | 43 | /** |
21 | 44 | * CounterHandle allows the SDK to observe/record a single metric event. The |
22 | 45 | * value of single handle in the `Counter` associated with specified label |
23 | 46 | * values. |
24 | 47 | */ |
25 | | -export class CounterHandle implements types.CounterHandle { |
26 | | - private _data = 0; |
27 | | - |
| 48 | +export class CounterHandle extends BaseHandle implements types.CounterHandle { |
28 | 49 | constructor( |
29 | 50 | private readonly _disabled: boolean, |
30 | 51 | private readonly _monotonic: boolean, |
| 52 | + private readonly _valueType: types.ValueType, |
31 | 53 | private readonly _labelValues: string[], |
32 | 54 | private readonly _logger: types.Logger |
33 | | - ) {} |
| 55 | + ) { |
| 56 | + super(_labelValues); |
| 57 | + } |
34 | 58 |
|
35 | 59 | add(value: number): void { |
36 | 60 | if (this._disabled) return; |
37 | 61 |
|
38 | 62 | if (this._monotonic && value < 0) { |
39 | | - this._logger.error('Monotonic counter cannot descend.'); |
| 63 | + this._logger.error( |
| 64 | + `Monotonic counter cannot descend for ${this._labelValues}` |
| 65 | + ); |
40 | 66 | return; |
41 | 67 | } |
| 68 | + if (this._valueType === types.ValueType.INT && !Number.isInteger(value)) { |
| 69 | + this._logger.warn( |
| 70 | + `INT counter cannot accept a floating-point value for ${this._labelValues}, ignoring the fractional digits.` |
| 71 | + ); |
| 72 | + value = Math.trunc(value); |
| 73 | + } |
42 | 74 | this._data = this._data + value; |
43 | 75 | } |
44 | | - |
45 | | - /** |
46 | | - * Returns the TimeSeries with one or more Point. |
47 | | - * |
48 | | - * @param timestamp The time at which the counter is recorded. |
49 | | - * @returns The TimeSeries. |
50 | | - */ |
51 | | - getTimeSeries(timestamp: types.HrTime): TimeSeries { |
52 | | - return { |
53 | | - labelValues: this._labelValues.map(value => ({ value })), |
54 | | - points: [{ value: this._data, timestamp }], |
55 | | - }; |
56 | | - } |
57 | 76 | } |
58 | 77 |
|
59 | 78 | /** |
60 | 79 | * GaugeHandle allows the SDK to observe/record a single metric event. The |
61 | 80 | * value of single handle in the `Gauge` associated with specified label values. |
62 | 81 | */ |
63 | | -export class GaugeHandle implements types.GaugeHandle { |
64 | | - private _data = 0; |
65 | | - |
| 82 | +export class GaugeHandle extends BaseHandle implements types.GaugeHandle { |
66 | 83 | constructor( |
67 | 84 | private readonly _disabled: boolean, |
68 | 85 | private readonly _monotonic: boolean, |
| 86 | + private readonly _valueType: types.ValueType, |
69 | 87 | private readonly _labelValues: string[], |
70 | 88 | private readonly _logger: types.Logger |
71 | | - ) {} |
| 89 | + ) { |
| 90 | + super(_labelValues); |
| 91 | + } |
72 | 92 |
|
73 | 93 | set(value: number): void { |
74 | 94 | if (this._disabled) return; |
75 | 95 |
|
76 | 96 | if (this._monotonic && value < this._data) { |
77 | | - this._logger.error('Monotonic gauge cannot descend.'); |
| 97 | + this._logger.error( |
| 98 | + `Monotonic gauge cannot descend for ${this._labelValues}` |
| 99 | + ); |
78 | 100 | return; |
79 | 101 | } |
80 | | - this._data = value; |
81 | | - } |
82 | 102 |
|
83 | | - /** |
84 | | - * Returns the TimeSeries with one or more Point. |
85 | | - * |
86 | | - * @param timestamp The time at which the gauge is recorded. |
87 | | - * @returns The TimeSeries. |
88 | | - */ |
89 | | - getTimeSeries(timestamp: types.HrTime): TimeSeries { |
90 | | - return { |
91 | | - labelValues: this._labelValues.map(value => ({ value })), |
92 | | - points: [{ value: this._data, timestamp }], |
93 | | - }; |
| 103 | + if (this._valueType === types.ValueType.INT && !Number.isInteger(value)) { |
| 104 | + this._logger.warn( |
| 105 | + `INT gauge cannot accept a floating-point value for ${this._labelValues}, ignoring the fractional digits.` |
| 106 | + ); |
| 107 | + value = Math.trunc(value); |
| 108 | + } |
| 109 | + this._data = value; |
94 | 110 | } |
95 | 111 | } |
96 | 112 |
|
97 | 113 | /** |
98 | 114 | * MeasureHandle is an implementation of the {@link MeasureHandle} interface. |
99 | 115 | */ |
100 | | -export class MeasureHandle implements types.MeasureHandle { |
| 116 | +export class MeasureHandle extends BaseHandle implements types.MeasureHandle { |
101 | 117 | record( |
102 | 118 | value: number, |
103 | 119 | distContext?: types.DistributedContext, |
|
0 commit comments