11package metrics
22
33import (
4- "fmt "
4+ "runtime "
55 "sync"
66 "time"
77
88 dogstatsd "github.com/DataDog/datadog-go/v5/statsd"
9- statsd "github.com/alexcesaro/statsd"
9+ "github.com/alexcesaro/statsd"
10+ "github.com/mixpanel/mixpanel-go"
1011 "github.com/pkg/errors"
1112 "go.opentelemetry.io/otel"
1213 "go.opentelemetry.io/otel/trace"
1314 ddotel "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentelemetry"
15+ "gopkg.in/DataDog/dd-trace-go.v1/profiler"
16+
17+ log "github.com/InjectiveLabs/suplog"
1418)
1519
1620const (
2529 clientMux = new (sync.RWMutex )
2630 config * StatterConfig
2731
28- traceProvider * ddotel.TracerProvider
29- tracer trace.Tracer
32+ traceProvider * ddotel.TracerProvider
33+ tracer trace.Tracer
34+ mixPanelClient * mixpanel.ApiClient
3035)
3136
3237type StatterConfig struct {
@@ -35,10 +40,15 @@ type StatterConfig struct {
3540 Agent string // telegraf/datadog
3641 EnvName string // dev/test/staging/prod
3742 HostName string // hostname
43+ Version string // version
3844 StuckFunctionTimeout time.Duration // stuck time
45+ MockingThreshold time.Duration // mocking threshold
3946 MockingEnabled bool // whether to enable mock statter, which only produce logs
4047 Disabled bool // whether to disable metrics completely
4148 TracingEnabled bool // whether DataDog tracing should be enabled (via OpenTelemetry)
49+ ProfilingEnabled bool // whether Datadog profiling should be enabled
50+ MixPanelEnabled bool // whether MixPanel should be enabled
51+ MixPanelProjectToken string // MixPanel project token
4252}
4353
4454func (m * StatterConfig ) BaseTags () []string {
@@ -82,35 +92,15 @@ func Close() {
8292 if client == nil {
8393 return
8494 }
85- if traceProvider != nil {
86- traceProvider .Shutdown ()
87- }
8895 client .Close ()
8996}
9097
91- func Disable () {
92- config = checkConfig (nil )
93- clientMux .Lock ()
94- client = newMockStatter (true )
95- clientMux .Unlock ()
96- tracer = nil
97- }
98-
99- func InitWithConfig (cfg * StatterConfig ) error {
100- return Init (cfg .Addr , cfg .Prefix , cfg )
101- }
102-
10398func Init (addr string , prefix string , cfg * StatterConfig ) error {
104- if cfg .Disabled {
105- Disable ()
106- return nil
107- }
108-
10999 config = checkConfig (cfg )
110100 if config .MockingEnabled {
111101 // init a mock statter instead of real statsd client
112102 clientMux .Lock ()
113- client = newMockStatter (false )
103+ client = newMockStatter (cfg )
114104 clientMux .Unlock ()
115105 return nil
116106 }
@@ -150,12 +140,51 @@ func Init(addr string, prefix string, cfg *StatterConfig) error {
150140 clientMux .Unlock ()
151141
152142 // OpenTelemetry tracing via DataDog provider
153- if cfg .TracingEnabled {
143+ if cfg .Agent == DatadogAgent && cfg . TracingEnabled {
154144 traceProvider = ddotel .NewTracerProvider ()
155145 otel .SetTracerProvider (traceProvider )
156146 tracer = otel .Tracer ("" )
157147 }
158148
149+ if cfg .Agent == DatadogAgent && cfg .ProfilingEnabled {
150+ err = setupProfiler (cfg )
151+ if err != nil {
152+ return err
153+ }
154+ }
155+
156+ if cfg .MixPanelEnabled {
157+ StartMixPanel (cfg .MixPanelProjectToken )
158+ }
159+
160+ return nil
161+ }
162+
163+ func StartMixPanel (projectToken string ) {
164+ clientMux .Lock ()
165+ defer clientMux .Unlock ()
166+ mixPanelClient = mixpanel .NewApiClient (projectToken )
167+ }
168+
169+ func setupProfiler (cfg * StatterConfig ) error {
170+ runtime .SetMutexProfileFraction (5 )
171+ runtime .SetBlockProfileRate (5 )
172+
173+ err := profiler .Start (
174+ profiler .WithService (cfg .Prefix ),
175+ profiler .WithEnv (cfg .EnvName ),
176+ profiler .WithHostname (cfg .HostName ),
177+ profiler .WithVersion (cfg .Version ),
178+ profiler .WithProfileTypes (
179+ profiler .CPUProfile ,
180+ profiler .HeapProfile ,
181+ profiler .BlockProfile ,
182+ profiler .MutexProfile ,
183+ ),
184+ )
185+ if err != nil {
186+ return errors .Wrap (err , "profiler start failed" )
187+ }
159188 return nil
160189}
161190
@@ -173,44 +202,86 @@ func checkConfig(cfg *StatterConfig) *StatterConfig {
173202}
174203
175204func errHandler (err error ) {
176- fmt . Printf ( "statsd error, err: %v \n " , err )
205+ log . WithError ( err ). Errorln ( "statsd error" )
177206}
178207
179- func newMockStatter (noop bool ) Statter {
180- return & mockStatter {}
208+ func newMockStatter (cfg * StatterConfig ) Statter {
209+ return & mockStatter {
210+ l : log .WithFields (log.Fields {
211+ "module" : "mock_statter" ,
212+ }),
213+ threshold : cfg .MockingThreshold ,
214+ }
181215}
182216
183217type mockStatter struct {
218+ l log.Logger
219+ threshold time.Duration
184220}
185221
186222func (s * mockStatter ) Count (name string , value int64 , tags []string , rate float64 ) error {
223+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Count %s: %v" , name , value )
187224 return nil
188225}
189226
190227func (s * mockStatter ) Incr (name string , tags []string , rate float64 ) error {
228+ if s .threshold > 0 {
229+ return nil
230+ }
231+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Incr %s" , name )
191232 return nil
192233}
193234
194235func (s * mockStatter ) Decr (name string , tags []string , rate float64 ) error {
236+ if s .threshold > 0 {
237+ return nil
238+ }
239+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Decr %s" , name )
195240 return nil
196241}
197242
198243func (s * mockStatter ) Gauge (name string , value float64 , tags []string , rate float64 ) error {
244+ if s .threshold > 0 {
245+ return nil
246+ }
247+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Gauge %s: %v" , name , value )
199248 return nil
200249}
201250
202251func (s * mockStatter ) Timing (name string , value time.Duration , tags []string , rate float64 ) error {
252+ if value > s .threshold {
253+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Timing %s: %v" , name , value )
254+ }
203255 return nil
204256}
205257
206258func (s * mockStatter ) Histogram (name string , value float64 , tags []string , rate float64 ) error {
259+ if value > float64 (s .threshold .Milliseconds ()) {
260+ s .l .WithFields (s .withTagFields (tags )).Debugf ("Histogram %s: %v" , name , value )
261+ }
207262 return nil
208263}
209264
210265func (s * mockStatter ) Unique (bucket string , value string ) error {
266+ if s .threshold > 0 {
267+ return nil
268+ }
269+ s .l .Debugf ("Unique %s: %v" , bucket , value )
211270 return nil
212271}
213272
214273func (s * mockStatter ) Close () error {
274+ s .l .Debugf ("closed at %s" , time .Now ())
215275 return nil
216276}
277+
278+ func (s * mockStatter ) withTagFields (tags []string ) log.Fields {
279+ fields := make (log.Fields )
280+ for i := 0 ; i < len (tags ); i += 2 {
281+ if i + 1 >= len (tags ) { // protect against odd number of tags
282+ break
283+ }
284+ fields [tags [i ]] = tags [i + 1 ]
285+ }
286+ return fields
287+ }
0 commit comments