quipo / statsd Goto Github PK
View Code? Open in Web Editor NEWGolang StatsD client
License: MIT License
Golang StatsD client
License: MIT License
We use Collectd to collect the timing stats, and it automatically calculates averages++ based on the timing events from statsd. But because statsd already calculates avg,cnt, max and min before sending the data, we end up with events like x.x.avg.avg, x.x.avg.cnt etc. instead of simply x.x.avg. I am no expert on the StatsD protocol or anything, but are averages, counts etc. really 'timing' measurements?
As it is, we have had to change our version of quipo/statsd so that the PrecisionTiming.Statsd function prints 'c' for count and 'g' instead of 'ms' to get correct measurements.
I wonder if this should be incorporated into the base code somehow?
Right now when I create udp socket there is no option to specify which ip version to use, I've got an issue on one of my servers statd clients sends udp packets over udp6
#
U ::1:13896 -> ::1:8125
environment.p007.p007_1.p007_1.redis.connection.active:1596|g
But statsd just drops these packets, only when I send them over ipv4
echo "sample.gauge:14|g" | nc -u -w0 127.0.0.1 8125
it is ok. Is there any way to specify ip version of client or it needs pull request?
This is essentially the opposite of #25, but the way Sysdig handles StatsD is to listen for outgoing packets in the kernel, rather than capture them. This is a relatively common use case for containerized applications (i.e. Docker & Kubernetes). By doing it this way, there's no need to instrument a StatsD listener in the container or deal with networking.
More info here:
https://sysdig.com/blog/how-to-collect-statsd-metrics-in-containers/
From looking into it, quipo/statsd use net.Conn, which will log a failure when emitting to no one in particular:
https://github.com/quipo/statsd/blob/master/client.go#L190
[BufferedStatsdClient] 2017/03/28 21:44:41 write udp 127.0.0.1:57858->127.0.0.1:8125: write: connection refused
Using a net.PacketConn and WriteTo() does not produce an error in the same conditions. I was considering a pull request for a sysdig client, but the scope is pretty large for an essentially parallel code path. I was wondering about just replacing the existing net.conn with a net.PacketConn?
The checkCount function evaluates if a count is less than or equal to zero, but raises an ErrInvalidCount
error that states ""count is less than 0".
func checkCount(c int64) error {
if c <= 0 {
return ErrInvalidCount
}
return nil
}
checkCount
should be evaluating for c < 0
. (Zero is OK).
The non-buffered client does this, but the buffered client does not.
The effect is that statsd interprets it as setting the value of the gauge instead of applying a delta.
When running in distributed container environments (Kubernetes) resolving connection to statsd
service may not always be successful, due to various reasons (outdated or lagging iptables
is one of many). The current implementation does not provide good handling for such edge-case. While consumer of the client library can "re-dial" the socket connection, it has no control over metrics functionality (bar overloading send
methods)
It would be very helpful if client library could "handle" this edge-case periodically retry socket connection while dropping current metrics.
Use-case:
dial TCP/UDP
errornil
Expected outcomes:
A. socket creation is successful upon initial socket creation (current model)
B. socket creation failed upon initial attempt, however, subsequently succeeds. Impact: loss of metrics until the socket is re-dialled.
C. socket creation failed upon initial and on all successive attempts. Impact: loss of all metrics.
We would need to block the call to flush otherwise we could lose some events between when the events collection gets send to statds and when the collection is reset. Is this intentional?
It it not possible to send sub millisecond timings, or timings with more than 1millisecond precision.
I suggest: #3
I want to use the same key in both Incr and PrecisionTiming. I assumed that the internal logic would take care of using prefixes like "timers" and other things like ".count", ".avg", etc.
https://github.com/quipo/statsd/blob/master/bufferedclient.go#L147 is calling update because it thinks they are the same type since they are hashed only based on key and not based on type as well.
However, according to https://github.com/quipo/statsd/blob/master/event/precisiontiming.go#L23
they have to be of the same type - which makes sense here.
Currently, buffered client optimizes only at the level of each "key" being updated if many of them come before a flush happens.
However, SendEvent
is called for each key, and then an fmt.Fprintf(c.conn...)
for every stat in that event. This leads to quite a lot of udp traffic.
The statsd protocol supports sending more than one stat by separating by \n
. By doing so, we will reduce the number of fmt.Fprintf(c.conn...)
calls, thereby reducing udp traffic.
Neither CreateSocket() nor any of the metrics-generating methods (i.e. Timing(), Incr(), etc) return an error when there's no statsd listening on the address given when creating the client, as can be seen at the following gist: https://gist.github.com/gsalgado/07b8bec3e326582c7174
I'd expect them all to return an error in this case.
Hi
It would be great if you tagged the current HEAD with v1.0.0, and in the future, occasionally bump the version and make new tags with new releases. I suggest using the semver.org versioning scheme, where you have major.minor.patch, and you bump the major for incompatible changes and the minor for compatible changes to the API.
add sample rate support?
@quipo Can StatsdBuffer be used concurrently. Like in a production scenario if we create one instance of StatsdBuffer and use it across the code till the program exists, is it fine?
Gauge should set the metric to an absolute value but rather increments the previous value by the set value.
When statsdbuffer.Close()
is called, it dumps [BufferedStatsdClient] 2015/03/06 14:38:03 Asked to terminate. Flushing stats before returning.
out.
How do I prevent it from doing this?
In buffered client, if failed to createsocket or failed to send events due to connection errors, counters are being deleted in flush function.
It appears to be copied from the Gauge event, which does not look like the correct logic for GaugeDelta.
the code in event/precisiontiming.go has the String function calling the Payload function, and the payload function returns the precision timing object - this is causing infinite recursion.
package main
import "fmt"
type PrecisionTiming struct {
Name string
}
func (e PrecisionTiming) Payload() interface{} {
return e
}
func (e PrecisionTiming) String() string {
return fmt.Sprintf("{Value: %+v}", e.Payload())
}
func main() {
p := PrecisionTiming{}
fmt.Printf("%s\n", p)
}
Using StatsdBuffer
now breaks my app. Trying to compile:
*"github.com/quipo/statsd".StatsdBuffer does not implement "github.com/quipo/statsd".Statsd (missing CreateTCPSocket method)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.