@effect/opentelemetry 0.31.19 → 0.31.21

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.
@@ -4,6 +4,7 @@ import type * as Resources from "@opentelemetry/resources"
4
4
  import type {
5
5
  CollectionResult,
6
6
  DataPoint,
7
+ Histogram,
7
8
  MetricCollectOptions,
8
9
  MetricData,
9
10
  MetricDescriptor,
@@ -26,13 +27,27 @@ const sdkName = "@effect/opentelemetry/Metrics"
26
27
 
27
28
  /** @internal */
28
29
  export class MetricProducerImpl implements MetricProducer {
29
- constructor(readonly resource: Resources.Resource) {
30
+ constructor(readonly resource: Resources.Resource) {}
31
+
32
+ startTimes = new Map<string, HrTime>()
33
+
34
+ startTimeFor(name: string, hrTime: HrTime) {
35
+ if (this.startTimes.has(name)) {
36
+ return this.startTimes.get(name)!
37
+ }
38
+ this.startTimes.set(name, hrTime)
39
+ return hrTime
30
40
  }
31
41
 
32
42
  collect(_options?: MetricCollectOptions): Promise<CollectionResult> {
33
43
  const snapshot = Metric.unsafeSnapshot()
34
44
  const hrTimeNow = currentHrTime()
35
45
  const metricData: Array<MetricData> = []
46
+ const metricDataByName = new Map<string, MetricData>()
47
+ const addMetricData = (data: MetricData) => {
48
+ metricData.push(data)
49
+ metricDataByName.set(data.descriptor.name, data)
50
+ }
36
51
 
37
52
  for (let i = 0, len = snapshot.length; i < len; i++) {
38
53
  const { metricKey, metricState } = snapshot[i]
@@ -41,32 +56,43 @@ export class MetricProducerImpl implements MetricProducer {
41
56
  return acc
42
57
  })
43
58
  const descriptor = descriptorFromKey(metricKey, attributes)
59
+ const startTime = this.startTimeFor(descriptor.name, hrTimeNow)
44
60
 
45
61
  if (MetricState.isCounterState(metricState)) {
46
- metricData.push({
47
- dataPointType: DataPointType.SUM,
48
- descriptor,
49
- isMonotonic: descriptor.type === InstrumentType.COUNTER,
50
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
51
- dataPoints: [{
52
- startTime: hrTimeNow,
53
- endTime: hrTimeNow,
54
- attributes,
55
- value: Number(metricState.count)
56
- }]
57
- })
62
+ const dataPoint: DataPoint<number> = {
63
+ startTime,
64
+ endTime: hrTimeNow,
65
+ attributes,
66
+ value: Number(metricState.count)
67
+ }
68
+ if (metricDataByName.has(descriptor.name)) {
69
+ metricDataByName.get(descriptor.name)!.dataPoints.push(dataPoint as any)
70
+ } else {
71
+ addMetricData({
72
+ dataPointType: DataPointType.SUM,
73
+ descriptor,
74
+ isMonotonic: descriptor.type === InstrumentType.COUNTER,
75
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
76
+ dataPoints: [dataPoint]
77
+ })
78
+ }
58
79
  } else if (MetricState.isGaugeState(metricState)) {
59
- metricData.push({
60
- dataPointType: DataPointType.GAUGE,
61
- descriptor,
62
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
63
- dataPoints: [{
64
- startTime: hrTimeNow,
65
- endTime: hrTimeNow,
66
- attributes,
67
- value: Number(metricState.value)
68
- }]
69
- })
80
+ const dataPoint: DataPoint<number> = {
81
+ startTime,
82
+ endTime: hrTimeNow,
83
+ attributes,
84
+ value: Number(metricState.value)
85
+ }
86
+ if (metricDataByName.has(descriptor.name)) {
87
+ metricDataByName.get(descriptor.name)!.dataPoints.push(dataPoint as any)
88
+ } else {
89
+ addMetricData({
90
+ dataPointType: DataPointType.GAUGE,
91
+ descriptor,
92
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
93
+ dataPoints: [dataPoint]
94
+ })
95
+ }
70
96
  } else if (MetricState.isHistogramState(metricState)) {
71
97
  const size = metricState.buckets.length
72
98
  const buckets = {
@@ -83,29 +109,34 @@ export class MetricProducerImpl implements MetricProducer {
83
109
  prev = value
84
110
  i++
85
111
  }
112
+ const dataPoint: DataPoint<Histogram> = {
113
+ startTime,
114
+ endTime: hrTimeNow,
115
+ attributes,
116
+ value: {
117
+ buckets,
118
+ count: metricState.count,
119
+ min: metricState.min,
120
+ max: metricState.max,
121
+ sum: metricState.sum
122
+ }
123
+ }
86
124
 
87
- metricData.push({
88
- dataPointType: DataPointType.HISTOGRAM,
89
- descriptor,
90
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
91
- dataPoints: [{
92
- startTime: hrTimeNow,
93
- endTime: hrTimeNow,
94
- attributes,
95
- value: {
96
- buckets,
97
- count: metricState.count,
98
- min: metricState.min,
99
- max: metricState.max,
100
- sum: metricState.sum
101
- }
102
- }]
103
- })
125
+ if (metricDataByName.has(descriptor.name)) {
126
+ metricDataByName.get(descriptor.name)!.dataPoints.push(dataPoint as any)
127
+ } else {
128
+ addMetricData({
129
+ dataPointType: DataPointType.HISTOGRAM,
130
+ descriptor,
131
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
132
+ dataPoints: [dataPoint]
133
+ })
134
+ }
104
135
  } else if (MetricState.isFrequencyState(metricState)) {
105
136
  const dataPoints: Array<DataPoint<number>> = []
106
137
  for (const [freqKey, value] of metricState.occurrences) {
107
138
  dataPoints.push({
108
- startTime: hrTimeNow,
139
+ startTime,
109
140
  endTime: hrTimeNow,
110
141
  attributes: {
111
142
  ...attributes,
@@ -114,76 +145,90 @@ export class MetricProducerImpl implements MetricProducer {
114
145
  value
115
146
  })
116
147
  }
117
- metricData.push({
118
- dataPointType: DataPointType.SUM,
119
- descriptor: descriptorFromKey(metricKey, attributes),
120
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
121
- isMonotonic: true,
122
- dataPoints
123
- })
148
+ if (metricDataByName.has(descriptor.name)) {
149
+ // eslint-disable-next-line no-restricted-syntax
150
+ metricDataByName.get(descriptor.name)!.dataPoints.push(...dataPoints as any)
151
+ } else {
152
+ addMetricData({
153
+ dataPointType: DataPointType.SUM,
154
+ descriptor: descriptorFromKey(metricKey, attributes),
155
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
156
+ isMonotonic: true,
157
+ dataPoints
158
+ })
159
+ }
124
160
  } else if (MetricState.isSummaryState(metricState)) {
125
161
  const dataPoints: Array<DataPoint<number>> = [{
126
- startTime: hrTimeNow,
162
+ startTime,
127
163
  endTime: hrTimeNow,
128
164
  attributes: { ...attributes, quantile: "min" },
129
165
  value: metricState.min
130
166
  }]
131
167
  for (const [quantile, value] of metricState.quantiles) {
132
168
  dataPoints.push({
133
- startTime: hrTimeNow,
169
+ startTime,
134
170
  endTime: hrTimeNow,
135
171
  attributes: { ...attributes, quantile: quantile.toString() },
136
172
  value: value._tag === "Some" ? value.value : 0
137
173
  })
138
174
  }
139
175
  dataPoints.push({
140
- startTime: hrTimeNow,
176
+ startTime,
141
177
  endTime: hrTimeNow,
142
178
  attributes: { ...attributes, quantile: "max" },
143
179
  value: metricState.max
144
180
  })
181
+ const countDataPoint: DataPoint<number> = {
182
+ startTime,
183
+ endTime: hrTimeNow,
184
+ attributes,
185
+ value: metricState.count
186
+ }
187
+ const sumDataPoint: DataPoint<number> = {
188
+ startTime,
189
+ endTime: hrTimeNow,
190
+ attributes,
191
+ value: metricState.sum
192
+ }
145
193
 
146
- metricData.push({
147
- dataPointType: DataPointType.SUM,
148
- descriptor: descriptorFromKey(metricKey, attributes, "quantiles"),
149
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
150
- isMonotonic: false,
151
- dataPoints
152
- })
153
- metricData.push({
154
- dataPointType: DataPointType.SUM,
155
- descriptor: {
156
- ...descriptorMeta(metricKey, "count"),
157
- unit: "1",
158
- type: InstrumentType.COUNTER,
159
- valueType: ValueType.INT
160
- },
161
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
162
- isMonotonic: true,
163
- dataPoints: [{
164
- startTime: hrTimeNow,
165
- endTime: hrTimeNow,
166
- attributes,
167
- value: metricState.count
168
- }]
169
- })
170
- metricData.push({
171
- dataPointType: DataPointType.SUM,
172
- descriptor: {
173
- ...descriptorMeta(metricKey, "sum"),
174
- unit: "1",
175
- type: InstrumentType.COUNTER,
176
- valueType: ValueType.DOUBLE
177
- },
178
- aggregationTemporality: AggregationTemporality.CUMULATIVE,
179
- isMonotonic: true,
180
- dataPoints: [{
181
- startTime: hrTimeNow,
182
- endTime: hrTimeNow,
183
- attributes,
184
- value: metricState.sum
185
- }]
186
- })
194
+ if (metricDataByName.has(`${descriptor.name}_quantiles`)) {
195
+ // eslint-disable-next-line no-restricted-syntax
196
+ metricDataByName.get(`${descriptor.name}_quantiles`)!.dataPoints.push(...dataPoints as any)
197
+ metricDataByName.get(`${descriptor.name}_count`)!.dataPoints.push(countDataPoint as any)
198
+ metricDataByName.get(`${descriptor.name}_sum`)!.dataPoints.push(sumDataPoint as any)
199
+ } else {
200
+ addMetricData({
201
+ dataPointType: DataPointType.SUM,
202
+ descriptor: descriptorFromKey(metricKey, attributes, "quantiles"),
203
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
204
+ isMonotonic: false,
205
+ dataPoints
206
+ })
207
+ addMetricData({
208
+ dataPointType: DataPointType.SUM,
209
+ descriptor: {
210
+ ...descriptorMeta(metricKey, "count"),
211
+ unit: "1",
212
+ type: InstrumentType.COUNTER,
213
+ valueType: ValueType.INT
214
+ },
215
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
216
+ isMonotonic: true,
217
+ dataPoints: [countDataPoint]
218
+ })
219
+ addMetricData({
220
+ dataPointType: DataPointType.SUM,
221
+ descriptor: {
222
+ ...descriptorMeta(metricKey, "sum"),
223
+ unit: "1",
224
+ type: InstrumentType.COUNTER,
225
+ valueType: ValueType.DOUBLE
226
+ },
227
+ aggregationTemporality: AggregationTemporality.CUMULATIVE,
228
+ isMonotonic: true,
229
+ dataPoints: [sumDataPoint]
230
+ })
231
+ }
187
232
  }
188
233
  }
189
234