Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c937020
Updates: don't serialize through process, use "double buffer" methodo…
Jul 20, 2012
bd35779
Support a master node, which aggregates stats
Jul 25, 2012
6686af9
Fixes for master node implementation
Jul 25, 2012
5a30041
Add UDP server support
Nov 29, 2012
e012987
Basic protocol implementation
Nov 29, 2012
085fc79
Remove unused files.
Nov 29, 2012
a9d2333
estatsd cluster upgrade
Dec 4, 2012
b821905
Utils necessary for the previous patch
Dec 4, 2012
1a37bbc
Also, the header file with necessary definitions
Dec 4, 2012
d6d98fa
Include release directory
Dec 6, 2012
683886b
Include rebar.config too!
Dec 6, 2012
4eb22cc
R15B compatibility fixes
Dec 6, 2012
ce1a1a6
Default destination; no default peers
Dec 6, 2012
a21a81f
Correcting version.
Dec 6, 2012
873b4bd
Tagging support.
Dec 20, 2012
ff1ffbb
Fix: vm_metrics reporting when disabled
Dec 21, 2012
aa8e544
Warning cleanup
Dec 21, 2012
f4cd8ad
Update version: 1.0.0 -> 1.1.0
Dec 21, 2012
0907530
Make TCP ports configurable.
Dec 21, 2012
e170e4b
Fix: vm metric keys should be atoms
Jan 10, 2013
9b18b15
Fixed handling of ranch, it's now a dep instead of manually started.
Licenser Jan 20, 2013
4d8346b
Removed rel file so this can live happiely in another applicaiton.
Licenser Jan 20, 2013
daf5305
Merge pull request #2 from Licenser/master
soup-in-boots Jan 21, 2013
57ebfbb
Standalone service instructions
soup-in-boots Jan 21, 2013
fd83160
Support sample rates on counters
Feb 12, 2013
e00ddb0
Release: 1.1.4
Feb 12, 2013
43fbbdf
Bug fixes
Feb 13, 2013
1f9a382
Use same tree structures as newer statsd servers
Feb 13, 2013
69ebaed
Optimize timings
Mar 25, 2013
e994e4f
Correct parsing and aggregation for new timer methods
Mar 25, 2013
1f4c6ce
Minor bugfix
Mar 26, 2013
1f067a6
Release: 1.2.1
Mar 26, 2013
f477137
Release 1.2.2
Mar 27, 2013
8963198
Update README.txt
soup-in-boots Mar 28, 2013
993d946
Rename README.txt to README.md
soup-in-boots Mar 28, 2013
2fc5c13
Update README.md
soup-in-boots Mar 28, 2013
0d6b696
Segment support
soup-in-boots Jul 31, 2013
b9f86d3
Fix gauge accumulation
Oct 28, 2013
abcb865
Whitespace cleanup
Oct 28, 2013
8ce7bb0
RELEASE 1.3.1
Oct 28, 2013
8a5a885
Update ranch from 0.4.0 to 0.8.4
Nov 22, 2013
d403c22
RELEASE 1.3.2
Nov 22, 2013
a662f56
Enable timing samples via UDP protocol
Jan 3, 2014
d45c5f9
RELEASE 1.3.3
Jan 3, 2014
d06998f
RELEASE 1.3.4
May 13, 2014
f25af05
Add support for HTTP post for HostedGraphite
Jan 19, 2015
ee107f8
Support floats for timing values over UDP
Jan 19, 2015
a892ddc
code_change header was off
Jan 19, 2015
1c9deb2
RELEASE 1.3.5
Jan 19, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ebin
.*
*.app
*.beam
*~
erl_crash.dump
124 changes: 124 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
ESTATSD
==========
StatsD, a tool developed by etsy to track statistics, has become incredibly popular in web services
for its ease of use and its numerous appliactions. estatsd, a project initially created by Richard Jones,
was an attempt to develop a StatsD server as an Erlang application for easy integration with other Erlang
projects.

With 37 forks at the time of this writing, there's no shortage of usable variants of estatsd. What sets this one
apart from the others is its emphasis on distribution and scalability.

This flavor of estatsd is designed to run on multiple systems within a local network, across datacenters, as
a single embedded application, or a standalone UDP server. This allows you to *horizontally scale* your statsd
setup with the rest of your service.

HOW IT WORKS
==========
estatsd works on the concept of a cluster, or a local network, and uses Erlang's built-in support for distribrution
towards this end. Data being tracked by servers in the cluster is aggregated to a single, elected server (using
gen_leader; this election process makes the service more resilient in the case of network or server failure), and
is then sent on to its destination.

estatsd supports 3 types of destinations now and can easily be extended to target more. The types are:

1. graphite (of course) - The standard StatsD/estatsd endpoint
2. estatsd_tcp - A JSON-based aggregation protocol
3. estatsd_tcpz - Similar to estatsd_tcp, but also uses zlib to compress messages when sending

Using the estatsd_tcp and estatsd_tcpz protocols you can easily aggregate statistics from multiple datcenters into
a single graphite instance without the increased risk of lost messages that comes with UDP-repeater setups.

AND THERE'S MORE
=========
Tagging. You can apply arbitrary tags to keys (based on a regular expression) at two points: the node level, before
the stats are aggregated to the local network's master, or the cluster level, before the stats are forwarded to the
specified destination.

That's a little vague, so here's an example:

% /etc/estatsd/cluster.config
[
{estatsd, [
{cluster_tagging, [
{".*", copy, prefix, "my_dc_a"},
{".*", replace, prefix, "my_product"}
]}
]}
]

Suppose you have a statistic, foo, that you're tracking. When estatsd sends this data on to its destination, you'll
receive two metrics instead of one.

my_product.my_dc_a.foo 27
my_product.foo 27

Suppose you had another datacenter, my_dc_b, that was also sending data, but with the tag my_dc_b. You'll receive two
two metrics again.

my_product.my_dc_b.foo 23
my_product.foo 23

See where I'm going with this yet? Assuming that your destination is another estatsd instance, these stats will be
aggregated, and you'll be left with *3* keys:

my_product.my_dc_a.foo 27
my_product.my_dc_b.foo 23
my_product.foo 50

Intrigued yet?

QUICK DEMO
==========

1. Install and configure graphite (quick-ish)
2. Install rebar, have it in your path
3. rebar compile
4. erl -pa ebin
5. > application:start(estatsd).
> estatsd:increment(foo, 123).
6. Observe graphite now has 1 data point.

STANDALONE SERVICE
==========

Use [estatsd_server](https://github.com/fauxsoup/estatsd_server) to generate a standalone version of estatsd.

USAGE
=====

Add this app to your rebar deps, and make sure it's started somehow
eg: application:start(estatsd).

You can configure custom graphite host/port and flush interval using
application environment vars. See estatsd_sup for details.

The following calls to estatsd are all gen_server:cast, ie non-blocking.

Gauges
--------

estatsd:gauge(temperature, 45). %% set temperature to 45

Counters
--------

estatsd:increment(num_foos). %% increment num_foos by one

estatsd:decrement(<<"num_bars">>, 3). %% decrement num_bars by 3

estatsd:increment("tcp.bytes_in", 512). %% increment tcp.bytes_in by 512

Timers
------

estatsd:timing(sometask, 1534). %% report that sometask took 1534ms

Or for your convenience:

Start = erlang:now(),
do_sometask(),
estatsd:timing(sometast, Start). %% uses now() and now_diff for you



Soup <fauxsoup@gmail.com>
68 changes: 0 additions & 68 deletions README.txt

This file was deleted.

30 changes: 30 additions & 0 deletions ebin/estatsd.appup
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{"1.3.5", [
{"1.3.4", [
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]},
{"1.3.3", [
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]},
{"1.3.2", [
{load_module, estatsd},
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]}
],
[
{"1.3.4", [
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]},
{"1.3.3", [
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]},
{"1.3.2", [
{load_module, estatsd},
{update, estatsd_listener},
{update, estatsd_server, {advanced, []}}
]}
]}.
4 changes: 4 additions & 0 deletions include/estatsd.hrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-ifndef(ESTATSD_H).
-define(ESTATSD_H, 1).
-define(COMPILE_ONCE(RX), ct_expand:term((fun() -> {ok, Compiled} = re:compile(RX), Compiled end)())).
-endif.
8 changes: 8 additions & 0 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{sub_dirs, ["rel"]}.
{deps, [
{parse_trans, ".*", {git, "https://github.com/uwiger/parse_trans.git", {tag, "2.5.3"}}},
{gen_leader, ".*", {git, "https://github.com/garret-smith/gen_leader_revival.git", {branch, "master"}}},
{jiffy, ".*", {git, "https://github.com/davisp/jiffy.git", {tag, "0.8.5"}}},
{ranch, ".*", {git, "https://github.com/extend/ranch.git", {tag, "0.8.4"}}},
{ibrowse, ".*", {git, "https://github.com/cmullaparthi/ibrowse.git", {tag, "v4.0.2"}}}
]}.
6 changes: 4 additions & 2 deletions src/estatsd.app.src
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{application, estatsd,
[
{description, "Stats aggregation service that writes to graphite"},
{vsn, "1.0"},
{vsn, "1.3.5"},
{registered, []},
{applications, [
kernel,
stdlib
stdlib,
ranch,
ibrowse
]},
{mod, { estatsd_app, []}},
{env, []}
Expand Down
Loading