/
instrumentation.go
50 lines (41 loc) · 1.27 KB
/
instrumentation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package e
import (
"sync"
"go.opencensus.io/tag"
)
const (
maxErrorMutators = 10
maxErrorMutatorLen = 250
)
var (
mu = sync.Mutex{}
errKeys = make(map[string]tag.Mutator, maxErrorMutators)
mutatorErrorOther = tag.Insert(tag.MustNewKey("error"), "other")
)
// MutatorFromError keeps a package global map of error strings, capped at
// maxErrorMutators (10) to prevent unbounded cardinality, and has one of three outcomes:
// 1. returns an already created mutator from the map
// 2. returns an "other" mutator if the map is full
// 3. returns a newly created mutator and stores it in the map
func MutatorFromError(err error) tag.Mutator {
// get the root error text and truncate it if necessary
reportErr := Cause(err).Error()
if len(reportErr) > maxErrorMutatorLen {
reportErr = reportErr[:maxErrorMutatorLen]
}
mu.Lock()
defer mu.Unlock()
// check for an existing mutator for this error text and return if found
mut, ok := errKeys[reportErr]
if ok {
return mut
}
// if we have already reached max cardinality, return "other"
if len(errKeys) > maxErrorMutators {
return mutatorErrorOther
}
// create a new mutator, insert it into the map, then return it
// mut = tag.Insert(nstats.KeyError, reportErr)
errKeys[reportErr] = mut
return mut
}