Skip to content

Commit

Permalink
metricsbp: add MetricsLabels type (reddit#93)
Browse files Browse the repository at this point in the history
This is a `map[string]string` typedef that allows you to define StatsD labels in a simple way and provides a method to convert itself to the format that the StatsD client expects.
  • Loading branch information
pacejackson authored Feb 21, 2020
1 parent a4e0a1c commit 8a6e99f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 17 deletions.
27 changes: 22 additions & 5 deletions metricsbp/statsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,26 @@ type Statsd struct {
histogramSampleRate float64
}

// MetricsLabels allows you to specify labels as a convenient map and
// provides helpers to convert them into other formats.
type MetricsLabels map[string]string

// AsStatsdLabels returns the labels in the format expected by the
// statsd metrics client, that is a slice of strings.
//
// This method is nil-safe and will just return nil if the receiver is
// nil.
func (l MetricsLabels) AsStatsdLabels() []string {
if l == nil {
return nil
}
labels := make([]string, 0, len(l)*2)
for k, v := range l {
labels = append(labels, k, v)
}
return labels
}

// StatsdConfig is the configs used in NewStatsd.
type StatsdConfig struct {
// Prefix is the common metrics path prefix shared by all metrics managed by
Expand Down Expand Up @@ -111,7 +131,7 @@ type StatsdConfig struct {
// Labels are the labels/tags to be attached to every metrics created
// from this Statsd object. For labels/tags only needed by some metrics,
// use Counter/Gauge/Timing.With() instead.
Labels map[string]string
Labels MetricsLabels
}

// counterSampleRate treats 0 (abs(rate) < epsilon) as 1, and <-epsilon as 0.
Expand All @@ -136,10 +156,7 @@ func NewStatsd(ctx context.Context, cfg StatsdConfig) *Statsd {
if prefix != "" && !strings.HasSuffix(prefix, ".") {
prefix = prefix + "."
}
labels := make([]string, 0, len(cfg.Labels)*2)
for k, v := range cfg.Labels {
labels = append(labels, k, v)
}
labels := cfg.Labels.AsStatsdLabels()
st := &Statsd{
Statsd: influxstatsd.New(prefix, log.KitLogger(cfg.LogLevel), labels...),
ctx: ctx,
Expand Down
37 changes: 37 additions & 0 deletions metricsbp/statsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package metricsbp_test
import (
"bytes"
"context"
"reflect"
"strings"
"testing"

Expand Down Expand Up @@ -247,3 +248,39 @@ func BenchmarkStatsd(b *testing.B) {
},
)
}

func TestMetricsLabels(t *testing.T) {
t.Parallel()

cases := []struct {
name string
labels metricsbp.MetricsLabels
expected []string
}{
{
name: "nil",
labels: nil,
expected: nil,
},
{
name: "one",
labels: metricsbp.MetricsLabels{"key": "value"},
expected: []string{"key", "value"},
},
}

for _, _c := range cases {
c := _c
t.Run(c.name, func(t *testing.T) {
t.Parallel()

asStatsd := c.labels.AsStatsdLabels()
if len(asStatsd) != len(c.labels)*2 {
t.Fatalf("wrong size: %#v", asStatsd)
}
if !reflect.DeepEqual(c.expected, asStatsd) {
t.Fatalf("labels do not match, expected %#v, got %#v", c.expected, asStatsd)
}
})
}
}
14 changes: 2 additions & 12 deletions thriftclient/client_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type ClientPoolConfig struct {

// Any labels that should be applied to metrics logged by the ClientPool.
// This includes the optional pool stats.
MetricsLabels map[string]string
MetricsLabels metricsbp.MetricsLabels

// ReportPoolStats signals to the ClientPool that it should report
// statistics on the underlying clientpool.Pool in a background
Expand All @@ -61,16 +61,6 @@ type ClientPoolConfig struct {
PoolGaugeInterval time.Duration
}

// getMetricLabels returns c.MetricsLabels as a slice of strings, appropriate
// for passing to a metrics client.
func (c ClientPoolConfig) getMetricLabels() []string {
labels := make([]string, len(c.MetricsLabels)*2)
for k, v := range c.MetricsLabels {
labels = append(labels, k, v)
}
return labels
}

// Client is a client object that implements both the clientpool.Client and
// thrift.TCLient interfaces.
//
Expand Down Expand Up @@ -187,7 +177,7 @@ func NewCustomClientPool(cfg ClientPoolConfig, genAddr AddressGenerator, clientF
}

func newClientPool(cfg ClientPoolConfig, genAddr AddressGenerator, clientFact ClientFactory, protoFact thrift.TProtocolFactory) (*clientPool, error) {
labels := cfg.getMetricLabels()
labels := cfg.MetricsLabels.AsStatsdLabels()
pool, err := clientpool.NewChannelPool(
cfg.InitialConnections,
cfg.MaxConnections,
Expand Down

0 comments on commit 8a6e99f

Please sign in to comment.