/
statsderl_server.erl
85 lines (70 loc) · 1.96 KB
/
statsderl_server.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
-module(statsderl_server).
-include("statsderl.hrl").
-compile(inline).
-compile({inline_size, 512}).
-export([
start_link/1
]).
-behaviour(metal).
-export([
init/3,
handle_msg/2,
terminate/2
]).
-record(state, {
header :: iodata(),
socket :: inet:socket()
}).
%% public
-spec start_link(atom()) ->
{ok, pid()}.
start_link(Name) ->
metal:start_link(?SERVER, Name, undefined).
%% metal callbacks
-spec init(atom(), pid(), term()) ->
{ok, term()} | {stop, atom()}.
init(_Name, _Parent, _Opts) ->
BaseKey = ?ENV(?ENV_BASEKEY, ?DEFAULT_BASEKEY),
Hostname = ?ENV(?ENV_HOSTNAME, ?DEFAULT_HOSTNAME),
Port = ?ENV(?ENV_PORT, ?DEFAULT_PORT),
case udp_header(Hostname, Port, BaseKey) of
{ok, Header} ->
case gen_udp:open(0, [{active, false}]) of
{ok, Socket} ->
{ok, #state {
socket = Socket,
header = Header
}};
{error, Reason} ->
{stop, Reason}
end;
{error, Reason} ->
{stop, Reason}
end.
-spec handle_msg(term(), term()) ->
{ok, term()}.
handle_msg({cast, Packet}, #state {
header = Header,
socket = Socket
} = State) ->
erlang:port_command(Socket, [Header, Packet]),
{ok, State};
handle_msg({inet_reply, _Socket, ok}, State) ->
{ok, State};
handle_msg({inet_reply, _Socket, {error, Reason}}, State) ->
statsderl_utils:error_msg("inet_reply error: ~p~n", [Reason]),
{ok, State}.
-spec terminate(term(), term()) ->
ok.
terminate(_Reason, _State) ->
ok.
%% private
udp_header(Hostname, Port, BaseKey) ->
case statsderl_utils:getaddrs(Hostname) of
{ok, {A, B, C, D}} ->
Header = statsderl_udp:header({A, B, C, D}, Port),
BaseKey2 = statsderl_utils:base_key(BaseKey),
{ok, [Header, BaseKey2]};
{error, Reason} ->
{error, Reason}
end.