mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-06 00:25:55 +00:00
Merge pull request #121 from benbjohnson/statsd
Add StatsClient with DataDog implementation.
This commit is contained in:
commit
e553096159
3 changed files with 180 additions and 0 deletions
113
datadog/datadog.go
Normal file
113
datadog/datadog.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package datadog
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/DataDog/datadog-go/statsd"
|
||||
"github.com/umbel/pilosa"
|
||||
)
|
||||
|
||||
const (
|
||||
// Rate represents a metric rate of 1/sec.
|
||||
Rate = 1
|
||||
|
||||
// Client buffer size.
|
||||
BufferLen = 256
|
||||
)
|
||||
|
||||
// Ensure client implements interface.
|
||||
var _ pilosa.StatsClient = &StatsClient{}
|
||||
|
||||
// StatsClient represents a DataDog implementation of pilosa.StatsClient.
|
||||
type StatsClient struct {
|
||||
client *statsd.Client
|
||||
tags []string
|
||||
}
|
||||
|
||||
// NewStatsClient returns a new instance of StatsClient.
|
||||
func NewStatsClient() (*StatsClient, error) {
|
||||
c, err := statsd.NewBuffered("127.0.0.1:8125", BufferLen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &StatsClient{client: c}, nil
|
||||
}
|
||||
|
||||
// Close closes the connection to the agent.
|
||||
func (c *StatsClient) Close() error {
|
||||
return c.client.Close()
|
||||
}
|
||||
|
||||
// Tags returns a sorted list of tags on the client.
|
||||
func (c *StatsClient) Tags() []string {
|
||||
return c.tags
|
||||
}
|
||||
|
||||
// WithTags returns a new client with additional tags appended.
|
||||
func (c *StatsClient) WithTags(tags ...string) pilosa.StatsClient {
|
||||
return &StatsClient{
|
||||
client: c.client,
|
||||
tags: unionTags(c.tags, tags),
|
||||
}
|
||||
}
|
||||
|
||||
// Count tracks the number of times something occurs per second.
|
||||
func (c *StatsClient) Count(name string, value int64) error {
|
||||
return c.client.Count(name, value, c.tags, Rate)
|
||||
}
|
||||
|
||||
// Gauge sets the value of a metric.
|
||||
func (c *StatsClient) Gauge(name string, value float64) error {
|
||||
return c.client.Gauge(name, value, c.tags, Rate)
|
||||
}
|
||||
|
||||
// Histogram tracks statistical distribution of a metric.
|
||||
func (c *StatsClient) Histogram(name string, value float64) error {
|
||||
return c.client.Histogram(name, value, c.tags, Rate)
|
||||
}
|
||||
|
||||
// Set tracks number of unique elements.
|
||||
func (c *StatsClient) Set(name string, value string) error {
|
||||
return c.client.Set(name, value, c.tags, Rate)
|
||||
}
|
||||
|
||||
// Timing tracks timing information for a metric.
|
||||
func (c *StatsClient) Timing(name string, value time.Duration) error {
|
||||
return c.client.Timing(name, value, c.tags, Rate)
|
||||
}
|
||||
|
||||
// unionTags returns a sorted set of tags which combine a & b.
|
||||
func unionTags(a, b []string) []string {
|
||||
// Sort both sets first.
|
||||
sort.Strings(a)
|
||||
sort.Strings(b)
|
||||
|
||||
// Find size of largest slice.
|
||||
n := len(a)
|
||||
if len(b) > n {
|
||||
n = len(b)
|
||||
}
|
||||
|
||||
// Exit if both sets are empty.
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Iterate over both in order and merge.
|
||||
other := make([]string, 0, n)
|
||||
for len(a) > 0 || len(b) > 0 {
|
||||
if len(a) == 0 {
|
||||
other, b = append(other, b[0]), b[1:]
|
||||
} else if len(b) == 0 {
|
||||
other, a = append(other, a[0]), a[1:]
|
||||
} else if a[0] < b[0] {
|
||||
other, a = append(other, a[0]), a[1:]
|
||||
} else if b[0] < a[0] {
|
||||
other, b = append(other, b[0]), b[1:]
|
||||
} else {
|
||||
other, a, b = append(other, a[0]), a[1:], b[1:]
|
||||
}
|
||||
}
|
||||
return other
|
||||
}
|
||||
29
datadog/datadog_test.go
Normal file
29
datadog/datadog_test.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package datadog_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/umbel/pilosa/datadog"
|
||||
)
|
||||
|
||||
func TestStatsClient_WithTags(t *testing.T) {
|
||||
// Create a new client.
|
||||
c, err := datadog.NewStatsClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
// Create a new client with additional tags.
|
||||
c1 := c.WithTags("foo", "bar")
|
||||
if tags := c1.Tags(); !reflect.DeepEqual(tags, []string{"bar", "foo"}) {
|
||||
t.Fatalf("unexpected tags: %+v", tags)
|
||||
}
|
||||
|
||||
// Create a new client from the clone with more tags.
|
||||
c2 := c1.WithTags("bar", "baz")
|
||||
if tags := c2.Tags(); !reflect.DeepEqual(tags, []string{"bar", "baz", "foo"}) {
|
||||
t.Fatalf("unexpected tags: %+v", tags)
|
||||
}
|
||||
}
|
||||
38
stats.go
Normal file
38
stats.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package pilosa
|
||||
|
||||
import "time"
|
||||
|
||||
// StatsClient represents a client to a stats server.
|
||||
type StatsClient interface {
|
||||
// Returns a sorted list of tags on the client.
|
||||
Tags() []string
|
||||
|
||||
// Returns a new client with additional tags appended.
|
||||
WithTags(tags ...string) StatsClient
|
||||
|
||||
// Tracks the number of times something occurs per second.
|
||||
Count(name string, value int64) error
|
||||
|
||||
// Sets the value of a metric.
|
||||
Gauge(name string, value float64) error
|
||||
|
||||
// Tracks statistical distribution of a metric.
|
||||
Histogram(name string, value float64) error
|
||||
|
||||
// Tracks number of unique elements.
|
||||
Set(name string, value string) error
|
||||
|
||||
// Tracks timing information for a metric.
|
||||
Timing(name string, value time.Duration) error
|
||||
}
|
||||
|
||||
// NopStatsClient represents a client that doesn't do anything.
|
||||
type NopStatsClient struct{}
|
||||
|
||||
func (c *NopStatsClient) Tags() []string { return nil }
|
||||
func (c *NopStatsClient) WithTags(tags ...string) StatsClient { return c }
|
||||
func (c *NopStatsClient) Count(name string, value int64) error { return nil }
|
||||
func (c *NopStatsClient) Gauge(name string, value float64) error { return nil }
|
||||
func (c *NopStatsClient) Histogram(name string, value float64) error { return nil }
|
||||
func (c *NopStatsClient) Set(name string, value string) error { return nil }
|
||||
func (c *NopStatsClient) Timing(name string, value time.Duration) error { return nil }
|
||||
Loading…
Add table
Reference in a new issue