-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstats.go
153 lines (131 loc) · 4.18 KB
/
stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package stat
import (
"context"
"fmt"
"net"
"strings"
"time"
"github.com/asecurityteam/settings/v2"
"github.com/rs/xstats"
"github.com/rs/xstats/dogstatsd"
)
const (
defaultDDAddr = "localhost:8125"
defaultDDPacketSize = 1 << 15 // Matches what is used in the xstats library.
defaultDDFlush = 10 * time.Second
// OutputNull is the selection for no metrics.
OutputNull = "NULL"
// OutputDatadog selects the datadog/extended-statsd driver.
OutputDatadog = "DATADOG"
defaultOutput = OutputNull
)
var (
defaultDDTags = []string{}
)
// NullConfig is empty. There are no options for NULL.
type NullConfig struct{}
// Name of the configuration as it might appear in config files.
func (*NullConfig) Name() string {
return "nullstat"
}
// NullComponent implements the settings.Component interface for
// a NOP stat client.
type NullComponent struct{}
// Settings generates a config with default values applied.
func (*NullComponent) Settings() *NullConfig {
return &NullConfig{}
}
// New creates a configured stats client.
func (*NullComponent) New(_ context.Context, conf *NullConfig) (Stat, error) {
return xstats.FromContext(context.Background()), nil
}
// DatadogConfig is for configuration a datadog client.
type DatadogConfig struct {
Address string `description:"Listener address to use when sending metrics."`
FlushInterval time.Duration `description:"Frequencing of sending metrics to listener."`
Tags []string `description:"Any static tags for all metrics."`
PacketSize int `description:"Max packet size to send."`
}
// Name of the configuration as it might appear in config files.
func (*DatadogConfig) Name() string {
return "datadog"
}
// DatadogComponent implements the settings.Component interface for
// a datadog stats client.
type DatadogComponent struct{}
// Settings generates a config with default values applied.
func (*DatadogComponent) Settings() *DatadogConfig {
return &DatadogConfig{
Address: defaultDDAddr,
FlushInterval: defaultDDFlush,
Tags: defaultDDTags,
PacketSize: defaultDDPacketSize,
}
}
// New creates a configured stats client.
func (*DatadogComponent) New(_ context.Context, conf *DatadogConfig) (Stat, error) {
writer, err := net.Dial("udp", conf.Address)
if err != nil {
return nil, err
}
stater := xstats.New(dogstatsd.NewMaxPacket(writer, conf.FlushInterval, conf.PacketSize))
if len(conf.Tags) > 0 {
stater.AddTags(conf.Tags...)
}
return stater, nil
}
// Config contains all configuration values for creating
// a system stat client.
type Config struct {
Output string `description:"Destination stream of the stats. One of NULLSTAT, DATADOG."`
NullStat *NullConfig
Datadog *DatadogConfig
}
// Name of the configuration as it might appear in config files.
func (*Config) Name() string {
return "stats"
}
// Component enables creating configured loggers.
type Component struct {
NullStat *NullComponent
Datadog *DatadogComponent
}
// NewComponent populates an StatComponent with defaults.
func NewComponent() *Component {
return &Component{
NullStat: &NullComponent{},
Datadog: &DatadogComponent{},
}
}
// Settings generates a StatsConfig with default values applied.
func (c *Component) Settings() *Config {
return &Config{
Output: defaultOutput,
NullStat: c.NullStat.Settings(),
Datadog: c.Datadog.Settings(),
}
}
// New creates a configured stats client.
func (c *Component) New(ctx context.Context, conf *Config) (Stat, error) {
switch {
case strings.EqualFold(conf.Output, OutputNull):
return c.NullStat.New(ctx, conf.NullStat)
case strings.EqualFold(conf.Output, OutputDatadog):
return c.Datadog.New(ctx, conf.Datadog)
default:
return nil, fmt.Errorf("unknown stats output %s", conf.Output)
}
}
// Load is a convenience method for binding the source to the component.
func Load(ctx context.Context, source settings.Source, c *Component) (Stat, error) {
dst := new(Stat)
err := settings.NewComponent(ctx, source, c, dst)
if err != nil {
return nil, err
}
return *dst, nil
}
// New is the top-level entry point for creating a new stat client.
func New(ctx context.Context, source settings.Source) (Stat, error) {
return Load(ctx, source, NewComponent())
}