UNPKG

7.26 kBPlain TextView Raw
1%%
2%% Example erlang client implementation for the Etsy statsd
3%%
4%% Copyright (c) 2011-2012 Daniel Schauenberg, Sean Johnson
5%%
6%% Permission is hereby granted, free of charge, to any person
7%% obtaining a copy of this software and associated documentation
8%% files (the "Software"), to deal in the Software without
9%% restriction, including without limitation the rights to use,
10%% copy, modify, merge, publish, distribute, sublicense, and/or sell
11%% copies of the Software, and to permit persons to whom the
12%% Software is furnished to do so, subject to the following
13%% conditions:
14%%
15%% The above copyright notice and this permission notice shall be
16%% included in all copies or substantial portions of the Software.
17%%
18%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25%% OTHER DEALINGS IN THE SOFTWARE.
26%%
27%% Implements the following functions:
28%% increment(Stat) -> Increment the counter for the Stat by 1 with a 1.0 Sample Rate.
29%% increment(Stat, Amount) -> Increment the counter by the Amount for the Stat with a 1.0 Sample Rate.
30%% increment(Stat, Amount, SampleRate) -> Increment the counter for Stat by the Amount with the Sample Rate.
31%% decrement(Stat) -> Decrement the counter for the Stat by 1 with a 1.0 Sample Rate.
32%% decrement(Stat, Amount) -> Decrement the counter by the Amount for the Stat with a 1.0 Sample Rate.
33%% decrement(Stat, Amount, SampleRate) -> Decrement the counter for Stat by the Amount with the Sample Rate.
34%% timing(Stat, Time) -> Record a Time for the Stat with a 1.0 Sample Rate.
35%% timing(Stat, Time, SampleRate) -> Record Time for the Stat with the Sample Rate.
36%% gauge(Stat, Reading) -> Record a Reading of the Stat
37%%
38%% Run tests with:
39%% Run statsd with the parameters set in the -defines()
40%% % erlc -pa /path/to/eunit/ebin -DTEST -o.statsd.erl
41%% % erl -noshell -pa. -eval "eunit:test(statsd, [verbose])" -s init stop
42%%
43%%
44-module(statsd).
45% Meta information
46-author("Daniel Schauenberg <d@unwiredcouch.com>").
47-author("Sean Johnson <sean@talkto.com>").
48% defines
49-define(HOST, "localhost").
50-define(PORT, 8125).
51% exports
52-export([increment/1,increment/2,increment/3,
53 decrement/1, decrement/2, decrement/3,
54 timing/2, timing/3,
55 gauge/2]).
56
57%
58% API functions
59%
60
61% functions for incrementing counters
62increment(Stat) -> increment(Stat, 1, 1.0).
63increment(Stat, Delta) when is_integer(Delta) ->
64 increment(Stat, Delta, 1.0);
65increment(Stat, Samplerate) when is_float(Samplerate) ->
66 increment(Stat, 1, Samplerate).
67increment(Stat, Delta, Samplerate) when is_integer(Delta), is_float(Samplerate) ->
68 send({counter, Stat, Delta, Samplerate}).
69
70% functions for decrementing counters
71decrement(Stat) -> decrement(Stat, 1, 1.0).
72decrement(Stat, Delta) when is_integer(Delta) ->
73 decrement(Stat, Delta, 1.0);
74decrement(Stat, Samplerate) when is_float(Samplerate) ->
75 decrement(Stat, 1, Samplerate).
76decrement(Stat, Delta, Samplerate) when is_integer(Delta), is_float(Samplerate) ->
77 send({counter, Stat, -abs(Delta), Samplerate}).
78
79% functions for timing values
80timing(Stat, Time) when is_float(Time); is_integer(Time) ->
81 timing(Stat, Time, 1.0).
82timing(Stat, Time, Samplerate) when is_float (Time); is_integer(Time),
83 is_float(Samplerate) ->
84 send({timer, Stat, Time, Samplerate}).
85
86% functions for guages
87gauge(Stat, Reading) ->
88 send({gauge, Stat, Reading}).
89
90%
91% update functions
92%
93
94% recursive functions for multiple stats
95send({counter, [H|Stats], Delta, Samplerate}) ->
96 send({counter, H, Delta, Samplerate}),
97 send({counter, Stats, Delta, Samplerate});
98send({counter, [], _, _}) -> {ok, "Success."};
99
100send({timer, [H|Stats], Delta, Samplerate}) ->
101 send({timer, H, Delta, Samplerate}),
102 send({timer, Stats, Delta, Samplerate});
103send({timer, [], _, _}) -> {ok, "Success."};
104
105send({gauge, [H|Stats], Reading}) ->
106 send({gauge, H, Reading}),
107 send({gauge, Stats, Reading});
108send({gauge, [], _}) -> {ok, "Success."};
109
110% functions for single stats
111send({counter, Stat, Delta, Samplerate}) when Samplerate < 1.0, is_atom(Stat) ->
112 Rand = random:uniform(),
113 if
114 Rand =< Samplerate ->
115 send_udp_message(?HOST, ?PORT, io_lib:format("~p:~p|c|@~p",
116 [Stat, Delta, Samplerate]));
117 true -> {ok, "Success."}
118 end;
119
120send({counter, Stat, Delta, _}) ->
121 send_udp_message(?HOST, ?PORT, io_lib:format("~p:~p|c", [Stat, Delta]));
122
123send({timer, Stat, Time, Samplerate}) when Samplerate < 1.0 ->
124 Rand = random:uniform(),
125 if
126 Rand =< Samplerate ->
127 send_udp_message(?HOST, ?PORT, io_lib:format("~p:~p|ms|@~p",
128 [Stat, Time, Samplerate]));
129 true -> {ok, "Success."}
130 end;
131
132send({timer, Stat, Time, _}) ->
133 send_udp_message(?HOST, ?PORT, io_lib:format("~p:~p|ms", [Stat, Time]));
134
135send({gauge, Stat, Reading}) ->
136 send_udp_message(?HOST, ?PORT, io_lib:format("~p:~p|g", [Stat, Reading])).
137
138%
139% Raw UDP send message function
140%
141send_udp_message(Host, Port, Msg) when is_integer(Port),
142 is_list(Host) ->
143 {ok, Socket} = gen_udp:open(0, [binary]),
144 ok = gen_udp:send(Socket, Host, Port, Msg),
145 gen_udp:close(Socket),
146 {ok, "Success."}.
147
148%
149% unit tests
150%
151% EUnit headers
152-ifdef(TEST).
153-include_lib("eunit/include/eunit.hrl").
154% test functions go here
155increment_test_() ->
156 [?_assert(increment(stat1) =:= {ok, "Success."}),
157 ?_assert(increment(stat1, 1) =:= {ok, "Success."}),
158 ?_assert(increment(stat1, 1, 0.5) =:= {ok, "Success."}),
159 ?_assert(increment([stat1, stat2]) =:= {ok, "Success."}),
160 ?_assert(increment([stat1, stat2], 1) =:= {ok, "Success."}),
161 ?_assert(increment([stat1, stat2], 1, 0.5) =:= {ok, "Success."})
162 ].
163decrement_test_() ->
164 [?_assert(decrement(stat1) =:= {ok, "Success."}),
165 ?_assert(decrement(stat1, 1) =:= {ok, "Success."}),
166 ?_assert(decrement(stat1, -1) =:= {ok, "Success."}),
167 ?_assert(decrement(stat1, 1, 0.5) =:= {ok, "Success."}),
168 ?_assert(decrement([stat1, stat2]) =:= {ok, "Success."}),
169 ?_assert(decrement([stat1, stat2], 1) =:= {ok, "Success."}),
170 ?_assert(decrement([stat1, stat2], -1) =:= {ok, "Success."}),
171 ?_assert(decrement([stat1, stat2], 1, 0.5) =:= {ok, "Success."})
172 ].
173timing_test_() ->
174 [
175 ?_assert(timing(stat1, 100) =:= {ok, "Success."}),
176 ?_assert(timing(stat1, 100, 0.5) =:= {ok, "Success."}),
177 ?_assert(timing([stat1, stat2], 100) =:= {ok, "Success."}),
178 ?_assert(timing([stat1, stat2], 100, 0.5) =:= {ok, "Success."})
179 ].
180gauge_test_() ->
181 [
182 ?_assert(gauge(stat1, 100) =:= {ok, "Success."}),
183 ?_assert(gauge([stat1, stat2], 100) =:= {ok, "Success."})
184 ].
185
186-endif.
\No newline at end of file