Merge pull request #1284 from nbrownus/telemetry

Option to disable hostnames from telemetry
This commit is contained in:
James Phillips 2016-02-06 22:00:14 -08:00
commit a599e88507
5 changed files with 181 additions and 77 deletions

View File

@ -588,12 +588,13 @@ func (c *Command) Run(args []string) int {
*/
inm := metrics.NewInmemSink(10*time.Second, time.Minute)
metrics.DefaultInmemSignal(inm)
metricsConf := metrics.DefaultConfig(config.StatsitePrefix)
metricsConf := metrics.DefaultConfig(config.Telemetry.StatsitePrefix)
metricsConf.EnableHostname = !config.Telemetry.DisableHostname
// Configure the statsite sink
var fanout metrics.FanoutSink
if config.StatsiteAddr != "" {
sink, err := metrics.NewStatsiteSink(config.StatsiteAddr)
if config.Telemetry.StatsiteAddr != "" {
sink, err := metrics.NewStatsiteSink(config.Telemetry.StatsiteAddr)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to start statsite sink. Got: %s", err))
return 1
@ -602,8 +603,8 @@ func (c *Command) Run(args []string) int {
}
// Configure the statsd sink
if config.StatsdAddr != "" {
sink, err := metrics.NewStatsdSink(config.StatsdAddr)
if config.Telemetry.StatsdAddr != "" {
sink, err := metrics.NewStatsdSink(config.Telemetry.StatsdAddr)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to start statsd sink. Got: %s", err))
return 1
@ -612,14 +613,14 @@ func (c *Command) Run(args []string) int {
}
// Configure the DogStatsd sink
if config.DogStatsdAddr != "" {
if config.Telemetry.DogStatsdAddr != "" {
var tags []string
if config.DogStatsdTags != nil {
tags = config.DogStatsdTags
if config.Telemetry.DogStatsdTags != nil {
tags = config.Telemetry.DogStatsdTags
}
sink, err := datadog.NewDogStatsdSink(config.DogStatsdAddr, metricsConf.HostName)
sink, err := datadog.NewDogStatsdSink(config.Telemetry.DogStatsdAddr, metricsConf.HostName)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to start DogStatsd sink. Got: %s", err))
return 1

View File

@ -91,6 +91,32 @@ type DNSConfig struct {
OnlyPassing bool `mapstructure:"only_passing"`
}
// Telemetry is the telemetry configuration for the server
type Telemetry struct {
// StatsiteAddr is the address of a statsite instance. If provided,
// metrics will be streamed to that instance.
StatsiteAddr string `mapstructure:"statsite_address"`
// StatsdAddr is the address of a statsd instance. If provided,
// metrics will be sent to that instance.
StatsdAddr string `mapstructure:"statsd_address"`
// StatsitePrefix is the prefix used to write stats values to. By
// default this is set to 'consul'.
StatsitePrefix string `mapstructure:"statsite_prefix"`
// DisableHostname will disable hostname prefixing for all metrics
DisableHostname bool `mapstructure:"disable_hostname"`
// DogStatsdAddr is the address of a dogstatsd instance. If provided,
// metrics will be sent to that instance
DogStatsdAddr string `mapstructure:"dogstatsd_addr"`
// DogStatsdTags are the global tags that should be sent with each packet to dogstatsd
// It is a list of strings, where each string looks like "my_tag_name:my_tag_value"
DogStatsdTags []string `mapstructure:"dogstatsd_tags"`
}
// Config is the configuration that can be set for an Agent.
// Some of this is configurable as CLI flags, but most must
// be set using a configuration file.
@ -177,25 +203,7 @@ type Config struct {
// the INT signal. Defaults false. This can be changed on reload.
SkipLeaveOnInt bool `mapstructure:"skip_leave_on_interrupt"`
// StatsiteAddr is the address of a statsite instance. If provided,
// metrics will be streamed to that instance.
StatsiteAddr string `mapstructure:"statsite_addr"`
// StatsitePrefix is the prefix used to write stats values to. By
// default this is set to 'consul'.
StatsitePrefix string `mapstructure:"statsite_prefix"`
// StatsdAddr is the address of a statsd instance. If provided,
// metrics will be sent to that instance.
StatsdAddr string `mapstructure:"statsd_addr"`
// DogStatsdAddr is the address of a dogstatsd instance. If provided,
// metrics will be sent to that instance
DogStatsdAddr string `mapstructure:"dogstatsd_addr"`
// DogStatsdTags are the global tags that should be sent with each packet to dogstatsd
// It is a list of strings, where each string looks like "my_tag_name:my_tag_value"
DogStatsdTags []string `mapstructure:"dogstatsd_tags"`
Telemetry Telemetry `mapstructure:"telemetry"`
// Protocol is the Consul protocol version to use.
Protocol int `mapstructure:"protocol"`
@ -464,6 +472,10 @@ func (u UnixSocketPermissions) Mode() string {
return u.Perms
}
func (s *Telemetry) GoString() string {
return fmt.Sprintf("*%#v", *s)
}
// UnixSocketConfig stores information about various unix sockets which
// Consul creates and uses for communication.
type UnixSocketConfig struct {
@ -504,7 +516,9 @@ func DefaultConfig() *Config {
DNSConfig: DNSConfig{
MaxStale: 5 * time.Second,
},
StatsitePrefix: "consul",
Telemetry: Telemetry{
StatsitePrefix: "consul",
},
SyslogFacility: "LOCAL0",
Protocol: consul.ProtocolVersion2Compatible,
CheckUpdateInterval: 5 * time.Minute,
@ -613,6 +627,30 @@ func DecodeConfig(r io.Reader) (*Config, error) {
}
result.Checks = append(result.Checks, check)
}
// A little hacky but upgrades the old stats config directives to the new way
if sub, ok := obj["statsd_addr"]; ok && result.Telemetry.StatsdAddr == "" {
result.Telemetry.StatsdAddr = sub.(string)
}
if sub, ok := obj["statsite_addr"]; ok && result.Telemetry.StatsiteAddr == "" {
result.Telemetry.StatsiteAddr = sub.(string)
}
if sub, ok := obj["statsite_prefix"]; ok && result.Telemetry.StatsitePrefix == "" {
result.Telemetry.StatsitePrefix = sub.(string)
}
if sub, ok := obj["dogstatsd_addr"]; ok && result.Telemetry.DogStatsdAddr == "" {
result.Telemetry.DogStatsdAddr = sub.(string)
}
if sub, ok := obj["dogstatsd_tags"].([]interface{}); ok && len(result.Telemetry.DogStatsdTags) == 0 {
result.Telemetry.DogStatsdTags = make([]string, len(sub))
for i := range sub {
result.Telemetry.DogStatsdTags[i] = sub[i].(string)
}
}
}
// Decode
@ -632,7 +670,11 @@ func DecodeConfig(r io.Reader) (*Config, error) {
// Check unused fields and verify that no bad configuration options were
// passed to Consul. There are a few additional fields which don't directly
// use mapstructure decoding, so we need to account for those as well.
allowedKeys := []string{"service", "services", "check", "checks"}
allowedKeys := []string{
"service", "services", "check", "checks", "statsd_addr", "statsite_addr", "statsite_prefix",
"dogstatsd_addr", "dogstatsd_tags",
}
var unused []string
for _, field := range md.Unused {
if !lib.StrContains(allowedKeys, field) {
@ -947,20 +989,23 @@ func MergeConfig(a, b *Config) *Config {
if b.SkipLeaveOnInt == true {
result.SkipLeaveOnInt = true
}
if b.StatsiteAddr != "" {
result.StatsiteAddr = b.StatsiteAddr
if b.Telemetry.DisableHostname == true {
result.Telemetry.DisableHostname = true
}
if b.StatsitePrefix != "" {
result.StatsitePrefix = b.StatsitePrefix
if b.Telemetry.StatsdAddr != "" {
result.Telemetry.StatsdAddr = b.Telemetry.StatsdAddr
}
if b.StatsdAddr != "" {
result.StatsdAddr = b.StatsdAddr
if b.Telemetry.StatsiteAddr != "" {
result.Telemetry.StatsiteAddr = b.Telemetry.StatsiteAddr
}
if b.DogStatsdAddr != "" {
result.DogStatsdAddr = b.DogStatsdAddr
if b.Telemetry.StatsitePrefix != "" {
result.Telemetry.StatsitePrefix = b.Telemetry.StatsitePrefix
}
if b.DogStatsdTags != nil {
result.DogStatsdTags = b.DogStatsdTags
if b.Telemetry.DogStatsdAddr != "" {
result.Telemetry.DogStatsdAddr = b.Telemetry.DogStatsdAddr
}
if b.Telemetry.DogStatsdTags != nil {
result.Telemetry.DogStatsdTags = b.Telemetry.DogStatsdTags
}
if b.EnableDebug {
result.EnableDebug = true

View File

@ -635,10 +635,10 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("err: %s", err)
}
if config.StatsiteAddr != "127.0.0.1:7250" {
if config.Telemetry.StatsiteAddr != "127.0.0.1:7250" {
t.Fatalf("bad: %#v", config)
}
if config.StatsdAddr != "127.0.0.1:7251" {
if config.Telemetry.StatsdAddr != "127.0.0.1:7251" {
t.Fatalf("bad: %#v", config)
}
@ -648,19 +648,19 @@ func TestDecodeConfig(t *testing.T) {
if err != nil {
t.Fatalf("err: %s", err)
}
if config.DogStatsdAddr != "127.0.0.1:7254" {
if config.Telemetry.DogStatsdAddr != "127.0.0.1:7254" {
t.Fatalf("bad: %#v", config)
}
if len(config.DogStatsdTags) != 2 {
if len(config.Telemetry.DogStatsdTags) != 2 {
t.Fatalf("bad: %#v", config)
}
if config.DogStatsdTags[0] != "tag_1:val_1" {
if config.Telemetry.DogStatsdTags[0] != "tag_1:val_1" {
t.Fatalf("bad: %#v", config)
}
if config.DogStatsdTags[1] != "tag_2:val_2" {
if config.Telemetry.DogStatsdTags[1] != "tag_2:val_2" {
t.Fatalf("bad: %#v", config)
}
@ -670,7 +670,32 @@ func TestDecodeConfig(t *testing.T) {
if err != nil {
t.Fatalf("err: %s", err)
}
if config.StatsitePrefix != "my_prefix" {
if config.Telemetry.StatsitePrefix != "my_prefix" {
t.Fatalf("bad: %#v", config)
}
// New telemetry
input = `{"telemetry": { "statsite_prefix": "my_prefix", "statsite_address": "127.0.0.1:7250", "statsd_address":"127.0.0.1:7251", "disable_hostname": true, "dogstatsd_addr": "1.1.1.1:111", "dogstatsd_tags": [ "tag_1:val_1" ] } }`
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
if err != nil {
t.Fatalf("err: %s", err)
}
if config.Telemetry.StatsitePrefix != "my_prefix" {
t.Fatalf("bad: %#v", config)
}
if config.Telemetry.StatsiteAddr != "127.0.0.1:7250" {
t.Fatalf("bad: %#v", config)
}
if config.Telemetry.StatsdAddr != "127.0.0.1:7251" {
t.Fatalf("bad: %#v", config)
}
if config.Telemetry.DisableHostname != true {
t.Fatalf("bad: %#v", config)
}
if config.Telemetry.DogStatsdAddr != "1.1.1.1:111" {
t.Fatalf("bad: %#v", config)
}
if config.Telemetry.DogStatsdTags[0] != "tag_1:val_1" {
t.Fatalf("bad: %#v", config)
}
@ -1191,6 +1216,14 @@ func TestMergeConfig(t *testing.T) {
CheckUpdateIntervalRaw: "8m",
RetryIntervalRaw: "10s",
RetryIntervalWanRaw: "10s",
Telemetry: Telemetry{
DisableHostname: false,
StatsdAddr: "nope",
StatsiteAddr: "nope",
StatsitePrefix: "nope",
DogStatsdAddr: "nope",
DogStatsdTags: []string{"nope"},
},
}
b := &Config{
@ -1269,12 +1302,15 @@ func TestMergeConfig(t *testing.T) {
"handler": "foobar",
},
},
DisableRemoteExec: true,
StatsiteAddr: "127.0.0.1:7250",
StatsitePrefix: "stats_prefix",
StatsdAddr: "127.0.0.1:7251",
DogStatsdAddr: "127.0.0.1:7254",
DogStatsdTags: []string{"tag_1:val_1", "tag_2:val_2"},
DisableRemoteExec: true,
Telemetry: Telemetry{
StatsiteAddr: "127.0.0.1:7250",
StatsitePrefix: "stats_prefix",
StatsdAddr: "127.0.0.1:7251",
DisableHostname: true,
DogStatsdAddr: "127.0.0.1:7254",
DogStatsdTags: []string{"tag_1:val_1", "tag_2:val_2"},
},
DisableUpdateCheck: true,
DisableAnonymousSignature: true,
HTTPAPIResponseHeaders: map[string]string{

View File

@ -273,7 +273,10 @@ definitions support being updated during a reload.
"type": "checks",
"handler": "/usr/bin/health-check-handler.sh"
}
]
],
"telemetry": {
"statsite_address": "127.0.0.1:2180"
}
}
```
@ -572,29 +575,48 @@ definitions support being updated during a reload.
* <a name="start_join_wan"></a><a href="#start_join_wan">`start_join_wan`</a> An array of strings specifying
addresses of WAN nodes to [`-join-wan`](#_join_wan) upon startup.
* <a name="statsd_addr"></a><a href="#statsd_addr">`statsd_addr`</a> This provides the address of a
statsd instance in the format `host:port`. If provided, Consul will send various telemetry information
to that instance for aggregation. This can be used to capture runtime information. This sends UDP packets
only and can be used with statsd or statsite.
* <a name="telemetry"></a><a href="#telemetry">`telemetry`</a> An object describing where to send telemetry to
* <a name="dogstatsd_addr"></a><a href="#dogstatsd_addr">`dogstatsd_addr`</a> This provides the
address of a DogStatsD instance in the format `host:port`. DogStatsD is a protocol-compatible flavor of
statsd, with the added ability to decorate metrics with tags and event information. If provided, Consul will
send various telemetry information to that instance for aggregation. This can be used to capture runtime
information.
* <a name="telemetry-statsd_address"></a><a href="#telemetry-statsd_address">`statsd_address`</a> This provides the
address of a statsd instance. If provided, Consul will send various telemetry information to that instance for
aggregation. This can be used to capture runtime information. This sends UDP packets only and can be used with
statsd or statsite.
* <a name="telemetry-statsite_address"></a><a href="#telemetry-statsite_address">`statsite_address`</a> This provides
the address of a statsite instance. If provided, Consul will stream various telemetry information to that instance
for aggregation. This can be used to capture runtime information. This streams via TCP and can only be used with
statsite.
* <a name="telemetry-statsite_prefix"></a><a href="#telemetry-statsite_prefix">`statsite_prefix`</a>
The prefix used while writing all telemetry data to statsite. By default, this is set to "consul".
* <a name="telemetry-dogstatsd_addr"></a><a href="#telemetry-dogstatsd_addr">`dogstatsd_addr`</a> This provides the
address of a DogStatsD instance in the format `host:port`. DogStatsD is a protocol-compatible flavor of
statsd, with the added ability to decorate metrics with tags and event information. If provided, Consul will
send various telemetry information to that instance for aggregation. This can be used to capture runtime
information.
* <a name="telemetry-dogstatsd_tags"></a><a href="#telemetry-dogstatsd_tags">`dogstatsd_tags`</a> This provides a list of global tags
that will be added to all telemetry packets sent to DogStatsD. It is a list of strings, where each string
looks like "my_tag_name:my_tag_value".
* <a name="telemetry-disable_hostname"></a><a href="#telemetry-disable_hostname">`disable_hostname`</a>
Whether or not to prepend runtime telemetry with the machines hostname, defaults to false.
* <a name="statsd_addr"></a><a href="#statsd_addr">`statsd_addr`</a> Deprecated, see
<a href="#telemetry-statsd_address">`statsd_address`</a>
* <a name="dogstatsd_tags"></a><a href="#dogstatsd_tags">`dogstatsd_tags`</a> This provides a list of global tags
that will be added to all telemetry packets sent to DogStatsD. It is a list of strings, where each string
looks like "my_tag_name:my_tag_value".
* <a name="statsite_addr"></a><a href="#statsite_addr">`statsite_addr`</a> Deprecated, see
<a href="#telemetry-statsite_address">`statsite_address`</a>
* <a name="statsite_addr"></a><a href="#statsite_addr">`statsite_addr`</a> This provides the address of a
statsite instance in the format `host:port`. If provided, Consul will stream various telemetry information
to that instance for aggregation. This can be used to capture runtime information. This streams via TCP and
can only be used with statsite.
* <a name="statsite_prefix"></a><a href="#statsite_prefix">`statsite_prefix`</a> Deprecated, see
<a href="#telemetry-statsite_prefix">`statsite_prefix`</a>
* <a name="statsite_prefix"></a><a href="#statsite_prefix">`statsite_prefix`</a>
The prefix used while writing all telemetry data to statsite. By default, this
is set to "consul".
* <a name="dogstatsd_addr"></a><a href="#dogstatsd_addr">`dogstatsd_addr`</a> Deprecated, see
<a href="#telemetry-dogstatsd_addr">`dogstatsd_addr`</a>
* <a name="dogstatsd_tags"></a><a href="#dogstatsd_tags">`dogstatsd_tags`</a> Deprecated, see
<a href="#telemetry-dogstatsd_tags">`dogstatsd_tags`</a>
* <a name="syslog_facility"></a><a href="#syslog_facility">`syslog_facility`</a> When
[`enable_syslog`](#enable_syslog) is provided, this controls to which

View File

@ -19,10 +19,10 @@ it will dump the current telemetry information to the agent's `stderr`.
This telemetry information can be used for debugging or otherwise
getting a better view of what Consul is doing.
Additionally, if the [`statsite_addr` configuration option](/docs/agent/options.html#statsite_addr)
is provided, the telemetry information will be streamed to a
[statsite](http://github.com/armon/statsite) server where it can be
aggregated and flushed to Graphite or any other metrics store.
Additionally, if the [`telemetry` configuration options](/docs/agent/options.html#telemetry)
are provided, the telemetry information will be streamed to a
[statsite](http://github.com/armon/statsite) or [statsd](http://github.com/etsy/statsd) server where
it can be aggregated and flushed to Graphite or any other metrics store.
Below is sample output of a telemetry dump: