1package statsd 2 3import ( 4 "errors" 5 "fmt" 6 "net" 7 "os" 8 "time" 9) 10 11const ( 12 autoHostEnvName = "DD_AGENT_HOST" 13 autoPortEnvName = "DD_DOGSTATSD_PORT" 14 defaultUDPPort = "8125" 15) 16 17// udpWriter is an internal class wrapping around management of UDP connection 18type udpWriter struct { 19 conn net.Conn 20} 21 22// New returns a pointer to a new udpWriter given an addr in the format "hostname:port". 23func newUDPWriter(addr string) (*udpWriter, error) { 24 if addr == "" { 25 addr = addressFromEnvironment() 26 } 27 if addr == "" { 28 return nil, errors.New("No address passed and autodetection from environment failed") 29 } 30 31 udpAddr, err := net.ResolveUDPAddr("udp", addr) 32 if err != nil { 33 return nil, err 34 } 35 conn, err := net.DialUDP("udp", nil, udpAddr) 36 if err != nil { 37 return nil, err 38 } 39 writer := &udpWriter{conn: conn} 40 return writer, nil 41} 42 43// SetWriteTimeout is not needed for UDP, returns error 44func (w *udpWriter) SetWriteTimeout(d time.Duration) error { 45 return errors.New("SetWriteTimeout: not supported for UDP connections") 46} 47 48// Write data to the UDP connection with no error handling 49func (w *udpWriter) Write(data []byte) (int, error) { 50 return w.conn.Write(data) 51} 52 53func (w *udpWriter) Close() error { 54 return w.conn.Close() 55} 56 57func (w *udpWriter) remoteAddr() net.Addr { 58 return w.conn.RemoteAddr() 59} 60 61func addressFromEnvironment() string { 62 autoHost := os.Getenv(autoHostEnvName) 63 if autoHost == "" { 64 return "" 65 } 66 67 autoPort := os.Getenv(autoPortEnvName) 68 if autoPort == "" { 69 autoPort = defaultUDPPort 70 } 71 72 return fmt.Sprintf("%s:%s", autoHost, autoPort) 73} 74