Skip to content

Commit 55ca35b

Browse files
committed
Better numeric checks.
1 parent 9a13ee3 commit 55ca35b

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

go/internal/otel/custom_sampler.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,18 @@ func getExitingCachedRegex(cs *CustomSampler, pattern string) *regexp.Regexp {
177177
return nil
178178
}
179179

180+
type number interface {
181+
int64 | float64
182+
}
183+
184+
const epsilon = 0.0000000000000001
185+
186+
func compareNumeric[N number](matchValue float64, b N) bool {
187+
// Comparisons for integers larger than 2^53 will be imprecise.
188+
diff := float64(b) - matchValue
189+
return diff < epsilon && diff > -epsilon
190+
}
191+
180192
type matchable interface {
181193
attribute.Value | attribute.Key | string | log.Value
182194
}
@@ -252,17 +264,23 @@ func matchLogValue(v log.Value, matchValue interface{}, cs *CustomSampler) bool
252264
}
253265
return asBool == v.AsBool()
254266
case log.KindInt64:
255-
asInt64, ok := matchValue.(int64)
267+
// Only float64 supported from the config.
268+
asFloat64, ok := matchValue.(float64)
269+
256270
if !ok {
257271
return false
258272
}
259-
return asInt64 == v.AsInt64()
273+
// JSON match value will be a float64.
274+
return compareNumeric(asFloat64, v.AsInt64())
260275
case log.KindFloat64:
276+
// Only float64 supported from the config.
261277
asFloat64, ok := matchValue.(float64)
278+
262279
if !ok {
263280
return false
264281
}
265-
return asFloat64 == v.AsFloat64()
282+
// JSON match value will be a float64.
283+
return compareNumeric(asFloat64, v.AsFloat64())
266284
case log.KindString:
267285
asString, ok := matchValue.(string)
268286
if !ok {
@@ -298,17 +316,23 @@ func matchAttributeValue(v attribute.Value, matchValue interface{}) bool {
298316
}
299317
return asBool == v.AsBool()
300318
case attribute.INT64:
301-
asInt64, ok := matchValue.(int64)
319+
// Only float64 supported from the config.
320+
asFloat64, ok := matchValue.(float64)
321+
302322
if !ok {
303323
return false
304324
}
305-
return asInt64 == v.AsInt64()
325+
// JSON match value will be a float64.
326+
return compareNumeric(asFloat64, v.AsFloat64())
306327
case attribute.FLOAT64:
328+
// Only float64 supported from the config.
307329
asFloat64, ok := matchValue.(float64)
330+
308331
if !ok {
309332
return false
310333
}
311-
return asFloat64 == v.AsFloat64()
334+
// JSON match value will be a float64.
335+
return compareNumeric(asFloat64, v.AsFloat64())
312336
case attribute.STRING:
313337
asString, ok := matchValue.(string)
314338
if !ok {

0 commit comments

Comments
 (0)