diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/CHANGELOG.md golang-github-cactus-go-statsd-client-3.2.0/CHANGELOG.md --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/CHANGELOG.md 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/CHANGELOG.md 2019-09-22 03:37:35.000000000 +0000 @@ -3,6 +3,12 @@ ## head +## 3.2.0 2019-09-21 +* A new client constructor with "config style" semantics. + "legacy" client construction still supported, to retain backwards compat. +* Add an optional re-resolving client configuration. This sets a schedule for + having the client periodically re-resolve the addr to ip. This does add some + overhead, so best used only when necessary. ## 3.1.1 2018-01-19 * avoid some overhead by not using defer for two "hot" path funcs diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/debian/changelog golang-github-cactus-go-statsd-client-3.2.0/debian/changelog --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/debian/changelog 2019-07-14 16:48:02.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/debian/changelog 2019-12-08 22:41:26.000000000 +0000 @@ -1,3 +1,9 @@ +golang-github-cactus-go-statsd-client (3.2.0-1) unstable; urgency=medium + + * New upstream release + + -- Thorsten Alteholz Sun, 08 Dec 2019 22:41:26 +0000 + golang-github-cactus-go-statsd-client (3.1.1+git20190125.82b7a17-2) unstable; urgency=medium * upload source package diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/debian/watch golang-github-cactus-go-statsd-client-3.2.0/debian/watch --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/debian/watch 2019-02-21 17:58:02.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/debian/watch 2019-12-08 22:41:20.000000000 +0000 @@ -1,4 +1,4 @@ version=4 opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/golang-github-cactus-go-statsd-client-\$1\.tar\.gz/,\ uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/\$1~\$2\$3/ \ - https://github.com/cactus/go-statsd-client/tags .*/v?(\d\S*)\.tar\.gz + https://github.com/cactus/go-statsd-client/tags .*/v?(\d\S*)\.tar\.gz debian uupdate diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/README.md golang-github-cactus-go-statsd-client-3.2.0/README.md --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/README.md 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/README.md 2019-09-22 03:37:35.000000000 +0000 @@ -16,6 +16,79 @@ ## Example +Some examples: + +``` go +import ( + "log" + + "github.com/cactus/go-statsd-client/statsd" +) + +func main() { + // First create a client config. Here is a simple config that sends one + // stat per packet (for compatibility). + config := &statsd.ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + } + + /* + // This one is for a client that re-resolves the hostname ever 30 seconds. + // Useful if the address of a hostname changes frequently. Note that this + // type of client has some additional locking overhead for safety. + // As such, leave ResInetval as the zero value (previous exmaple) if you + // don't specifically need this functionality. + config := &statsd.ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + ResInterval: 30 * time.Second, + } + + // This one is for a buffered client, which sends multiple stats in one + // packet, is recommended when your server supports it (better performance). + config := &statsd.ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + UseBuffered: true, + // interval to force flush buffer. full buffers will flush on their own, + // but for data not frequently sent, a max threshold is useful + FlushInterval: 300*time.Millisecond, + } + + // This one is for a buffered resolving client, which sends multiple stats + // in one packet (like previous example), as well as re-resolving the + // hostname every 30 seconds. + config := &statsd.ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + ResInterval: 30 * time.Second, + UseBuffered: true, + FlushInterval: 300*time.Millisecond, + } + */ + + // Now create the client + client, err := statsd.NewClientWithConfig(config) + + // and handle any initialization errors + if err != nil { + log.Fatal(err) + } + + // make sure to close to clean up when done, to avoid leaks. + defer client.Close() + + // Send a stat + client.Inc("stat1", 42, 1.0) +} +``` + +### Legacy Example + +A legacy client creation method is still supported. This is retained so as not to break +or interrupt existing integrations. + ``` go import ( "log" @@ -36,7 +109,7 @@ if err != nil { log.Fatal(err) } - // make sure to clean up + // make sure to close to clean up when done, to avoid leaks. defer client.Close() // Send a stat @@ -44,7 +117,8 @@ } ``` -See [docs][2] for more info. There is also some simple example code in the + +See [docs][2] for more info. There is also some additional example code in the `test-client` directory. ## Contributors diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/SECURITY.md golang-github-cactus-go-statsd-client-3.2.0/SECURITY.md --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/SECURITY.md 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/SECURITY.md 2019-09-22 03:37:35.000000000 +0000 @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Either of the following are currently supported: + +* The HEAD of the master branch. +* The most recent tagged "release" version to appear on the [releases][1] page. + +## Reporting a Vulnerability + +To report a vulnerability, please open a github Issue stating only that you have found a security vulnerability or other problem that you would like to report, and requesting a [Draft Security Advisory][2] be created. + +A Draft Security Advisory will then be created, and the user that opened the Issue will be invited to collaborate on the Draft Advisory. + +If the issue is accepted, a comment to that effect will be made in the original issue. If the Security Advistory leaves draft state, it will eventually be linked from the original issue. + +If the issue is declined, a comment to that effect will be made in the original issue. + +[1]: https://github.com/cactus/go-statsd-client/releases +[2]: https://help.github.com/en/articles/about-maintainer-security-advisories diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_buffered.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_buffered.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_buffered.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_buffered.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// Copyright (c) 2012-2016 Eli Janssen -// Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file. - -package statsd - -import "time" - -// NewBufferedClient returns a new BufferedClient -// -// addr is a string of the format "hostname:port", and must be parsable by -// net.ResolveUDPAddr. -// -// prefix is the statsd client prefix. Can be "" if no prefix is desired. -// -// flushInterval is a time.Duration, and specifies the maximum interval for -// packet sending. Note that if you send lots of metrics, you will send more -// often. This is just a maximal threshold. -// -// If flushInterval is 0ms, defaults to 300ms. -// -// flushBytes specifies the maximum udp packet size you wish to send. If adding -// a metric would result in a larger packet than flushBytes, the packet will -// first be send, then the new data will be added to the next packet. -// -// If flushBytes is 0, defaults to 1432 bytes, which is considered safe -// for local traffic. If sending over the public internet, 512 bytes is -// the recommended value. -func NewBufferedClient(addr, prefix string, flushInterval time.Duration, flushBytes int) (Statter, error) { - if flushBytes <= 0 { - // https://github.com/etsy/statsd/blob/master/docs/metric_types.md#multi-metric-packets - flushBytes = 1432 - } - if flushInterval <= time.Duration(0) { - flushInterval = 300 * time.Millisecond - } - sender, err := NewBufferedSender(addr, flushInterval, flushBytes) - if err != nil { - return nil, err - } - - client := &Client{ - prefix: prefix, - sender: sender, - } - - return client, nil -} diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_buffered_test.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_buffered_test.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_buffered_test.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_buffered_test.go 2019-09-22 03:37:35.000000000 +0000 @@ -185,13 +185,44 @@ } func ExampleClient_buffered() { + // This one is for a buffered client, which sends multiple stats in one + // packet, is recommended when your server supports it (better performance). + config := &ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + UseBuffered: true, + // interval to force flush buffer. full buffers will flush on their own, + // but for data not frequently sent, a max threshold is useful + FlushInterval: 300 * time.Millisecond, + } + + // Now create the client + client, err := NewClientWithConfig(config) + + // and handle any initialization errors + if err != nil { + log.Fatal(err) + } + + // make sure to close to clean up when done, to avoid leaks. + defer client.Close() + + // Send a stat + err = client.Inc("stat1", 42, 1.0) + // handle any errors + if err != nil { + log.Printf("Error sending metric: %+v", err) + } +} + +func ExampleClient_legacyBuffered() { // first create a client client, err := NewBufferedClient("127.0.0.1:8125", "test-client", 10*time.Millisecond, 0) // handle any errors if err != nil { log.Fatal(err) } - // make sure to clean up + // make sure to close to clean up when done, to avoid leaks. defer client.Close() // Send a stat diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_config.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_config.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_config.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_config.go 2019-09-22 03:37:35.000000000 +0000 @@ -0,0 +1,111 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "fmt" + "time" +) + +type ClientConfig struct { + // addr is a string of the format "hostname:port", and must be something + // validly parsable by net.ResolveUDPAddr. + Address string + + // prefix is the statsd client prefix. Can be "" if no prefix is desired. + Prefix string + + // ResInterval is the interval over which the addr is re-resolved. + // Do note that this /does/ add overhead! + // If you need higher performance, leave unset (or set to 0), + // in which case the address will not be re-resolved. + // + // Note that if Address is an {ip}:{port} and not a {hostname}:{port}, then + // ResInterval will be ignored. + ResInterval time.Duration + + // UseBuffered determines whether a buffered sender is used or not. + // If a buffered sender is /not/ used, FlushInterval and FlushBytes values are + // ignored. Default is false. + UseBuffered bool + + // FlushInterval is a time.Duration, and specifies the maximum interval for + // packet sending. Note that if you send lots of metrics, you will send more + // often. This is just a maximal threshold. + // If FlushInterval is 0, defaults to 300ms. + FlushInterval time.Duration + + // If flushBytes is 0, defaults to 1432 bytes, which is considered safe + // for local traffic. If sending over the public internet, 512 bytes is + // the recommended value. + FlushBytes int +} + +// NewClientWithConfig returns a new BufferedClient +// +// config is a ClientConfig, which holds various configuration values. +func NewClientWithConfig(config *ClientConfig) (Statter, error) { + var sender Sender + var err error + + // guard against nil config + if config == nil { + return nil, fmt.Errorf("config cannot be nil") + } + + // Use a re-resolving simple sender iff: + // * The time duration greater than 0 + // * The Address is not an ip (eg. {ip}:{port}). + // Otherwise, re-resolution is not required. + if config.ResInterval > 0 && !mustBeIP(config.Address) { + sender, err = NewResolvingSimpleSender(config.Address, config.ResInterval) + } else { + sender, err = NewSimpleSender(config.Address) + } + if err != nil { + return nil, err + } + + if config.UseBuffered { + return newBufferedC(sender, config) + } else { + return NewClientWithSender(sender, config.Prefix) + } +} + +func newBufferedC(baseSender Sender, config *ClientConfig) (Statter, error) { + + flushBytes := config.FlushBytes + if flushBytes <= 0 { + // ref: + // github.com/etsy/statsd/blob/master/docs/metric_types.md#multi-metric-packets + flushBytes = 1432 + } + + flushInterval := config.FlushInterval + if flushInterval <= time.Duration(0) { + flushInterval = 300 * time.Millisecond + } + + bufsender, err := newBufferedSenderWithSender(baseSender, flushInterval, flushBytes) + if err != nil { + return nil, err + } + + return NewClientWithSender(bufsender, config.Prefix) +} + +// NewClientWithSender returns a pointer to a new Client and an error. +// +// sender is an instance of a statsd.Sender interface and may not be nil +// +// prefix is the stastd client prefix. Can be "" if no prefix is desired. +func NewClientWithSender(sender Sender, prefix string) (Statter, error) { + if sender == nil { + return nil, fmt.Errorf("Client sender may not be nil") + } + + return &Client{prefix: prefix, sender: sender}, nil +} diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client.go 2019-09-22 03:37:35.000000000 +0000 @@ -279,34 +279,6 @@ return c } -// NewClient returns a pointer to a new Client, and an error. -// -// addr is a string of the format "hostname:port", and must be parsable by -// net.ResolveUDPAddr. -// -// prefix is the statsd client prefix. Can be "" if no prefix is desired. -func NewClient(addr, prefix string) (Statter, error) { - sender, err := NewSimpleSender(addr) - if err != nil { - return nil, err - } - - return &Client{prefix: prefix, sender: sender}, nil -} - -// NewClientWithSender returns a pointer to a new Client and an error. -// -// sender is an instance of a statsd.Sender interface and may not be nil -// -// prefix is the stastd client prefix. Can be "" if no prefix is desired. -func NewClientWithSender(sender Sender, prefix string) (Statter, error) { - if sender == nil { - return nil, fmt.Errorf("Client sender may not be nil") - } - - return &Client{prefix: prefix, sender: sender}, nil -} - // joinPathComp is a helper that ensures we combine path components with a dot // when it's appropriate to do so; prefix is the existing prefix and suffix is // the new component being added. @@ -319,9 +291,3 @@ } return prefix + suffix } - -// Dial is a compatibility alias for NewClient -var Dial = NewClient - -// New is a compatibility alias for NewClient -var New = NewClient diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_legacy.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_legacy.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_legacy.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_legacy.go 2019-09-22 03:37:35.000000000 +0000 @@ -0,0 +1,73 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import "time" + +// Deprecated stuff here... + +// NewBufferedClient returns a new BufferedClient +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +// +// prefix is the statsd client prefix. Can be "" if no prefix is desired. +// +// flushInterval is a time.Duration, and specifies the maximum interval for +// packet sending. Note that if you send lots of metrics, you will send more +// often. This is just a maximal threshold. +// +// If flushInterval is 0ms, defaults to 300ms. +// +// flushBytes specifies the maximum udp packet size you wish to send. If adding +// a metric would result in a larger packet than flushBytes, the packet will +// first be send, then the new data will be added to the next packet. +// +// If flushBytes is 0, defaults to 1432 bytes, which is considered safe +// for local traffic. If sending over the public internet, 512 bytes is +// the recommended value. +// +// Deprecated: This interface is "legacy", and it is recommented to migrate to +// using NewClientWithConfig in the future. +func NewBufferedClient(addr, prefix string, flushInterval time.Duration, flushBytes int) (Statter, error) { + config := &ClientConfig{ + Address: addr, + Prefix: prefix, + UseBuffered: true, + FlushInterval: flushInterval, + FlushBytes: flushBytes, + } + return NewClientWithConfig(config) +} + +// NewClient returns a pointer to a new Client, and an error. +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +// +// prefix is the statsd client prefix. Can be "" if no prefix is desired. +// +// Deprecated: This interface is "legacy", and it is recommented to migrate to +// using NewClientWithConfig in the future. +func NewClient(addr, prefix string) (Statter, error) { + config := &ClientConfig{ + Address: addr, + Prefix: prefix, + UseBuffered: false, + } + return NewClientWithConfig(config) +} + +// Dial is a compatibility alias for NewClient +// +// Deprecated: This interface is "legacy", and it is recommented to migrate to +// using NewClientWithConfig in the future. +var Dial = NewClient + +// New is a compatibility alias for NewClient +// +// Deprecated: This interface is "legacy", and it is recommented to migrate to +// using NewClientWithConfig in the future. +var New = NewClient diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_noop.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_noop.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_noop.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_noop.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -// Copyright (c) 2012-2016 Eli Janssen -// Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file. - -package statsd - -import "time" - -// A NoopClient is a client that does nothing. -type NoopClient struct{} - -// Close closes the connection and cleans up. -func (s *NoopClient) Close() error { - return nil -} - -// Inc increments a statsd count type. -// stat is a string name for the metric. -// value is the integer value -// rate is the sample rate (0.0 to 1.0) -func (s *NoopClient) Inc(stat string, value int64, rate float32) error { - return nil -} - -// Dec decrements a statsd count type. -// stat is a string name for the metric. -// value is the integer value. -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) Dec(stat string, value int64, rate float32) error { - return nil -} - -// Gauge submits/Updates a statsd gauge type. -// stat is a string name for the metric. -// value is the integer value. -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) Gauge(stat string, value int64, rate float32) error { - return nil -} - -// GaugeDelta submits a delta to a statsd gauge. -// stat is the string name for the metric. -// value is the (positive or negative) change. -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) GaugeDelta(stat string, value int64, rate float32) error { - return nil -} - -// Timing submits a statsd timing type. -// stat is a string name for the metric. -// delta is the time duration value in milliseconds -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) Timing(stat string, delta int64, rate float32) error { - return nil -} - -// TimingDuration submits a statsd timing type. -// stat is a string name for the metric. -// delta is the timing value as time.Duration -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) TimingDuration(stat string, delta time.Duration, rate float32) error { - return nil -} - -// Set submits a stats set type. -// stat is a string name for the metric. -// value is the string value -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) Set(stat string, value string, rate float32) error { - return nil -} - -// SetInt submits a number as a stats set type. -// convenience method for Set with number. -// stat is a string name for the metric. -// value is the integer value -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) SetInt(stat string, value int64, rate float32) error { - return nil -} - -// Raw formats the statsd event data, handles sampling, prepares it, -// and sends it to the server. -// stat is the string name for the metric. -// value is the preformatted "raw" value string. -// rate is the sample rate (0.0 to 1.0). -func (s *NoopClient) Raw(stat string, value string, rate float32) error { - return nil -} - -// SetPrefix sets/updates the statsd client prefix -func (s *NoopClient) SetPrefix(prefix string) {} - -// NewSubStatter returns a SubStatter with appended prefix -func (s *NoopClient) NewSubStatter(prefix string) SubStatter { - return &NoopClient{} -} - -// SetSamplerFunc sets the sampler function -func (s *NoopClient) SetSamplerFunc(sampler SamplerFunc) {} - -// NewNoopClient returns a pointer to a new NoopClient, and an error (always -// nil, just supplied to support api convention). -// Use variadic arguments to support identical format as NewClient, or a more -// conventional no argument form. -func NewNoopClient(a ...interface{}) (Statter, error) { - return &NoopClient{}, nil -} - -// NewNoop is a compatibility alias for NewNoopClient -var NewNoop = NewNoopClient diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_noop_legacy.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_noop_legacy.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_noop_legacy.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_noop_legacy.go 2019-09-22 03:37:35.000000000 +0000 @@ -0,0 +1,120 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import "time" + +// A NoopClient is a client that does nothing. +// +// Deprecated: This type is "legacy", and it is recommented to migrate to +// using a nil *Client in the future. +type NoopClient struct{} + +// Close closes the connection and cleans up. +func (s *NoopClient) Close() error { + return nil +} + +// Inc increments a statsd count type. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0) +func (s *NoopClient) Inc(stat string, value int64, rate float32) error { + return nil +} + +// Dec decrements a statsd count type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Dec(stat string, value int64, rate float32) error { + return nil +} + +// Gauge submits/Updates a statsd gauge type. +// stat is a string name for the metric. +// value is the integer value. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Gauge(stat string, value int64, rate float32) error { + return nil +} + +// GaugeDelta submits a delta to a statsd gauge. +// stat is the string name for the metric. +// value is the (positive or negative) change. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) GaugeDelta(stat string, value int64, rate float32) error { + return nil +} + +// Timing submits a statsd timing type. +// stat is a string name for the metric. +// delta is the time duration value in milliseconds +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Timing(stat string, delta int64, rate float32) error { + return nil +} + +// TimingDuration submits a statsd timing type. +// stat is a string name for the metric. +// delta is the timing value as time.Duration +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) TimingDuration(stat string, delta time.Duration, rate float32) error { + return nil +} + +// Set submits a stats set type. +// stat is a string name for the metric. +// value is the string value +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Set(stat string, value string, rate float32) error { + return nil +} + +// SetInt submits a number as a stats set type. +// convenience method for Set with number. +// stat is a string name for the metric. +// value is the integer value +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) SetInt(stat string, value int64, rate float32) error { + return nil +} + +// Raw formats the statsd event data, handles sampling, prepares it, +// and sends it to the server. +// stat is the string name for the metric. +// value is the preformatted "raw" value string. +// rate is the sample rate (0.0 to 1.0). +func (s *NoopClient) Raw(stat string, value string, rate float32) error { + return nil +} + +// SetPrefix sets/updates the statsd client prefix +func (s *NoopClient) SetPrefix(prefix string) {} + +// NewSubStatter returns a SubStatter with appended prefix +func (s *NoopClient) NewSubStatter(prefix string) SubStatter { + return &NoopClient{} +} + +// SetSamplerFunc sets the sampler function +func (s *NoopClient) SetSamplerFunc(sampler SamplerFunc) {} + +// NewNoopClient returns a pointer to a new NoopClient, and an error (always +// nil, just supplied to support api convention). +// Use variadic arguments to support identical format as NewClient, or a more +// conventional no argument form. +// +// Deprecated: This type is "legacy", and it is recommented to migrate to +// using a nil *Client in the future. +func NewNoopClient(a ...interface{}) (Statter, error) { + return &NoopClient{}, nil +} + +// NewNoop is a compatibility alias for NewNoopClient +// +// Deprecated: This type is "legacy", and it is recommented to migrate to +// using a nil *Client in the future. +var NewNoop = NewNoopClient diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_substatter_test.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_substatter_test.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_substatter_test.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_substatter_test.go 2019-09-22 03:37:35.000000000 +0000 @@ -272,13 +272,20 @@ } func ExampleClient_substatter() { - // first create a client - client, err := NewClient("127.0.0.1:8125", "test-client") + // First create a client config. Here is a simple config that sends one + // stat per packet (for compatibility). + config := &ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + } + + // Now create the client + client, err := NewClientWithConfig(config) // handle any errors if err != nil { log.Fatal(err) } - // make sure to clean up + // make sure to close to clean up when done, to avoid leaks. defer client.Close() // create a substatter diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_test.go golang-github-cactus-go-statsd-client-3.2.0/statsd/client_test.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/client_test.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/client_test.go 2019-09-22 03:37:35.000000000 +0000 @@ -158,13 +158,40 @@ } func ExampleClient() { + // First create a client config. Here is a simple config that sends one + // stat per packet (for compatibility). + config := &ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + } + + // Now create the client + client, err := NewClientWithConfig(config) + + // and handle any initialization errors + if err != nil { + log.Fatal(err) + } + + // make sure to clean up + defer client.Close() + + // Send a stat + err = client.Inc("stat1", 42, 1.0) + // handle any errors + if err != nil { + log.Printf("Error sending metric: %+v", err) + } +} + +func ExampleClient_legacySimple() { // first create a client client, err := NewClient("127.0.0.1:8125", "test-client") // handle any errors if err != nil { log.Fatal(err) } - // make sure to clean up + // make sure to close to clean up when done, to avoid leaks. defer client.Close() // Send a stat @@ -180,22 +207,26 @@ var client Statter var err error - // first try to create a real client - client, err = NewClient("not-resolvable:8125", "test-client") + // First create a client config. Here is a simple config that sends one + // stat per packet (for compatibility). + config := &ClientConfig{ + Address: "not-resolvable:8125", + Prefix: "test-client", + } + + // Now create the client + client, err = NewClientWithConfig(config) + // Let us say real client creation fails, but you don't care enough about // stats that you don't want your program to run. Just log an error and // make a NoopClient instead if err != nil { log.Println("Remote endpoint did not resolve. Disabling stats", err) - client, _ = NewNoopClient() } - // make sure to clean up + // at this point, client is a nil *Client. This will work like a noop client. + // It is ok to call close when client is nil. It will be a noop too. defer client.Close() - // Send a stat + // Sicne client is nil, this is a noop. err = client.Inc("stat1", 42, 1.0) - // handle any errors - if err != nil { - log.Printf("Error sending metric: %+v", err) - } } diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/doc.go golang-github-cactus-go-statsd-client-3.2.0/statsd/doc.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/doc.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/doc.go 2019-09-22 03:37:35.000000000 +0000 @@ -9,21 +9,30 @@ Example usage: - // first create a client - client, err := statsd.NewClient("127.0.0.1:8125", "test-client") - // handle any errors - if err != nil { - log.Fatal(err) - } - // make sure to clean up - defer client.Close() - - // Send a stat - err = client.Inc("stat1", 42, 1.0) - // handle any errors - if err != nil { - log.Printf("Error sending metric: %+v", err) - } + // First create a client config. Here is a simple config that sends one + // stat per packet (for compatibility). + config := &statsd.ClientConfig{ + Address: "127.0.0.1:8125", + Prefix: "test-client", + } + + // Now create the client + client, err := statsd.NewClientWithConfig(config) + + // and handle any initialization errors + if err != nil { + log.Fatal(err) + } + + // make sure to clean up + defer client.Close() + + // Send a stat + err = client.Inc("stat1", 42, 1.0) + // handle any errors + if err != nil { + log.Printf("Error sending metric: %+v", err) + } */ package statsd diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/go.mod golang-github-cactus-go-statsd-client-3.2.0/statsd/go.mod --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/go.mod 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/go.mod 2019-09-22 03:37:35.000000000 +0000 @@ -1 +1,3 @@ module github.com/cactus/go-statsd-client/statsd + +go 1.12 diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender_buffered.go golang-github-cactus-go-statsd-client-3.2.0/statsd/sender_buffered.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender_buffered.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/sender_buffered.go 2019-09-22 03:37:35.000000000 +0000 @@ -54,7 +54,7 @@ return len(data), nil } -// Close Buffered Sender +// Close closes the Buffered Sender and cleans up. func (s *BufferedSender) Close() error { // since we are running, write lock during cleanup s.runmx.Lock() @@ -161,15 +161,33 @@ if err != nil { return nil, err } + return newBufferedSenderWithSender(simpleSender, flushInterval, flushBytes) +} + +// newBufferedSender returns a new BufferedSender +// +// sender is an instance of a statsd.Sender interface. Sender is required. +// +// flushInterval is a time.Duration, and specifies the maximum interval for +// packet sending. Note that if you send lots of metrics, you will send more +// often. This is just a maximal threshold. +// +// flushBytes specifies the maximum udp packet size you wish to send. If adding +// a metric would result in a larger packet than flushBytes, the packet will +// first be send, then the new data will be added to the next packet. +func newBufferedSenderWithSender(sender Sender, flushInterval time.Duration, flushBytes int) (Sender, error) { + if sender == nil { + return nil, fmt.Errorf("sender may not be nil") + } - sender := &BufferedSender{ + bufSender := &BufferedSender{ flushBytes: flushBytes, flushInterval: flushInterval, - sender: simpleSender, + sender: sender, buffer: senderPool.Get(), shutdown: make(chan chan error), } - sender.Start() - return sender, nil + bufSender.Start() + return bufSender, nil } diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender.go golang-github-cactus-go-statsd-client-3.2.0/statsd/sender.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/sender.go 2019-09-22 03:37:35.000000000 +0000 @@ -37,7 +37,7 @@ return n, nil } -// Close closes the SimpleSender +// Close closes the SimpleSender and cleans up. func (s *SimpleSender) Close() error { err := s.c.Close() return err diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender_resolving.go golang-github-cactus-go-statsd-client-3.2.0/statsd/sender_resolving.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/sender_resolving.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/sender_resolving.go 2019-09-22 03:37:35.000000000 +0000 @@ -0,0 +1,170 @@ +// Copyright (c) 2012-2016 Eli Janssen +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +package statsd + +import ( + "errors" + "fmt" + "net" + "sync" + "time" +) + +// ResolvingSimpleSender provides a socket send interface that re-resolves and +// reconnects. +type ResolvingSimpleSender struct { + // underlying connection + conn net.PacketConn + // resolved udp address + addrResolved *net.UDPAddr + // unresolved addr + addrUnresolved string + // interval time + reresolveInterval time.Duration + // lifecycle + mx sync.RWMutex + doneChan chan struct{} + running bool +} + +// Send sends the data to the server endpoint. +func (s *ResolvingSimpleSender) Send(data []byte) (int, error) { + s.mx.RLock() + if !s.running { + s.mx.RUnlock() + return 0, fmt.Errorf("ResolvingSimpleSender is not running") + } + + // no need for locking here, as the underlying fdNet + // already serialized writes + n, err := s.conn.(*net.UDPConn).WriteToUDP(data, s.addrResolved) + + // unlock manually, and early (vs doing a defer) to avoid some overhead + s.mx.RUnlock() + + if err != nil { + return 0, err + } + if n == 0 { + return n, errors.New("Wrote no bytes") + } + return n, nil +} + +// Close closes the ResolvingSender and cleans up +func (s *ResolvingSimpleSender) Close() error { + // lock to guard against ra reconnection modification + s.mx.Lock() + defer s.mx.Unlock() + + if !s.running { + return nil + } + + s.running = false + close(s.doneChan) + + err := s.conn.Close() + return err +} + +func (s *ResolvingSimpleSender) Reconnect() { + // lock to guard against s.running mutation + s.mx.RLock() + + if !s.running { + s.mx.RUnlock() + return + } + + // get old addr for comparison, then release lock (asap) + oldAddr := s.addrResolved.String() + + // done with rlock for now + s.mx.RUnlock() + + // ro doesn't change, so no need to lock + addrResolved, err := net.ResolveUDPAddr("udp", s.addrUnresolved) + + if err != nil { + // no good new address.. so continue with old address + return + } + + if oldAddr == addrResolved.String() { + // got same address.. so continue with old address + return + } + + // acquire write lock to both guard against s.running having been mutated in the + // meantime, as well as for safely setting s.ra + s.mx.Lock() + + // check running again, just to be sure nothing was terminated in the meantime... + if s.running { + s.addrResolved = addrResolved + } + s.mx.Unlock() +} + +// Start Resolving Simple Sender +// Begins ticker and read loop +func (s *ResolvingSimpleSender) Start() { + // write lock to start running + s.mx.Lock() + defer s.mx.Unlock() + + if s.running { + return + } + + s.running = true + go s.run() +} + +func (s *ResolvingSimpleSender) run() { + ticker := time.NewTicker(s.reresolveInterval) + defer ticker.Stop() + + for { + select { + case <-s.doneChan: + return + case <-ticker.C: + // reconnect locks/checks running, so no need to do it here + s.Reconnect() + } + } +} + +// NewResolvingSimpleSender returns a new ResolvingSimpleSender for +// sending to the supplied addresss. +// +// addr is a string of the format "hostname:port", and must be parsable by +// net.ResolveUDPAddr. +func NewResolvingSimpleSender(addr string, interval time.Duration) (Sender, error) { + conn, err := net.ListenPacket("udp", ":0") + if err != nil { + return nil, err + } + + addrResolved, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + conn.Close() + return nil, err + } + + sender := &ResolvingSimpleSender{ + conn: conn, + addrResolved: addrResolved, + addrUnresolved: addr, + reresolveInterval: interval, + doneChan: make(chan struct{}), + running: false, + } + + sender.Start() + return sender, nil +} diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/validator.go golang-github-cactus-go-statsd-client-3.2.0/statsd/validator.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/statsd/validator.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/statsd/validator.go 2019-09-22 03:37:35.000000000 +0000 @@ -6,6 +6,7 @@ import ( "fmt" + "net" "regexp" ) @@ -24,3 +25,13 @@ } return nil } + +func mustBeIP(hostport string) bool { + host, _, err := net.SplitHostPort(hostport) + if err != nil { + return false + } + + ip := net.ParseIP(host) + return ip != nil +} diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/test-client/main.go golang-github-cactus-go-statsd-client-3.2.0/test-client/main.go --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/test-client/main.go 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/test-client/main.go 2019-09-22 03:37:35.000000000 +0000 @@ -57,13 +57,21 @@ os.Exit(1) } + config := &statsd.ClientConfig{ + Address: opts.HostPort, + Prefix: opts.Prefix, + ResInterval: time.Duration(0), + } + var client statsd.Statter if !opts.Nil { - if !opts.Buffered { - client, err = statsd.NewClient(opts.HostPort, opts.Prefix) - } else { - client, err = statsd.NewBufferedClient(opts.HostPort, opts.Prefix, opts.Duration/time.Duration(4), 0) + if opts.Buffered { + config.UseBuffered = true + config.FlushInterval = opts.Duration / time.Duration(4) + config.FlushBytes = 0 } + + client, err = statsd.NewClientWithConfig(config) if err != nil { log.Fatal(err) } @@ -106,7 +114,6 @@ } case <-ender: log.Printf("%d events called\n", count) - os.Exit(0) return } } diff -Nru golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/.travis.yml golang-github-cactus-go-statsd-client-3.2.0/.travis.yml --- golang-github-cactus-go-statsd-client-3.1.1+git20190125.82b7a17/.travis.yml 2019-02-21 08:58:00.000000000 +0000 +++ golang-github-cactus-go-statsd-client-3.2.0/.travis.yml 2019-09-22 03:37:35.000000000 +0000 @@ -2,6 +2,5 @@ sudo: false script: go test -v -cpu=1,2 ./... go: - - "1.8.x" - - "1.9.x" - - "1.10.x" + - "1.11.x" + - "1.12.x"