diff --git a/pkg/config/config.go b/pkg/config/config.go index 0eb86fb42351bd..54b10a02479cca 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -181,6 +181,7 @@ func InitConfig(config Config) { config.BindEnvAndSetDefault("check_runners", int64(4)) config.BindEnvAndSetDefault("auth_token_file_path", "") config.BindEnvAndSetDefault("bind_host", "localhost") + config.BindEnvAndSetDefault("dogstatsd_windows_pipe_name", "") config.BindEnvAndSetDefault("ipc_address", "localhost") config.BindEnvAndSetDefault("health_port", int64(0)) config.BindEnvAndSetDefault("disable_py3_validation", false) diff --git a/pkg/trace/config/apply.go b/pkg/trace/config/apply.go index e31aca85315d64..674e1348c8e7d5 100644 --- a/pkg/trace/config/apply.go +++ b/pkg/trace/config/apply.go @@ -238,6 +238,9 @@ func (c *AgentConfig) applyDatadogConfig() error { } } + if config.Datadog.IsSet("dogstatsd_windows_pipe_name") { + c.StatsdWindowsPipe = config.Datadog.GetString("dogstatsd_windows_pipe_name") + } if config.Datadog.IsSet("bind_host") { host := config.Datadog.GetString("bind_host") c.StatsdHost = host diff --git a/pkg/trace/config/config.go b/pkg/trace/config/config.go index de2e818e22b25e..f24c7fa10950b7 100644 --- a/pkg/trace/config/config.go +++ b/pkg/trace/config/config.go @@ -83,8 +83,9 @@ type AgentConfig struct { ConnectionResetInterval time.Duration // frequency at which outgoing connections are reset. 0 means no reset is performed // internal telemetry - StatsdHost string - StatsdPort int + StatsdWindowsPipe string + StatsdHost string + StatsdPort int // logging LogLevel string diff --git a/pkg/trace/metrics/metrics.go b/pkg/trace/metrics/metrics.go index 70fc06d353f12d..5788b7e63a3a88 100644 --- a/pkg/trace/metrics/metrics.go +++ b/pkg/trace/metrics/metrics.go @@ -13,14 +13,30 @@ import ( "fmt" "github.com/DataDog/datadog-agent/pkg/trace/config" + "github.com/DataDog/datadog-go/statsd" ) // Configure creates a statsd client for the given agent's configuration, using the specified global tags. func Configure(conf *config.AgentConfig, tags []string) error { - client, err := statsd.New(fmt.Sprintf("%s:%d", conf.StatsdHost, conf.StatsdPort), statsd.WithTags(tags)) - if err != nil { - return err + var ( + client *statsd.Client + err error + ) + if conf.StatsdWindowsPipe != "" { + pipe, err := dialPipe(conf.StatsdWindowsPipe, nil) + if err != nil { + return err + } + client, err = statsd.NewWithWriter(pipe, statsd.WithTags(tags)) + if err != nil { + return err + } + } else { + client, err = statsd.New(fmt.Sprintf("%s:%d", conf.StatsdHost, conf.StatsdPort), statsd.WithTags(tags)) + if err != nil { + return err + } } Client = client return nil diff --git a/pkg/trace/metrics/pipe.go b/pkg/trace/metrics/pipe.go new file mode 100644 index 00000000000000..665630d279eb4b --- /dev/null +++ b/pkg/trace/metrics/pipe.go @@ -0,0 +1,16 @@ +package metrics + +import ( + "errors" + "net" + "time" +) + +type statsWriter struct { + net.Conn +} + +// SetWriteTimeout is not available for Windows Pipes. returns error +func (w *statsWriter) SetWriteTimeout(d time.Duration) error { + return errors.New("SetWriteTimeout: not supported for Windows Pipe connections") +} diff --git a/pkg/trace/metrics/pipe_nonwindows.go b/pkg/trace/metrics/pipe_nonwindows.go new file mode 100644 index 00000000000000..df189ffe05b577 --- /dev/null +++ b/pkg/trace/metrics/pipe_nonwindows.go @@ -0,0 +1,13 @@ +// +build !windows + +package metrics + +import ( + "fmt" + "runtime" + "time" +) + +func dialPipe(path string, timeout *time.Duration) (*statsWriter, error) { + return nil, fmt.Errorf("Windows Pipe not available on %s", runtime.GOOS) +} diff --git a/pkg/trace/metrics/pipe_windows.go b/pkg/trace/metrics/pipe_windows.go new file mode 100644 index 00000000000000..57c7adcd511897 --- /dev/null +++ b/pkg/trace/metrics/pipe_windows.go @@ -0,0 +1,15 @@ +package metrics + +import ( + "time" + + "github.com/Microsoft/go-winio" +) + +func dialPipe(path string, timeout *time.Duration) (*statsWriter, error) { + c, err := winio.DialPipe(path, timeout) + if err != nil { + return nil, err + } + return &statsWriter{c}, nil +}