package metrics import ( "fmt" "net/url" ) // The MetricSink interface is used to transmit metrics information // to an external system type MetricSink interface { // A Gauge should retain the last value it is set to SetGauge(key []string, val float32) // Should emit a Key/Value pair for each call EmitKey(key []string, val float32) // Counters should accumulate values IncrCounter(key []string, val float32) // Samples are for timing information, where quantiles are used AddSample(key []string, val float32) } // BlackholeSink is used to just blackhole messages type BlackholeSink struct{} func (*BlackholeSink) SetGauge(key []string, val float32) {} func (*BlackholeSink) EmitKey(key []string, val float32) {} func (*BlackholeSink) IncrCounter(key []string, val float32) {} func (*BlackholeSink) AddSample(key []string, val float32) {} // FanoutSink is used to sink to fanout values to multiple sinks type FanoutSink []MetricSink func (fh FanoutSink) SetGauge(key []string, val float32) { for _, s := range fh { s.SetGauge(key, val) } } func (fh FanoutSink) EmitKey(key []string, val float32) { for _, s := range fh { s.EmitKey(key, val) } } func (fh FanoutSink) IncrCounter(key []string, val float32) { for _, s := range fh { s.IncrCounter(key, val) } } func (fh FanoutSink) AddSample(key []string, val float32) { for _, s := range fh { s.AddSample(key, val) } } // sinkURLFactoryFunc is an generic interface around the *SinkFromURL() function provided // by each sink type type sinkURLFactoryFunc func(*url.URL) (MetricSink, error) // sinkRegistry supports the generic NewMetricSink function by mapping URL // schemes to metric sink factory functions var sinkRegistry = map[string]sinkURLFactoryFunc{ "statsd": NewStatsdSinkFromURL, "statsite": NewStatsiteSinkFromURL, "inmem": NewInmemSinkFromURL, } // NewMetricSinkFromURL allows a generic URL input to configure any of the // supported sinks. The scheme of the URL identifies the type of the sink, the // and query parameters are used to set options. // // "statsd://" - Initializes a StatsdSink. The host and port are passed through // as the "addr" of the sink // // "statsite://" - Initializes a StatsiteSink. The host and port become the // "addr" of the sink // // "inmem://" - Initializes an InmemSink. The host and port are ignored. The // "interval" and "duration" query parameters must be specified with valid // durations, see NewInmemSink for details. func NewMetricSinkFromURL(urlStr string) (MetricSink, error) { u, err := url.Parse(urlStr) if err != nil { return nil, err } sinkURLFactoryFunc := sinkRegistry[u.Scheme] if sinkURLFactoryFunc == nil { return nil, fmt.Errorf( "cannot create metric sink, unrecognized sink name: %q", u.Scheme) } return sinkURLFactoryFunc(u) }