Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote-tracking branch 'etsy/master'

  • Loading branch information...
commit 3f6b96b7301a881d979ff201dcf860e01ba05798 2 parents 4e4ed79 + 42ff275
@jeffminard-ck authored
View
8 README.md
@@ -225,6 +225,11 @@ Inspiration
StatsD was inspired (heavily) by the project (of the same name) at Flickr. Here's a post where Cal Henderson described it in depth:
[Counting and timing](http://code.flickr.com/blog/2008/10/27/counting-timing/). Cal re-released the code recently: [Perl StatsD](https://github.com/iamcal/Flickr-StatsD)
+Meta
+---------
+- IRC channel: `#statsd` on freenode
+- Mailing list: `statsd@librelist.com`
+
Contribute
---------------------
@@ -242,6 +247,7 @@ fork StatsD from here: http://github.com/etsy/statsd
We'll do our best to get your changes in!
+
[graphite]: http://graphite.wikidot.com
[etsy]: http://www.etsy.com
[blog post]: http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/
@@ -254,4 +260,4 @@ Contributors
-----------------
In lieu of a list of contributors, check out the commit history for the project:
-http://github.com/etsy/statsd/commits/master
+https://github.com/etsy/statsd/graphs/contributors
View
22 backends/graphite.js
@@ -72,6 +72,12 @@ var flush_stats = function graphite_flush(ts, metrics) {
var min = values[0];
var max = values[count - 1];
+ var cumulativeValues = [min];
+ for (var i = 1; i < count; i++) {
+ cumulativeValues.push(values[i] + cumulativeValues[i-1]);
+ }
+
+ var sum = min;
var mean = min;
var maxAtThreshold = max;
@@ -84,15 +90,9 @@ var flush_stats = function graphite_flush(ts, metrics) {
if (count > 1) {
var thresholdIndex = Math.round(((100 - pct) / 100) * count);
var numInThreshold = count - thresholdIndex;
- var pctValues = values.slice(0, numInThreshold);
- maxAtThreshold = pctValues[numInThreshold - 1];
-
- // average the remaining timings
- var sum = 0;
- for (var i = 0; i < numInThreshold; i++) {
- sum += pctValues[i];
- }
+ maxAtThreshold = values[numInThreshold - 1];
+ sum = cumulativeValues[numInThreshold - 1];
mean = sum / numInThreshold;
}
@@ -100,11 +100,17 @@ var flush_stats = function graphite_flush(ts, metrics) {
clean_pct.replace('.', '_');
message += 'stats.timers.' + key + '.mean_' + clean_pct + ' ' + mean + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper_' + clean_pct + ' ' + maxAtThreshold + ' ' + ts + "\n";
+ message += 'stats.timers.' + key + '.sum_' + clean_pct + ' ' + sum + ' ' + ts + "\n";
}
+ sum = cumulativeValues[count-1];
+ mean = sum / count;
+
message += 'stats.timers.' + key + '.upper ' + max + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.lower ' + min + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.count ' + count + ' ' + ts + "\n";
+ message += 'stats.timers.' + key + '.sum ' + sum + ' ' + ts + "\n";
+ message += 'stats.timers.' + key + '.mean ' + mean + ' ' + ts + "\n";
statString += message;
numStats += 1;
View
4 examples/Etsy/StatsD.pm
@@ -99,7 +99,7 @@ sub send {
my $sampled_data;
if ( defined($sample_rate) and $sample_rate < 1 ){
- while (my($stat,$value) = each %$sampled_data) {
+ while (my($stat,$value) = each %$data) {
$sampled_data->{$stat} = "$value|\@$sample_rate" if rand() <= $sample_rate;
}
} else {
@@ -124,4 +124,4 @@ Steve Sanbeg L<http://www.buzzfeed.com/stv>
=cut
-1;
+1;
View
1  examples/README.md
@@ -11,6 +11,7 @@ Here's a bunch of example code contributed by the communinty for interfacing wit
python_example.py - Python
ruby_example.rb - Ruby
statsd.erl - Erlang
+ statsd-client.sh - Bash
Third Party StatsD Libraries
============================
View
4 examples/python_example.py
@@ -72,7 +72,7 @@ def send(data, sample_rate=1):
import random
if random.random() <= sample_rate:
for stat in data.keys():
- value = sampled_data[stat]
+ value = data[stat]
sampled_data[stat] = "%s|@%s" %(value, sample_rate)
else:
sampled_data=data
@@ -81,7 +81,7 @@ def send(data, sample_rate=1):
udp_sock = socket(AF_INET, SOCK_DGRAM)
try:
for stat in sampled_data.keys():
- value = data[stat]
+ value = sampled_data[stat]
send_data = "%s:%s" % (stat, value)
udp_sock.sendto(send_data, addr)
except:
View
25 examples/statsd-client.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Very simple bash client to send metrics to a statsd server
+# Example with gauge: ./statsd-client.sh 'my_metric:100|g'
+#
+# Alexander Fortin <alexander.fortin@gmail.com>
+#
+STATSD="statsd-ip-address"
+PORT="8125"
+
+if [ $# -ne 1 ]
+then
+ echo "Syntax: $0 '<gauge_data_for_statsd>'"
+ exit 1
+fi
+
+# Setup UDP socket with statsd server
+exec 3<> /dev/udp/${STATSD}/${PORT}
+
+# Send data
+echo "$1" >&3
+
+# Close UDP socket
+exec 3<&-
+exec 3>&-
View
76 stats.js
@@ -85,47 +85,51 @@ config.configFile(process.argv[2], function (config, oldConfig) {
var keyFlushInterval = Number((config.keyFlush && config.keyFlush.interval) || 0);
server = dgram.createSocket('udp4', function (msg, rinfo) {
- if (config.dumpMessages) { util.log(msg.toString()); }
- var bits = msg.toString().split(':');
- var key = bits.shift()
- .replace(/\s+/g, '_')
- .replace(/\//g, '-')
- .replace(/[^a-zA-Z_\-0-9\.]/g, '');
-
- if (keyFlushInterval > 0) {
- if (! keyCounter[key]) {
- keyCounter[key] = 0;
+ var metrics = msg.toString().split("\n");
+
+ for (midx in metrics) {
+ if (config.dumpMessages) { util.log(metrics[midx].toString()); }
+ var bits = metrics[midx].toString().split(':');
+ var key = bits.shift()
+ .replace(/\s+/g, '_')
+ .replace(/\//g, '-')
+ .replace(/[^a-zA-Z_\-0-9\.]/g, '');
+
+ if (keyFlushInterval > 0) {
+ if (! keyCounter[key]) {
+ keyCounter[key] = 0;
+ }
+ keyCounter[key] += 1;
}
- keyCounter[key] += 1;
- }
- if (bits.length == 0) {
- bits.push("1");
- }
-
- for (var i = 0; i < bits.length; i++) {
- var sampleRate = 1;
- var fields = bits[i].split("|");
- if (fields[1] === undefined) {
- util.log('Bad line: ' + fields);
- stats['messages']['bad_lines_seen']++;
- continue;
+ if (bits.length == 0) {
+ bits.push("1");
}
- if (fields[1].trim() == "ms") {
- if (! timers[key]) {
- timers[key] = [];
- }
- timers[key].push(Number(fields[0] || 0));
- } else if (fields[1].trim() == "g") {
- gauges[key] = Number(fields[0] || 0);
- } else {
- if (fields[2] && fields[2].match(/^@([\d\.]+)/)) {
- sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);
+
+ for (var i = 0; i < bits.length; i++) {
+ var sampleRate = 1;
+ var fields = bits[i].split("|");
+ if (fields[1] === undefined) {
+ util.log('Bad line: ' + fields);
+ stats['messages']['bad_lines_seen']++;
+ continue;
}
- if (! counters[key]) {
- counters[key] = 0;
+ if (fields[1].trim() == "ms") {
+ if (! timers[key]) {
+ timers[key] = [];
+ }
+ timers[key].push(Number(fields[0] || 0));
+ } else if (fields[1].trim() == "g") {
+ gauges[key] = Number(fields[0] || 0);
+ } else {
+ if (fields[2] && fields[2].match(/^@([\d\.]+)/)) {
+ sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);
+ }
+ if (! counters[key]) {
+ counters[key] = 0;
+ }
+ counters[key] += Number(fields[0] || 1) * (1 / sampleRate);
}
- counters[key] += Number(fields[0] || 1) * (1 / sampleRate);
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.