Skip to content

Commit

Permalink
Merge 258b9e3 into b0beb37
Browse files Browse the repository at this point in the history
  • Loading branch information
lpgauth committed Nov 5, 2016
2 parents b0beb37 + 258b9e3 commit 1d5c1e3
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 91 deletions.
Binary file modified bin/rebar3
Binary file not shown.
5 changes: 3 additions & 2 deletions include/statsderl.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
-type base_key() :: base_key_part() | [base_key_part()].
-type base_key_part() :: hostname | name | sname | undefined | iodata().
-type key() :: iodata().
-type op_code() :: decrement | gauge | gauge_decrement | gauge_increment |
increment | timing.
-type op() :: term().
-type op_code() :: counter | gauge | gauge_decrement | gauge_increment |
timing | timing_now | timing_now_us.
-type sample_rate() :: number().
-type value() :: number().

8 changes: 7 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{cover_export_enabled, true}.
{cover_excl_mods, [
statsderl_debug,
statsderl_profile,
statsderl_tests,
statsderl_transform,
statsderl_utils_tests
]}.
{coveralls_coverdata, "_build/test/cover/eunit.coverdata"}.
{coveralls_service_name, "travis-ci"}.

{deps, [
{granderl, ".*",
{git, "https://github.com/tokenrove/granderl.git", {tag, "v0.1.4"}}}
{git, "https://github.com/tokenrove/granderl.git", {tag, "v0.1.4"}}},
{parse_trans, ".*",
{git, "https://github.com/uwiger/parse_trans.git", {tag, "3.0.0"}}}
]}.

{edoc_opts, [
Expand All @@ -22,6 +26,8 @@
{title, "statsderl"}
]}.

{erl_first_files, ["src/statsderl_transform.erl"]}.

{erl_opts, [
debug_info,
{platform_define, "19", 'UDP_HEADER'}
Expand Down
4 changes: 4 additions & 0 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
[{<<"granderl">>,
{git,"https://github.com/tokenrove/granderl.git",
{ref,"b44725cdd3ae6d2d4170e0d72ebb2fcad98d5ad2"}},
0},
{<<"parse_trans">>,
{git,"https://github.com/uwiger/parse_trans.git",
{ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}},
0}].
86 changes: 20 additions & 66 deletions src/statsderl.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,108 +22,62 @@
-spec counter(key(), value(), sample_rate()) ->
ok.

counter(Key, Value, SampleRate) ->
sample(counter, Key, Value, SampleRate).
counter(Key, Value, Rate) ->
statsderl_pool:sample(Rate, {counter, Key, Value, Rate}).

-spec decrement(key(), value(), sample_rate()) ->
ok.

decrement(Key, Value, SampleRate) when Value >= 0 ->
sample(counter, Key, -Value, SampleRate).
decrement(Key, Value, Rate) when Value >= 0 ->
statsderl_pool:sample(Rate, {counter, Key, -Value, Rate}).

-spec gauge(key(), value(), sample_rate()) ->
ok.

gauge(Key, Value, SampleRate) when Value >= 0 ->
sample(gauge, Key, Value, SampleRate).
gauge(Key, Value, Rate) when Value >= 0 ->
statsderl_pool:sample(Rate, {gauge, Key, Value}).

-spec gauge_decrement(key(), value(), sample_rate()) ->
ok.

gauge_decrement(Key, Value, SampleRate) when Value >= 0 ->
sample(gauge_decrement, Key, Value, SampleRate).
gauge_decrement(Key, Value, Rate) when Value >= 0 ->
statsderl_pool:sample(Rate, {gauge_decrement, Key, Value}).

-spec gauge_increment(key(), value(), sample_rate()) ->
ok.

gauge_increment(Key, Value, SampleRate) when Value >= 0 ->
sample(gauge_increment, Key, Value, SampleRate).
gauge_increment(Key, Value, Rate) when Value >= 0 ->
statsderl_pool:sample(Rate, {gauge_increment, Key, Value}).

-spec increment(key(), value(), sample_rate()) ->
ok.

increment(Key, Value, SampleRate) when Value >= 0 ->
sample(counter, Key, Value, SampleRate).
increment(Key, Value, Rate) when Value >= 0 ->
statsderl_pool:sample(Rate, {counter, Key, Value, Rate}).

-spec timing(key(), value(), sample_rate()) ->
ok.

timing(Key, Value, SampleRate) ->
sample(timing, Key, Value, SampleRate).
timing(Key, Value, Rate) ->
statsderl_pool:sample(Rate, {timing, Key, Value}).

-spec timing_fun(key(), fun(), sample_rate()) ->
ok.

timing_fun(Key, Fun, SampleRate) ->
timing_fun(Key, Fun, Rate) ->
Timestamp = statsderl_utils:timestamp(),
Result = Fun(),
timing_now(Key, Timestamp, SampleRate),
timing_now(Key, Timestamp, Rate),
Result.

-spec timing_now(key(), erlang:timestamp(), sample_rate()) ->
ok.

timing_now(Key, Timestamp, SampleRate) ->
sample(timing_now, Key, Timestamp, SampleRate).
timing_now(Key, Timestamp, Rate) ->
statsderl_pool:sample(Rate, {timing_now, Key, Timestamp}).

-spec timing_now_us(key(), erlang:timestamp(), sample_rate()) ->
ok.

timing_now_us(Key, Timestamp, SampleRate) ->
sample(timing_now_us, Key, Timestamp, SampleRate).

%% private
cast(OpCode, Key, Value, SampleRate, ServerName) ->
Packet = statsderl_protocol:encode(OpCode, Key, Value, SampleRate),
send(ServerName, {cast, Packet}).

operation(OpCode, Key, Value, SampleRate) ->
ServerName = statsderl_utils:random_server(),
operation(OpCode, Key, Value, SampleRate, ServerName).

operation(timing_now, Key, Value, SampleRate, ServerName) ->
cast(timing, Key, timing_now(Value), SampleRate, ServerName);
operation(timing_now_us, Key, Value, SampleRate, ServerName) ->
cast(timing, Key, timing_now_us(Value), SampleRate, ServerName);
operation(OpCode, Key, Value, SampleRate, ServerName) ->
cast(OpCode, Key, Value, SampleRate, ServerName).

sample(OpCode, Key, Value, 1) ->
operation(OpCode, Key, Value, 1);
sample(OpCode, Key, Value, 1.0) ->
operation(OpCode, Key, Value, 1);
sample(OpCode, Key, Value, SampleRate) ->
Rand = statsderl_utils:random(?MAX_UNSIGNED_INT_32),
case Rand =< SampleRate * ?MAX_UNSIGNED_INT_32 of
true ->
N = Rand rem ?POOL_SIZE + 1,
ServerName = statsderl_utils:server_name(N),
operation(OpCode, Key, Value, SampleRate, ServerName);
false ->
ok
end.

send(ServerName, Msg) ->
case whereis(ServerName) of
undefined ->
ok;
Pid ->
Pid ! Msg
end.

timing_now(Timestamp) ->
timing_now_us(Timestamp) div 1000.

timing_now_us(Timestamp) ->
Timestamp2 = statsderl_utils:timestamp(),
timer:now_diff(Timestamp2, Timestamp).
timing_now_us(Key, Timestamp, Rate) ->
statsderl_pool:sample(Rate, {timing_now_us, Key, Timestamp}).
24 changes: 24 additions & 0 deletions src/statsderl_debug.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-module(statsderl_debug).

-compile({parse_transform, statsderl_transform}).

-export([test/0]).

-spec test() -> ok.

test() ->
A = <<"my_key">>,
B = 10,
C = 0.666,

statsderl:counter(["hello", <<"world">>], -1, 0.5),
statsderl:counter(["hello", A], 1, 0.5),
statsderl:counter(["hello", <<"world">>], B, 0.5),
statsderl:counter(["hello", <<"world">>], 1, C),

statsderl:gauge(["hello", <<"world">>], 1, 0.5),
statsderl:gauge(["hello", A], 1, 0.5),
statsderl:gauge(["hello", <<"world">>], B, 0.5),
statsderl:gauge(["hello", <<"world">>], 1, C),

ok.
70 changes: 70 additions & 0 deletions src/statsderl_pool.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
-module(statsderl_pool).
-include("statsderl.hrl").

-compile(inline).
-compile({inline_size, 512}).

-export([
sample/2,
sample_scaled/2,
server_name/1
]).

%% public
-spec sample(sample_rate(), op()) -> ok.

sample(1, Op) ->
operation(Op);
sample(1.0, Op) ->
operation(Op);
sample(Rate, Op) ->
RateInt = trunc(Rate * ?MAX_UNSIGNED_INT_32),
sample_scaled(RateInt, Op).

-spec sample_scaled(non_neg_integer(), op()) -> ok.

sample_scaled(RateInt, Op) ->
Rand = statsderl_utils:random(?MAX_UNSIGNED_INT_32),
case Rand =< RateInt of
true ->
N = Rand rem ?POOL_SIZE + 1,
operation(Op, server_name(N));
false ->
ok
end.

-spec server_name(1..4) -> atom().

server_name(1) -> statsderl_1;
server_name(2) -> statsderl_2;
server_name(3) -> statsderl_3;
server_name(4) -> statsderl_4.

%% private
cast({cast, _} = Cast, ServerName) ->
send(ServerName, Cast);
cast(Op, ServerName) ->
send(ServerName, {cast, statsderl_protocol:encode(Op)}).

operation(Op) ->
operation(Op, random_server()).

operation({timing_now, Key, Value}, ServerName) ->
Value2 = statsderl_utils:timing_now(Value),
cast({timing, Key, Value2}, ServerName);
operation({timing_now_us, Key, Value}, ServerName) ->
Value2 = statsderl_utils:timing_now_us(Value),
cast({timing, Key, Value2}, ServerName);
operation(Op, ServerName) ->
cast(Op, ServerName).

random_server() ->
server_name(statsderl_utils:random(?POOL_SIZE)).

send(ServerName, Msg) ->
case whereis(ServerName) of
undefined ->
ok;
Pid ->
Pid ! Msg
end.
14 changes: 7 additions & 7 deletions src/statsderl_protocol.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
-compile({inline_size, 512}).

-export([
encode/4
encode/1
]).

%% public
-spec encode(op_code(), key(), value(), sample_rate()) -> iodata().
-spec encode({op_code(), key(), value(), sample_rate()}) -> iodata().

encode(counter, Key, Value, SampleRate) ->
encode({counter, Key, Value, SampleRate}) ->
[Key, <<":">>, format_value(Value), <<"|c">>,
format_sample_rate(SampleRate)];
encode(gauge, Key, Value, _SampleRate) ->
encode({gauge, Key, Value}) ->
[Key, <<":">>, format_value(Value), <<"|g">>];
encode(gauge_decrement, Key, Value, _SampleRate) ->
encode({gauge_decrement, Key, Value}) ->
[Key, <<":-">>, format_value(Value), <<"|g">>];
encode(gauge_increment, Key, Value, _SampleRate) ->
encode({gauge_increment, Key, Value}) ->
[Key, <<":+">>, format_value(Value), <<"|g">>];
encode(timing, Key, Value, _SampleRate) ->
encode({timing, Key, Value}) ->
[Key, <<":">>, format_value(Value), <<"|ms">>].

%% private
Expand Down
2 changes: 1 addition & 1 deletion src/statsderl_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ init(_Args) ->
child_specs(0) ->
[];
child_specs(N) ->
Name = statsderl_utils:server_name(N),
Name = statsderl_pool:server_name(N),
[?CHILD(Name, ?SERVER) | child_specs(N - 1)].
Loading

0 comments on commit 1d5c1e3

Please sign in to comment.