added link to Ruby docs
[lwes-website.git] / specs / lwes-v1
blobecb041c9ae15b0bfdc1c7e68b6775a415e4c531b
1 LWES V1.0
3 LWES Core Changes
5 1. Goals
6     - additional types
7       - byte
8       - float
9       - double
10       - ipv4
11     - containers of sorts
12       - arrays
13     - capacity planning
14       - maximum size of event should be able to be determined from esf alone
15     - backward compatibility for serialization (ie, be able to deserialize
16       old events with new library).
17     - string maximum sizes
18     - required/optional fields
20 2. ESF changes
21     1. new string type includes a maximum length specified as (\d+) like
22        string(10), the (\d+) is optional, with a default of 65535 which is
23        large but what is used in the old versions.  This will allow older
24        ESFs to work without modification
25     2. required fields must be set at emission time, optional fields may not
26     3. byte type is new
27     4. arrays are specified by adding [\d+] after the type, the number is the
28        maximum length
29     5. default values can be set for base types and arrays of base types
31   Example ESF
33     MetaEventInfo
34     {
35       required   ip_addr          SenderIP;
36       required   uint16           SenderPort
37       required   int64            ReceiptTime;
38       required   string(10)       version = "25.1.6";   # esf version number
39       optional   uint16           SiteID;
40       optional   string(10)       st;
41     }
43     Event
44     {
45       required   boolean          aBool;
46       required   byte             aByte;
47       required   uint16           aUInt16;
48       required   int16            anInt16;
49       required   uint32           aUInt32;
50       required   int32            anInt32;
51       required   uint64           aUInt64;
52       required   int64            anInt64;
53       required   string(10)       aString;
54       required   ip_addr          anIPAddr; # deprecated
55       required   ipv4             ipv4Addr; # ipv4 with better marshalling
56       required   float            aFloat;   # we might as well support it
57       required   double           aDouble;  # this as well
59       required   boolean[10]      aBoolArray;
60       required   byte[10]         aByteArray;
61       required   uint16[10]       aUInt16Array;
62       required   int16[10]        anInt16Array;
63       required   uint32[10]       aUInt32Array;
64       required   int32[10]        anInt32Array;
65       required   uint64[10]       aUInt64Array;
66       required   int64[10]        anInt64Array;
67       required   string(10)[10]   aStringArray;
68       required   ip_addr[10]      anIPAddrArray;
70       optional   string(10)       anotherString;
72       # since this field is defaulted it will always be set at event
73       # creation time to the default value, and thus always be
74       # sent so being optional doesn't really matter
75       optional   boolean          defaultBoolean    = true;  # false also
76       optional   byte             defaultByte       = 5;
77       optional   string(5)        defaultedString   = "foo";
78       optional   int[5]           defaultedIntArray = { 1, 2, 3, 4, 5 };
79     }
81   Defaults
82     - default to optional if not set (for backwards compatibility, but
83       planning on leaving in place).
84     - string max defaults to 65535 if not set (may deprecate and require
85       length in future versions), if not set the checker should warn.
87   Possible ESF Compile Time checks
88     - maximum event size
89     - warn if string max length not set
90     - error is default values are out of range
92   Runtime checks
93     - defined event (EXISTING)
94       - checked when event name is set (DOES NOT CURRENTLY HAPPEN in C)
95     - defined attribute for event (EXISTING)
96       - checked when an attribute is added to an event (EXISTING)
97     - defined type for attribute for event (EXISTING)
98       - checked when an attribute is added to an event (EXISTING)
99     - check required fields are set (DOES NOT EXIST)
100       - checked when an event is emitted, an error is returned if not all
101         fields are set and event is not sent and an exception is thrown
102         or a non-zero return code is sent
103     - check maximum string length (DOES NOT EXIST)
104       - checked when set_STRING is called.
105         If esf db exists and the string is greater than the value given
106         in the esf, the field is not set and an exception or error is
107         returned.
109 3. Event Serialization Format
111       <version><event_name_length>     : 1 byte, 1 byte => N
112     | <event_name_length>              : 1 byte => N         (See 1 below)
113     <event_name_bytes>                 : N bytes
114     <number_of_attributes>             : 2 bytes (U_INT_16) => M
115     for (0 : M)
116       <attribute_name_length>          : 1 byte => X
117       <attribute_name_bytes>           : X bytes
118       <attribute_type>                 : 1 byte              (See 2 below)
119       <attribute_data>                 : Variable # bytes    (See 3 below)
120     <checksum>                         : 2 bytes             (See 4 below)
122     1. Versioning
124        When first bit is 0 event is in the old format, so first byte is
125         <event_name_length>.
126        When first bit is 1 this is the new format, so first byte is
127         <version> and second byte is <event_name_length>
129     2. Type Encoding
131       type      DEC HEX  byte value (bin)  array value (bin)
132       --------- --- ---- ----------------  ------------------
133       U_INT_16    1 0x01   00000001          10000001
134       INT_16      2 0x02   00000010          10000010
135       U_INT_32    3 0x03   00000011          10000011
136       INT_32      4 0x04   00000100          10000100
137       STRING      5 0x05   00000101          10000101
138       IP_ADDR     6 0x06   00000110          10000110
139       INT_64      7 0x07   00000111          10000111
140       U_INT_64    8 0x08   00001000          10001000
141       BOOLEAN     9 0x09   00001001          10001001
142       BYTE       10 0x0A   00001010          10001010
143       FLOAT      11 0x0B   00001011          10001011
144       DOUBLE     12 0x0C   00001100          10001100
145       IPV4       13 0x0D   00001101          10001101
147       * IP_ADDR should be deprecated, so should put out a warning from the esf
148         checker
150     3. Attribute Data Encoding
152     Where <attribute_data> is one of the normal types or an array or event type
154     U_INT_16
155       2 bytes - Network order
156     INT_16  
157       2 bytes - Network order
158     U_INT_32
159       4 bytes - Network order
160     INT_32  
161       4 bytes - Network order
162     STRING
163       2 bytes (U_INT_16) length => N
164       N bytes data - UTF-8 encoded
165     IP_ADDR 
166       4 bytes - Network order reversed *
168       * note: this encoding is completely wrong, so we are deprecating this type
169     INT_64
170       8 bytes - Network order
171     U_INT_64
172       8 bytes - Network order
173     BOOLEAN
174       1 byte  - 1 is true, 0 is false
175     BYTE
176       1 byte
177     FLOAT/DOUBLE
178       the way thrift (and probably protobuf) does things is they use
179       the 'IEEE 754 floating-point "single format" bit layout', which is easy
180       as C/C++/Java/etc all seem to easily support it.
182       In C you do
184       int32_t floatToIntBits (float input)
185       {
186         return *((int32_t *)&input);
187       }
189       float intBitsToFloat (int32_t input)
190       {
191         return *((float *)&input);
192       }
194       for floats and
196       int64_t doubleToLongBits (double input)
197       {
198         return *((int64_t *)&input);
199       }
201       double longBitsToDouble (int64_t input)
202       {
203         return *((double *)&input);
204       }
206       for doubles.
208       The equivalent functions in java are part of the standard library
210       int   Float.floatToIntBits (float value);
211       float Float.intBitsToFloat (int bits);
213       long   Double.floatToLongBits  (double value);
214       double Double.longBitsToDouble (long bits);
216       Now to actually encode for the network, you first convert from float
217       or double to an integer format, then use one of the int marshallers
218       which essentially call htonl or htonll on the value.
219       So encoding is
221       Float
222         -> IEEE 754 floating-point "single format" bit layout
223         -> Int 32 in Network Order
225       in C this looks like htonl (floatToIntBits (in))
227       Double
228         -> IEEE 754 floating-point "single format" bit layout
229         -> Int 64 in Network Order
231       in C this looks like htonll (doubleToIntBits (in))
233     IPV4
234       4 bytes - Network order
236       - in C, ip address are already in network order, so we can just
237         serialize it straight away.
238     ARRAYS
239       Array <attribute_data> is encoded as
240         <array_length>        2 bytes => Y
241         <attribute_data_0>    Variable # bytes based on type
242           ...
243         <attribute_data_N>    Varialbe # bytes based on type
245 4. API Changes
247    Basically, these reflect Public C API changes as the C implementation is
248    the reference implementation
250    1. Added API calls
252     /* set a byte type in an event */
253     int
254     lwes_event_set_BYTE
255       (struct lwes_event *event,
256        LWES_CONST_SHORT_STRING name,
257        LWES_BYTE byte);
259     /* get a byte type from an event */
260     int
261     lwes_event_get_BYTE
262       (struct lwes_event *event,
263        LWES_CONST_SHORT_STRING name,
264        LWES_BYTE *byte);
266     /* set a float type in an event */
267     int
268     lwes_event_set_FLOAT
269       (struct lwes_event *event,
270        LWES_CONST_SHORT_STRING name,
271        LWES_FLOAT flaot);
273     /* get a float type from an event */
274     int
275     lwes_event_get_FLOAT
276       (struct lwes_event *event,
277        LWES_CONST_SHORT_STRING name,
278        LWES_FLOAT *float);
280     /* set a double type in an event */
281     int
282     lwes_event_set_DOUBLE
283       (struct lwes_event *event,
284        LWES_CONST_SHORT_STRING name,
285        LWES_DOUBLE double);
287     /* get a double type from an event */
288     int
289     lwes_event_get_DOUBLE
290       (struct lwes_event *event,
291        LWES_CONST_SHORT_STRING name,
292        LWES_DOUBLE *double);
294     /* set a ipv4 type in an event */
295     int
296     lwes_event_set_IPV4
297       (struct lwes_event *event,
298        LWES_CONST_SHORT_STRING name,
299        LWES_IPV4 ipv4);
301     /* get a ipv4 type from an event */
302     int
303     lwes_event_get_IPV4
304       (struct lwes_event *event,
305        LWES_CONST_SHORT_STRING name,
306        LWES_IPV4 *ipv4);
308     For each of the types we also need array setters/getters
310     /* set an entire array in one call */
311     int
312     lwes_event_set_<TYPE>_arr
313       (struct lwes_event *event,
314        LWES_CONST_SHORT_STRING name,
315        LWES_INT_16 arr_length,
316        LWES_<TYPE> *arr);
318     /* set an entire array in one call */
319     int
320     lwes_event_get_<TYPE>_arr
321       (struct lwes_event *event,
322        LWES_CONST_SHORT_STRING name,
323        LWES_INT_16 arr_length,
324        LWES_<TYPE> **arr);
326   2. Removed/Changed API calls
328      Remove all 'enc' related calls, we're all utf-8
330      - lwes_event_create_with_encoding
331      - lwes_event_get_encoding
332      - lwes_event_set_encoding