initial version
[lwes-erlang.git] / src / lwes_event.erl
blobb317eb0f76d40959908509f6683af2ee600ee340
1 -module (lwes_event).
3 -include_lib ("lwes.hrl").
4 -include_lib ("lwes_internal.hrl").
6 -ifdef(HAVE_EUNIT).
7 -include_lib("eunit/include/eunit.hrl").
8 -endif.
10 %% API
11 -export([new/1,
12 set_uint16/3,
13 set_int16/3,
14 set_uint32/3,
15 set_int32/3,
16 set_uint64/3,
17 set_int64/3,
18 set_string/3,
19 set_ip_addr/3,
20 set_boolean/3,
21 to_binary/1,
22 from_udp_packet/2,
23 from_binary/2]).
25 %%====================================================================
26 %% API
27 %%====================================================================
28 new (Name) ->
29 #lwes_event { name = Name }.
31 set_int16 (E = #lwes_event { attrs = A }, K, V) when ?is_int16 (V) ->
32 E#lwes_event { attrs = [ { ?LWES_INT_16, K, V } | A ] }.
33 set_uint16 (E = #lwes_event { attrs = A }, K, V) when ?is_uint16 (V) ->
34 E#lwes_event { attrs = [ { ?LWES_U_INT_16, K, V } | A ] }.
35 set_int32 (E = #lwes_event { attrs = A}, K, V) when ?is_int32 (V) ->
36 E#lwes_event { attrs = [ { ?LWES_INT_32, K, V } | A ] }.
37 set_uint32 (E = #lwes_event { attrs = A}, K, V) when ?is_uint32 (V) ->
38 E#lwes_event { attrs = [ { ?LWES_U_INT_32, K, V } | A ] }.
39 set_int64 (E = #lwes_event { attrs = A}, K, V) when ?is_int64 (V) ->
40 E#lwes_event { attrs = [ { ?LWES_INT_64, K, V } | A ] }.
41 set_uint64 (E = #lwes_event { attrs = A}, K, V) when ?is_uint64 (V) ->
42 E#lwes_event { attrs = [ { ?LWES_U_INT_64, K, V } | A ] }.
43 set_boolean (E = #lwes_event { attrs = A}, K, V) when is_boolean (V) ->
44 E#lwes_event { attrs = [ { ?LWES_BOOLEAN, K, V } | A ] }.
45 set_string (E = #lwes_event { attrs = A}, K, V) when ?is_string (V) ->
46 E#lwes_event { attrs = [ { ?LWES_STRING, K, V } | A ] }.
47 set_ip_addr (E = #lwes_event { attrs = A}, K, V) ->
48 Ip = lwes_util:normalize_ip (V),
49 E#lwes_event { attrs = [ { ?LWES_IP_ADDR, K, Ip } | A ] }.
51 to_binary (#lwes_event { name = EventName, attrs = AttrList }) ->
52 NumAttrs = length (AttrList),
53 iolist_to_binary (
54 [ write_key (EventName),
55 <<NumAttrs:16/integer-unsigned-big>>,
56 write_attrs (AttrList, [])
60 from_udp_packet ({ udp, _Socket, SenderIP, SenderPort, Packet }, Format) ->
61 Extra =
62 case Format of
63 tagged ->
64 [ { ?LWES_IP_ADDR, <<"SenderIP">>, SenderIP },
65 { ?LWES_U_INT_16, <<"SenderPort">>, SenderPort },
66 { ?LWES_INT_64, <<"ReceiptTime">>, millisecond_since_epoch () } ];
67 _ ->
68 [ { <<"SenderIP">>, SenderIP },
69 { <<"SenderPort">>, SenderPort },
70 { <<"ReceiptTime">>, millisecond_since_epoch () } ]
71 end,
72 from_binary (Packet, Format, Extra).
74 from_binary (<<>>,_) ->
75 undefined;
76 from_binary (Binary,Format) ->
77 from_binary (Binary, Format, []).
79 %%====================================================================
80 %% Internal functions
81 %%====================================================================
83 from_binary (Binary, Format, Accum0) ->
84 <<Length:8/integer-unsigned-big,
85 EventName:Length/binary,
86 _NumAttrs:16/integer-unsigned-big,
87 Attrs/binary>> = Binary,
88 AttrList = read_attrs (Attrs, Format, Accum0),
89 #lwes_event { name = EventName, attrs = AttrList }.
91 type_to_atom (?LWES_TYPE_U_INT_16) -> ?LWES_U_INT_16;
92 type_to_atom (?LWES_TYPE_INT_16) -> ?LWES_INT_16;
93 type_to_atom (?LWES_TYPE_U_INT_32) -> ?LWES_U_INT_32;
94 type_to_atom (?LWES_TYPE_INT_32) -> ?LWES_INT_32;
95 type_to_atom (?LWES_TYPE_U_INT_64) -> ?LWES_U_INT_64;
96 type_to_atom (?LWES_TYPE_INT_64) -> ?LWES_INT_64;
97 type_to_atom (?LWES_TYPE_STRING) -> ?LWES_STRING;
98 type_to_atom (?LWES_TYPE_BOOLEAN) -> ?LWES_BOOLEAN;
99 type_to_atom (?LWES_TYPE_IP_ADDR) -> ?LWES_IP_ADDR.
101 millisecond_since_epoch () ->
102 {Meg, Sec, Mic} = os:timestamp(),
103 trunc (Meg * 1000000000 + Sec * 1000 + Mic / 1000).
105 write_attrs ([], Accum) ->
106 Accum;
107 write_attrs ([{T,K,V} | Rest], Accum) ->
108 write_attrs (Rest, [ write_key (K), write (T, V) | Accum ]);
109 write_attrs ([{K,V} | Rest], Accum) when ?is_int16 (V) ->
110 write_attrs (Rest, [ write_key (K), write (?LWES_INT_16, V) | Accum ]);
111 write_attrs ([{K,V} | Rest], Accum) when ?is_uint16 (V) ->
112 write_attrs (Rest, [ write_key (K), write (?LWES_U_INT_16, V) | Accum ]);
113 write_attrs ([{K,V} | Rest], Accum) when ?is_int32 (V) ->
114 write_attrs (Rest, [ write_key (K), write (?LWES_INT_32, V) | Accum ]);
115 write_attrs ([{K,V} | Rest], Accum) when ?is_uint32 (V) ->
116 write_attrs (Rest, [ write_key (K), write (?LWES_U_INT_32, V) | Accum ]);
117 write_attrs ([{K,V} | Rest], Accum) when ?is_int64 (V) ->
118 write_attrs (Rest, [ write_key (K), write (?LWES_INT_64, V) | Accum ]);
119 write_attrs ([{K,V} | Rest], Accum) when ?is_uint64 (V) ->
120 write_attrs (Rest, [ write_key (K), write (?LWES_U_INT_64, V) | Accum ]);
121 write_attrs ([{K,V} | Rest], Accum) when is_boolean (V) ->
122 write_attrs (Rest, [ write_key (K), write (?LWES_BOOLEAN, V) | Accum ]);
123 write_attrs ([{K,V} | Rest], Accum) when ?is_string (V) ->
124 write_attrs (Rest, [ write_key (K), write (?LWES_STRING, V) | Accum ]);
125 write_attrs ([{K,V = {_,_,_,_}} | Rest], Accum) when ?is_ip_addr (V) ->
126 write_attrs (Rest, [ write_key (K), write (?LWES_IP_ADDR, V) | Accum ]).
128 write_key (Key) when is_atom (Key) ->
129 write_key (atom_to_list (Key));
130 write_key (Key) ->
131 Len = iolist_size (Key),
132 [ <<Len:8/integer-unsigned-big>>, Key].
134 write (uint16, V) ->
135 <<?LWES_TYPE_U_INT_16:8/integer-unsigned-big, V:16/integer-unsigned-big>>;
136 write (int16, V) ->
137 <<?LWES_TYPE_INT_16:8/integer-unsigned-big, V:16/integer-signed-big>>;
138 write (uint32, V) ->
139 <<?LWES_TYPE_U_INT_32:8/integer-unsigned-big, V:32/integer-unsigned-big>>;
140 write (int32, V) ->
141 <<?LWES_TYPE_INT_32:8/integer-unsigned-big, V:32/integer-signed-big>>;
142 write (uint64, V) ->
143 <<?LWES_TYPE_U_INT_64:8/integer-unsigned-big, V:64/integer-unsigned-big>>;
144 write (int64, V) ->
145 <<?LWES_TYPE_INT_64:8/integer-unsigned-big, V:64/integer-signed-big>>;
146 write (ip_addr, {V1, V2, V3, V4}) ->
147 <<?LWES_TYPE_IP_ADDR:8/integer-unsigned-big,
148 V4:8/integer-unsigned-big,
149 V3:8/integer-unsigned-big,
150 V2:8/integer-unsigned-big,
151 V1:8/integer-unsigned-big>>;
152 write (boolean, true) ->
153 <<?LWES_TYPE_BOOLEAN:8/integer-unsigned-big, 1>>;
154 write (boolean, false) ->
155 <<?LWES_TYPE_BOOLEAN:8/integer-unsigned-big, 0>>;
156 write (string, V) when is_atom (V) ->
157 write (string, atom_to_list (V));
158 write (string, V) when is_list (V); is_binary (V) ->
159 SL = iolist_size (V),
160 [ <<?LWES_TYPE_STRING:8/integer-unsigned-big,
161 SL:16/integer-unsigned-big>>, V ].
163 read_attrs (<<>>, _Format, Accum) ->
164 Accum;
165 read_attrs (Bin, Format, Accum) ->
166 <<L:8/integer-unsigned-big, K:L/binary,
167 T:8/integer-unsigned-big, Vals/binary>> = Bin,
168 { V, Rest } = read_value (T, Vals),
169 read_attrs (Rest, Format,
170 [ case Format of
171 tagged -> {type_to_atom (T), K, V};
172 _ -> {K, V}
174 | Accum ]).
176 read_value (?LWES_TYPE_U_INT_16, Bin) ->
177 <<V:16/integer-unsigned-big, Rest/binary>> = Bin,
178 { V, Rest };
179 read_value (?LWES_TYPE_INT_16, Bin) ->
180 <<V:16/integer-signed-big, Rest/binary>> = Bin,
181 { V, Rest };
182 read_value (?LWES_TYPE_U_INT_32, Bin) ->
183 <<V:32/integer-unsigned-big, Rest/binary>> = Bin,
184 { V, Rest };
185 read_value (?LWES_TYPE_INT_32, Bin) ->
186 <<V:32/integer-signed-big, Rest/binary>> = Bin,
187 { V, Rest };
188 read_value (?LWES_TYPE_U_INT_64, Bin) ->
189 <<V:64/integer-unsigned-big, Rest/binary>> = Bin,
190 { V, Rest };
191 read_value (?LWES_TYPE_INT_64, Bin) ->
192 <<V:64/integer-signed-big, Rest/binary>> = Bin,
193 { V, Rest };
194 read_value (?LWES_TYPE_IP_ADDR, Bin) ->
195 <<V1:8/integer-unsigned-big,
196 V2:8/integer-unsigned-big,
197 V3:8/integer-unsigned-big,
198 V4:8/integer-unsigned-big, Rest/binary>> = Bin,
199 { {V4, V3, V2, V1}, Rest };
200 read_value (?LWES_TYPE_BOOLEAN, Bin) ->
201 <<V:8/integer-unsigned-big, Rest/binary>> = Bin,
202 { case V of 0 -> false; _ -> true end, Rest };
203 read_value (?LWES_TYPE_STRING, Bin) ->
204 <<SL:16/integer-unsigned-big, V:SL/binary, Rest/binary>> = Bin,
205 { V, Rest };
206 read_value (_, _) ->
207 throw (unknown_type).
209 %%====================================================================
210 %% Test functions
211 %%====================================================================
212 -ifdef(EUNIT).
214 -endif.