Skip to content

Commit

Permalink
Option to disable hostnames from telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
nbrownus committed Jan 29, 2016
1 parent 3215b87 commit 43a4f3f
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 81 deletions.
19 changes: 10 additions & 9 deletions command/agent/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,12 +587,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
Expand All @@ -601,8 +602,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
Expand All @@ -611,14 +612,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
Expand Down
107 changes: 76 additions & 31 deletions command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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.
Expand Down Expand Up @@ -176,25 +202,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"`
Expand Down Expand Up @@ -463,6 +471,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 {
Expand Down Expand Up @@ -503,7 +515,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,
Expand Down Expand Up @@ -612,6 +626,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
Expand All @@ -631,7 +669,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 !strContains(allowedKeys, field) {
Expand Down Expand Up @@ -946,20 +988,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.Telemetry.StatsdAddr != "" {
result.Telemetry.StatsdAddr = b.Telemetry.StatsdAddr
}
if b.StatsitePrefix != "" {
result.StatsitePrefix = b.StatsitePrefix
if b.Telemetry.StatsiteAddr != "" {
result.Telemetry.StatsiteAddr = b.Telemetry.StatsiteAddr
}
if b.StatsdAddr != "" {
result.StatsdAddr = b.StatsdAddr
if b.Telemetry.StatsitePrefix != "" {
result.Telemetry.StatsitePrefix = b.Telemetry.StatsitePrefix
}
if b.DogStatsdAddr != "" {
result.DogStatsdAddr = b.DogStatsdAddr
if b.Telemetry.DogStatsdAddr != "" {
result.Telemetry.DogStatsdAddr = b.Telemetry.DogStatsdAddr
}
if b.DogStatsdTags != nil {
result.DogStatsdTags = b.DogStatsdTags
if b.Telemetry.DogStatsdTags != nil {
result.Telemetry.DogStatsdTags = b.Telemetry.DogStatsdTags
}
if b.EnableDebug {
result.EnableDebug = true
Expand Down
62 changes: 49 additions & 13 deletions command/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,10 +633,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)
}

Expand All @@ -646,19 +646,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)
}

Expand All @@ -668,7 +668,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)
}

Expand Down Expand Up @@ -1189,6 +1214,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{
Expand Down Expand Up @@ -1267,12 +1300,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{
Expand Down
70 changes: 46 additions & 24 deletions website/source/docs/agent/options.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
```

Expand Down Expand Up @@ -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="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="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> 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>
The prefix used while writing all telemetry data to statsite. By default, this
is set to "consul".
* <a name="telemetry"></a><a href="#telemetry">`telemetry`</a> An object describing where to send telemetry to

* <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="statsite_addr"></a><a href="#statsite_addr">`statsite_addr`</a> Deprecated, see
<a href="#telemetry-statsite_address">`statsite_address`</a>

* <a name="statsite_prefix"></a><a href="#statsite_prefix">`statsite_prefix`</a> Deprecated, see
<a href="#telemetry-statsite_prefix">`statsite_prefix`</a>

* <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
Expand Down
Loading

0 comments on commit 43a4f3f

Please sign in to comment.