github.com/Jeffail/benthos/v3@v3.65.0/lib/metrics/statsd_legacy.go (about) 1 package metrics 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/Jeffail/benthos/v3/lib/log" 8 "github.com/quipo/statsd" 9 ) 10 11 //------------------------------------------------------------------------------ 12 13 type wrappedLogger struct { 14 m log.Modular 15 } 16 17 func (w *wrappedLogger) Println(v ...interface{}) { 18 w.m.Warnf(fmt.Sprintln(v...)) 19 } 20 21 //------------------------------------------------------------------------------ 22 23 // StatsdLegacyStat is a representation of a single metric stat. Interactions with 24 // this stat are thread safe. 25 type StatsdLegacyStat struct { 26 path string 27 s statsd.Statsd 28 } 29 30 // Incr increments a metric by an amount. 31 func (s *StatsdLegacyStat) Incr(count int64) error { 32 s.s.Incr(s.path, count) 33 return nil 34 } 35 36 // Decr decrements a metric by an amount. 37 func (s *StatsdLegacyStat) Decr(count int64) error { 38 s.s.Decr(s.path, count) 39 return nil 40 } 41 42 // Timing sets a timing metric. 43 func (s *StatsdLegacyStat) Timing(delta int64) error { 44 s.s.Timing(s.path, delta) 45 return nil 46 } 47 48 // Set sets a gauge metric. 49 func (s *StatsdLegacyStat) Set(value int64) error { 50 s.s.Gauge(s.path, value) 51 return nil 52 } 53 54 //------------------------------------------------------------------------------ 55 56 // StatsdLegacy is a stats object with capability to hold internal stats as a JSON 57 // endpoint. 58 type StatsdLegacy struct { 59 config Config 60 s statsd.Statsd 61 log log.Modular 62 pathMapping *pathMapping 63 } 64 65 // NewStatsdLegacy creates and returns a new StatsdLegacy object. 66 func NewStatsdLegacy(config Config, opts ...func(Type)) (Type, error) { 67 flushPeriod, err := time.ParseDuration(config.Statsd.FlushPeriod) 68 if err != nil { 69 return nil, fmt.Errorf("failed to parse flush period: %s", err) 70 } 71 s := &StatsdLegacy{ 72 config: config, 73 log: log.Noop(), 74 } 75 for _, opt := range opts { 76 opt(s) 77 } 78 79 if s.pathMapping, err = newPathMapping(config.Statsd.PathMapping, s.log); err != nil { 80 return nil, fmt.Errorf("failed to init path mapping: %v", err) 81 } 82 83 if config.Statsd.Network == "tcp" { 84 s.log.Warnf( 85 "Network set to 'tcp', falling back to legacy statsd client. The " + 86 "network field is due to be removed in the next major release, " + 87 " if you are relying on this field please raise an issue at: " + 88 "https://github.com/Jeffail/benthos/issues\n", 89 ) 90 } else { 91 s.log.Warnf( 92 "Falling back to legacy statsd client. To use the new client set " + 93 "the 'tag_format' field to 'none', 'datadog' or 'influxdb'. The " + 94 "network field is due to be removed in the next major release, " + 95 "if you are relying on this field please raise an issue at: " + 96 "https://github.com/Jeffail/benthos/issues\n", 97 ) 98 } 99 100 if config.Statsd.TagFormat != TagFormatNone && config.Statsd.TagFormat != TagFormatLegacy { 101 return nil, fmt.Errorf("tag format '%v' is not supported when using 'tcp' network traffic", config.Statsd.TagFormat) 102 } 103 104 prefix := config.Statsd.Prefix 105 if len(prefix) > 0 && prefix[len(prefix)-1] != '.' { 106 prefix += "." 107 } 108 109 statsdclient := statsd.NewStatsdBuffer( 110 flushPeriod, 111 statsd.NewStatsdClient(config.Statsd.Address, prefix), 112 ) 113 statsdclient.Logger = &wrappedLogger{m: s.log} 114 if config.Statsd.Network == "udp" { 115 if err := statsdclient.CreateSocket(); err != nil { 116 return nil, err 117 } 118 } else { 119 if err := statsdclient.CreateTCPSocket(); err != nil { 120 return nil, err 121 } 122 } 123 s.s = statsdclient 124 return s, nil 125 } 126 127 //------------------------------------------------------------------------------ 128 129 // GetCounter returns a stat counter object for a path. 130 func (h *StatsdLegacy) GetCounter(path string) StatCounter { 131 if path = h.pathMapping.mapPathNoTags(path); path == "" { 132 return DudStat{} 133 } 134 return &StatsdLegacyStat{ 135 path: path, 136 s: h.s, 137 } 138 } 139 140 // GetCounterVec returns a stat counter object for a path with the labels 141 // discarded. 142 func (h *StatsdLegacy) GetCounterVec(path string, n []string) StatCounterVec { 143 path = h.pathMapping.mapPathNoTags(path) 144 return fakeCounterVec(func([]string) StatCounter { 145 if path == "" { 146 return DudStat{} 147 } 148 return &StatsdLegacyStat{ 149 path: path, 150 s: h.s, 151 } 152 }) 153 } 154 155 // GetTimer returns a stat timer object for a path. 156 func (h *StatsdLegacy) GetTimer(path string) StatTimer { 157 if path = h.pathMapping.mapPathNoTags(path); path == "" { 158 return DudStat{} 159 } 160 return &StatsdLegacyStat{ 161 path: path, 162 s: h.s, 163 } 164 } 165 166 // GetTimerVec returns a stat timer object for a path with the labels 167 // discarded. 168 func (h *StatsdLegacy) GetTimerVec(path string, n []string) StatTimerVec { 169 path = h.pathMapping.mapPathNoTags(path) 170 return fakeTimerVec(func([]string) StatTimer { 171 if path == "" { 172 return DudStat{} 173 } 174 return &StatsdLegacyStat{ 175 path: path, 176 s: h.s, 177 } 178 }) 179 } 180 181 // GetGauge returns a stat gauge object for a path. 182 func (h *StatsdLegacy) GetGauge(path string) StatGauge { 183 if path = h.pathMapping.mapPathNoTags(path); path == "" { 184 return DudStat{} 185 } 186 return &StatsdLegacyStat{ 187 path: path, 188 s: h.s, 189 } 190 } 191 192 // GetGaugeVec returns a stat timer object for a path with the labels 193 // discarded. 194 func (h *StatsdLegacy) GetGaugeVec(path string, n []string) StatGaugeVec { 195 path = h.pathMapping.mapPathNoTags(path) 196 return fakeGaugeVec(func([]string) StatGauge { 197 if path == "" { 198 return DudStat{} 199 } 200 return &StatsdLegacyStat{ 201 path: path, 202 s: h.s, 203 } 204 }) 205 } 206 207 // SetLogger sets the logger used to print connection errors. 208 func (h *StatsdLegacy) SetLogger(log log.Modular) { 209 h.log = log 210 } 211 212 // Close stops the StatsdLegacy object from aggregating metrics and cleans up 213 // resources. 214 func (h *StatsdLegacy) Close() error { 215 h.s.Close() 216 return nil 217 } 218 219 //------------------------------------------------------------------------------