8
8
import static io .opentelemetry .sdk .testing .assertj .OpenTelemetryAssertions .assertThat ;
9
9
10
10
import io .github .netmikey .logunit .api .LogCapturer ;
11
+ import io .opentelemetry .extension .incubator .metrics .ExtendedDoubleHistogramBuilder ;
11
12
import io .opentelemetry .internal .testing .slf4j .SuppressLogger ;
12
13
import io .opentelemetry .sdk .common .InstrumentationScopeInfo ;
13
14
import io .opentelemetry .sdk .metrics .internal .state .MetricStorageRegistry ;
14
15
import io .opentelemetry .sdk .metrics .internal .view .ViewRegistry ;
15
16
import io .opentelemetry .sdk .testing .exporter .InMemoryMetricReader ;
17
+ import java .util .Arrays ;
16
18
import java .util .concurrent .atomic .AtomicLong ;
17
19
import org .junit .jupiter .api .BeforeEach ;
18
20
import org .junit .jupiter .api .Test ;
@@ -106,7 +108,7 @@ void sameMeterSameInstrumentNoViews() {
106
108
}
107
109
108
110
@ Test
109
- void sameMeterDifferentInstrumentNoViews () {
111
+ void sameMeterDifferentInstrumentNameNoViews () {
110
112
SdkMeterProvider meterProvider = builder .build ();
111
113
112
114
meterProvider .get ("meter1" ).counterBuilder ("counter1" ).build ().add (10 );
@@ -130,6 +132,139 @@ void sameMeterDifferentInstrumentNoViews() {
130
132
assertThat (metricStorageRegistryLogs .getEvents ()).hasSize (0 );
131
133
}
132
134
135
+ @ Test
136
+ void sameMeterDifferentInstrumentNameCaseNoViews () {
137
+ SdkMeterProvider meterProvider = builder .build ();
138
+
139
+ meterProvider .get ("meter1" ).counterBuilder ("Counter1" ).build ().add (10 );
140
+ meterProvider .get ("meter1" ).counterBuilder ("counter1" ).build ().add (10 );
141
+
142
+ assertThat (reader .collectAllMetrics ())
143
+ .satisfiesExactlyInAnyOrder (
144
+ metricData ->
145
+ assertThat (metricData )
146
+ .hasInstrumentationScope (forMeter ("meter1" ))
147
+ .hasName ("Counter1" )
148
+ .hasLongSumSatisfying (
149
+ sum -> sum .hasPointsSatisfying (point -> point .hasValue (20 ))));
150
+
151
+ assertThat (metricStorageRegistryLogs .getEvents ()).hasSize (0 );
152
+ }
153
+
154
+ @ Test
155
+ @ SuppressLogger (MetricStorageRegistry .class )
156
+ void sameMeterSameInstrumentNameDifferentIdentifyingFieldsNoViews () {
157
+ SdkMeterProvider meterProvider = builder .build ();
158
+
159
+ meterProvider .get ("meter1" ).counterBuilder ("counter1" ).build ().add (10 );
160
+ // Same name, different unit
161
+ meterProvider .get ("meter1" ).counterBuilder ("counter1" ).setUnit ("unit1" ).build ().add (10 );
162
+ // Same name, different description
163
+ meterProvider
164
+ .get ("meter1" )
165
+ .counterBuilder ("counter1" )
166
+ .setDescription ("description1" )
167
+ .build ()
168
+ .add (10 );
169
+ // Same name, different value type
170
+ meterProvider .get ("meter1" ).counterBuilder ("counter1" ).ofDoubles ().build ().add (10 );
171
+ // Same name, different instrument type
172
+ meterProvider .get ("meter1" ).upDownCounterBuilder ("counter1" ).build ().add (10 );
173
+
174
+ // When name is the same, but some identifying field is different (unit, description, value
175
+ // type, instrument type) we produce different metric streams are produced and log a warning
176
+ assertThat (reader .collectAllMetrics ())
177
+ .satisfiesExactlyInAnyOrder (
178
+ metricData ->
179
+ assertThat (metricData )
180
+ .hasInstrumentationScope (forMeter ("meter1" ))
181
+ .hasName ("counter1" )
182
+ .hasLongSumSatisfying (
183
+ sum -> sum .isMonotonic ().hasPointsSatisfying (point -> point .hasValue (10 ))),
184
+ metricData ->
185
+ assertThat (metricData )
186
+ .hasInstrumentationScope (forMeter ("meter1" ))
187
+ .hasName ("counter1" )
188
+ .hasUnit ("unit1" )
189
+ .hasLongSumSatisfying (
190
+ sum -> sum .isMonotonic ().hasPointsSatisfying (point -> point .hasValue (10 ))),
191
+ metricData ->
192
+ assertThat (metricData )
193
+ .hasInstrumentationScope (forMeter ("meter1" ))
194
+ .hasName ("counter1" )
195
+ .hasDescription ("description1" )
196
+ .hasLongSumSatisfying (
197
+ sum -> sum .isMonotonic ().hasPointsSatisfying (point -> point .hasValue (10 ))),
198
+ metricData ->
199
+ assertThat (metricData )
200
+ .hasInstrumentationScope (forMeter ("meter1" ))
201
+ .hasName ("counter1" )
202
+ .hasDoubleSumSatisfying (
203
+ sum -> sum .isMonotonic ().hasPointsSatisfying (point -> point .hasValue (10 ))),
204
+ metricData ->
205
+ assertThat (metricData )
206
+ .hasInstrumentationScope (forMeter ("meter1" ))
207
+ .hasName ("counter1" )
208
+ .hasLongSumSatisfying (
209
+ sum ->
210
+ sum .isNotMonotonic ().hasPointsSatisfying (point -> point .hasValue (10 ))));
211
+
212
+ assertThat (metricStorageRegistryLogs .getEvents ())
213
+ .allSatisfy (
214
+ logEvent ->
215
+ assertThat (logEvent .getMessage ()).contains ("Found duplicate metric definition" ))
216
+ .hasSize (4 );
217
+ }
218
+
219
+ @ Test
220
+ void sameMeterSameInstrumentNameDifferentNonIdentifyingFieldsNoViews () {
221
+ SdkMeterProvider meterProvider = builder .build ();
222
+
223
+ // Register histogram1, with and without advice. First registration without advice wins.
224
+ meterProvider .get ("meter1" ).histogramBuilder ("histogram1" ).build ().record (8 );
225
+ ((ExtendedDoubleHistogramBuilder ) meterProvider .get ("meter1" ).histogramBuilder ("histogram1" ))
226
+ .setAdvice (advice -> advice .setExplicitBucketBoundaries (Arrays .asList (10.0 , 20.0 , 30.0 )))
227
+ .build ()
228
+ .record (8 );
229
+
230
+ // Register histogram2, with and without advice. First registration with advice wins.
231
+ ((ExtendedDoubleHistogramBuilder ) meterProvider .get ("meter1" ).histogramBuilder ("histogram2" ))
232
+ .setAdvice (advice -> advice .setExplicitBucketBoundaries (Arrays .asList (10.0 , 20.0 , 30.0 )))
233
+ .build ()
234
+ .record (8 );
235
+ meterProvider .get ("meter1" ).histogramBuilder ("histogram2" ).build ().record (8 );
236
+
237
+ assertThat (reader .collectAllMetrics ())
238
+ .satisfiesExactlyInAnyOrder (
239
+ metricData ->
240
+ assertThat (metricData )
241
+ .hasInstrumentationScope (forMeter ("meter1" ))
242
+ .hasName ("histogram1" )
243
+ .hasHistogramSatisfying (
244
+ histogram ->
245
+ histogram .hasPointsSatisfying (
246
+ point ->
247
+ point
248
+ .hasBucketCounts (
249
+ 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
250
+ .hasBucketBoundaries (
251
+ 0d , 5d , 10d , 25d , 50d , 75d , 100d , 250d , 500d , 750d ,
252
+ 1_000d , 2_500d , 5_000d , 7_500d , 10_000d ))),
253
+ metricData ->
254
+ assertThat (metricData )
255
+ .hasInstrumentationScope (forMeter ("meter1" ))
256
+ .hasName ("histogram2" )
257
+ .hasHistogramSatisfying (
258
+ histogram ->
259
+ histogram .hasPointsSatisfying (
260
+ point ->
261
+ point
262
+ .hasBucketCounts (2 , 0 , 0 , 0 )
263
+ .hasBucketBoundaries (10.0 , 20.0 , 30.0 ))));
264
+
265
+ assertThat (metricStorageRegistryLogs .getEvents ()).hasSize (0 );
266
+ }
267
+
133
268
@ Test
134
269
void differentMeterSameInstrumentNoViews () {
135
270
// Meters are the same if their name, version, and scope are all equals
0 commit comments