skylight 0.2.7 → 0.3.0.rc.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/ext/checksums.yml +3 -0
  3. data/ext/extconf.rb +90 -0
  4. data/ext/skylight.map +4 -0
  5. data/ext/skylight_native.c +613 -0
  6. data/lib/skylight.rb +50 -7
  7. data/lib/skylight/config.rb +7 -1
  8. data/lib/skylight/helpers.rb +2 -2
  9. data/lib/skylight/instrumenter.rb +9 -5
  10. data/lib/skylight/messages.rb +13 -13
  11. data/lib/skylight/messages/error.rb +10 -6
  12. data/lib/skylight/messages/hello.rb +4 -45
  13. data/lib/skylight/messages/trace.rb +62 -103
  14. data/lib/skylight/messages/trace_envelope.rb +19 -0
  15. data/lib/skylight/native.rb +80 -0
  16. data/lib/skylight/normalizers/process_action.rb +1 -3
  17. data/lib/skylight/probes.rb +1 -1
  18. data/lib/skylight/subscriber.rb +1 -1
  19. data/lib/skylight/util/clock.rb +13 -6
  20. data/lib/skylight/version.rb +1 -1
  21. data/lib/skylight/worker/builder.rb +1 -1
  22. data/lib/skylight/worker/collector.rb +20 -32
  23. data/lib/skylight/worker/connection.rb +2 -2
  24. data/lib/skylight/worker/embedded.rb +18 -0
  25. data/lib/skylight/worker/server.rb +3 -3
  26. data/lib/skylight/worker/standalone.rb +9 -10
  27. data/lib/sql_lexer.rb +0 -1
  28. data/lib/sql_lexer/lexer.rb +50 -4
  29. data/lib/sql_lexer/version.rb +1 -1
  30. metadata +19 -22
  31. data/lib/skylight/messages/annotation.rb +0 -13
  32. data/lib/skylight/messages/base.rb +0 -24
  33. data/lib/skylight/messages/batch.rb +0 -12
  34. data/lib/skylight/messages/endpoint.rb +0 -12
  35. data/lib/skylight/messages/event.rb +0 -12
  36. data/lib/skylight/messages/span.rb +0 -166
  37. data/lib/skylight/vendor/beefcake.rb +0 -292
  38. data/lib/skylight/vendor/beefcake/buffer.rb +0 -119
  39. data/lib/skylight/vendor/beefcake/decode.rb +0 -107
  40. data/lib/skylight/vendor/beefcake/encode.rb +0 -132
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edae1bae15bae8f3c6570992aeef722d03a6daba
4
- data.tar.gz: 0bf27cb52e79314929c6d1e11e38956dcc93fa77
3
+ metadata.gz: a2b5eb1b24fdff7848211503dcda7504e1967c11
4
+ data.tar.gz: f1f07ea7ab290215cfef1fdadd0df71df2ee0634
5
5
  SHA512:
6
- metadata.gz: 30f1914554e84ef1ec3f7e728787a36cc12b8aa469798ec18bc8ba3f142bc6c305fd98f2917d09eb058acbf691282ff113cc1aa302ca22db2c5c5af8b026560c
7
- data.tar.gz: 292f7e33dc69706101430e2f0e6c21712d00526c7d789f7ca7bcaa02e1f622501c26ef493de776acbe7f448032ec0909f8f58dac60ad66d7e94df56cf3690fa7
6
+ metadata.gz: 86e844881f4861ea358c4711cd0b60c7709c18472ee970212bad864f454e030f1f10692161ff20a0ca78e33362864518f7c4e921c5e61ca0656322a50dd24b0c
7
+ data.tar.gz: 5dba678a612d519c3f11c808596486f2a17e8e383738039acff430d91d6b1e93d65a19d1005126f32a64f9e474e34551ffa9b76fc753195bac35d9f725f0a103
data/ext/checksums.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ dc29745.x86_64-linux: "4f0b9ef0d700d2da590ad0994c2067304a50d7b290f70353c394e4a040cdf0a5"
3
+ dc29745.i686-linux : "9b7beebe61ef3201f4d7ad2cf5e92dc69cedefda033b9d081384c71700927a37"
data/ext/extconf.rb ADDED
@@ -0,0 +1,90 @@
1
+ require 'mkmf'
2
+ require 'rbconfig'
3
+ require 'net/http'
4
+ require 'zlib'
5
+ require 'yaml'
6
+ require 'digest/sha2'
7
+
8
+ require_relative '../lib/skylight/version.rb'
9
+
10
+ checksums = YAML.load_file("checksums.yml")
11
+
12
+ rust_version = "dc29745"
13
+ ruby_version = Skylight::VERSION
14
+
15
+ arch = RbConfig::CONFIG["arch"]
16
+ url = "https://github.com/skylightio/skylight-rust/releases/download/v#{ruby_version}/libskylight.#{rust_version}.#{arch}.a.gz"
17
+
18
+ required = ENV.key?("SKYLIGHT_REQUIRED")
19
+
20
+ unless File.exist?("libskylight.a")
21
+ puts "[SKYLIGHT] Downloading from #{url.inspect}"
22
+ location = nil
23
+ uri = URI.parse(url)
24
+
25
+ begin
26
+ Net::HTTP.start("github.com", 443, use_ssl: true) do |http|
27
+ response = http.get(uri.request_uri)
28
+ location = response["Location"]
29
+ end
30
+
31
+ if location
32
+ archive = nil
33
+
34
+ uri = URI(location)
35
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
36
+ response = http.get(uri.request_uri)
37
+ archive = response.body
38
+ end
39
+ else
40
+ raise "No location returned" if required
41
+ missing_a = true
42
+ end
43
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
44
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError
45
+ raise if required
46
+ missing_a = true
47
+ end
48
+
49
+ unless missing_a
50
+ expected_checksum = checksums["#{rust_version}.#{arch}"]
51
+ actual_checksum = Digest::SHA2.hexdigest(archive)
52
+
53
+ if expected_checksum == actual_checksum
54
+ inflater, dest = Zlib::Inflate.new(32 + Zlib::MAX_WBITS), ""
55
+ dest << inflater.inflate(archive)
56
+ inflater.close
57
+
58
+ File.open("libskylight.a", "w") { |file| file.write dest }
59
+ else
60
+ raise "Checksum mismatched; expected=#{expected_checksum.inspect}; actual=#{actual_checksum.inspect}" if required
61
+ missing_a = true
62
+ end
63
+ end
64
+ end
65
+
66
+ if missing_a
67
+ puts "[SKYLIGHT] Could not download Skylight native code from Github; version=#{rust_version.inspect}; arch=#{arch.inspect}"
68
+
69
+ exit 1 if required
70
+
71
+ File.open("Makefile", "w") do |file|
72
+ file.puts "default:"
73
+ file.puts "install:"
74
+ end
75
+ else
76
+ have_header 'dlfcn.h'
77
+
78
+ find_library("skylight", "factory", ".")
79
+
80
+ if RbConfig::CONFIG["arch"] =~ /darwin(\d+)?/
81
+ $LDFLAGS << " -lpthread"
82
+ else
83
+ $LDFLAGS << " -Wl,--version-script=skylight.map"
84
+ $LDFLAGS << " -lrt -ldl -lm -lpthread"
85
+ end
86
+
87
+ CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
88
+
89
+ create_makefile 'skylight_native', '.'
90
+ end
data/ext/skylight.map ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ global: Init_skylight_native;
3
+ local: *;
4
+ };
@@ -0,0 +1,613 @@
1
+ #include <ruby.h>
2
+ #include <stdbool.h>
3
+
4
+ /**
5
+ * Ruby helpers
6
+ */
7
+
8
+ #define CHECK_TYPE(VAL, T) \
9
+ do { \
10
+ if (TYPE(VAL) != T) { \
11
+ rb_raise(rb_eArgError, #VAL " is not " #T); \
12
+ return Qnil; \
13
+ } \
14
+ } while(0) \
15
+
16
+ #define CHECK(EXPR, string) \
17
+ do { \
18
+ if (!({ EXPR; })) { \
19
+ rb_raise(rb_eArgError, string); \
20
+ return Qnil; \
21
+ } \
22
+ } while(0) \
23
+
24
+ #define CHECK_NUMERIC(VAL) \
25
+ CHECK(VAL, #VAL " is not numeric") \
26
+
27
+ #define My_Struct(name, Type, msg) \
28
+ Get_Struct(name, self, Type, msg); \
29
+
30
+ #define Transfer_My_Struct(name, Type, msg) \
31
+ My_Struct(name, Type, msg); \
32
+ DATA_PTR(self) = NULL; \
33
+
34
+ #define Transfer_Struct(name, obj, Type, msg) \
35
+ Get_Struct(name, obj, Type, msg); \
36
+ DATA_PTR(obj) = NULL; \
37
+
38
+ #define Get_Struct(name, obj, Type, msg) \
39
+ Type name; \
40
+ Data_Get_Struct(obj, Type, name); \
41
+ if (name == NULL) { \
42
+ rb_raise(rb_eRuntimeError, "%s", msg); \
43
+ } \
44
+
45
+ #define CHECK_FFI(success, message) \
46
+ { \
47
+ if (!(success)) \
48
+ rb_raise(rb_eRuntimeError, message); \
49
+ } \
50
+
51
+ /**
52
+ * Rust types
53
+ */
54
+
55
+ typedef struct {
56
+ size_t fill; // in bytes; if zero, heapified
57
+ size_t alloc; // in bytes
58
+ uint8_t data[0];
59
+ } rust_str;
60
+
61
+ typedef struct {
62
+ char * data;
63
+ long len;
64
+ } RustSlice;
65
+
66
+ typedef rust_str * RustString;
67
+ #define VEC2STR(string) ({ RustString s = (string); VALUE ret = rb_str_new((char *)s->data, s->fill); ret; })
68
+ #define SLICE2STR(slice) ({ RustSlice s = (slice); rb_str_new(s.data, s.len); })
69
+ #define STR2SLICE(string) ({ RustSlice s; VALUE rb_str = (string); s.data = RSTRING_PTR(rb_str); s.len = RSTRING_LEN(rb_str); s; })
70
+
71
+ #define UnwrapOption(T, val, transform) ({ T * v = (val); VALUE ret; if (v == NULL) ret = Qnil; else ret = transform(*v); ret; })
72
+
73
+ typedef struct {
74
+ uint8_t discrim;
75
+ RustSlice slice;
76
+ } OptionRustSlice;
77
+
78
+ #define IsNone(val) val.discrim == 0
79
+
80
+ /**
81
+ * Externed Rust functions from libskylight
82
+ */
83
+
84
+ typedef void * RustHello;
85
+ typedef void * RustError;
86
+ typedef void * RustTrace;
87
+ typedef void * RustBatch;
88
+
89
+ void factory();
90
+
91
+
92
+ // Rust skylight_hello prototypes
93
+ bool skylight_hello_new(RustSlice, uint32_t, RustHello*);
94
+ bool skylight_hello_free(RustHello);
95
+ bool skylight_hello_load(RustSlice, RustHello*);
96
+ bool skylight_hello_cmd_add(RustHello, RustSlice);
97
+ bool skylight_hello_get_version(RustHello, RustSlice*);
98
+ bool skylight_hello_cmd_length(RustHello, uint32_t*);
99
+ bool skylight_hello_get_cmd(RustHello, int, RustSlice*);
100
+ bool skylight_hello_serialize_into_new_buffer(RustHello, RustString*);
101
+ bool skylight_high_res_time(uint64_t*);
102
+
103
+ // Rust skylight_trace prototypes
104
+ bool skylight_trace_new(uint64_t, RustSlice, RustTrace*);
105
+ bool skylight_trace_free(RustTrace);
106
+ bool skylight_trace_load(RustSlice, RustTrace*);
107
+ bool skylight_trace_name_from_serialized_into_new_buffer(RustSlice, RustSlice*);
108
+ bool skylight_trace_get_started_at(RustTrace, uint64_t*);
109
+ bool skylight_trace_set_name(RustTrace, RustSlice);
110
+ bool skylight_trace_get_name(RustTrace, RustSlice*);
111
+ bool skylight_trace_get_uuid(RustTrace, RustSlice*);
112
+ bool skylight_trace_start_span(RustTrace, uint64_t, RustSlice, uint32_t*);
113
+ bool skylight_trace_stop_span(RustTrace, uint32_t, uint64_t);
114
+ bool skylight_trace_serialize_into_new_buffer(RustTrace, RustString*);
115
+ bool skylight_trace_span_set_title(RustTrace, uint64_t, RustSlice);
116
+ bool skylight_trace_span_set_description(RustTrace, uint64_t, RustSlice);
117
+
118
+ // Trace annotation methods
119
+ bool skylight_trace_add_annotation_int(RustTrace, uint32_t, uint32_t*, RustSlice*, int64_t);
120
+ bool skylight_trace_add_annotation_double(RustTrace, uint32_t, uint32_t*, RustSlice*, double);
121
+ bool skylight_trace_add_annotation_string(RustTrace, uint32_t, uint32_t*, RustSlice*, RustSlice);
122
+ bool skylight_trace_add_annotation_nested(RustTrace, uint32_t, uint32_t*, RustSlice*, uint32_t*);
123
+
124
+ // Batch methods
125
+ bool skylight_batch_new(uint32_t, RustString, RustBatch*);
126
+ bool skylight_batch_free(RustBatch);
127
+ bool skylight_batch_set_endpoint_count(RustBatch, RustSlice, uint64_t);
128
+ bool skylight_batch_move_in(RustBatch, RustString);
129
+ bool skylight_batch_serialize_into_new_buffer(RustBatch, RustString*);
130
+
131
+ // Error methods
132
+ bool skylight_error_new(RustSlice, RustSlice, RustError*);
133
+ bool skylight_error_free(RustError);
134
+ bool skylight_error_load(RustSlice, RustError*);
135
+ bool skylight_error_get_group(RustError, RustSlice*);
136
+ bool skylight_error_get_description(RustError, RustSlice*);
137
+ bool skylight_error_get_details(RustError, RustSlice*);
138
+ bool skylight_error_set_details(RustError, RustSlice);
139
+ bool skylight_error_serialize_into_new_buffer(RustError, RustString*);
140
+
141
+ void skylight_free_buf(RustString);
142
+
143
+ /**
144
+ * Convert Ruby String to a Rust String
145
+ */
146
+
147
+ RustString skylight_slice_to_owned(RustSlice);
148
+ RustString skylight_bytes_to_new_vec(uint8_t*, uint64_t);
149
+
150
+ #define STR2RUST(string) ({ VALUE rb_str = (string); skylight_bytes_to_new_vec((uint8_t*)RSTRING_PTR(rb_str), RSTRING_LEN(rb_str)); })
151
+
152
+ /**
153
+ * Ruby types defined here
154
+ */
155
+
156
+ VALUE rb_mSkylight;
157
+ VALUE rb_mUtil;
158
+ VALUE rb_cClock;
159
+ VALUE rb_cHello;
160
+ VALUE rb_cError;
161
+ VALUE rb_cTrace;
162
+ VALUE rb_cBatch;
163
+
164
+ /**
165
+ * class Skylight::Util::Clock
166
+ */
167
+
168
+ static VALUE clock_high_res_time(VALUE self) {
169
+ uint64_t time;
170
+ CHECK_FFI(skylight_high_res_time(&time), "Could not get high-res time");
171
+ return ULL2NUM(time);
172
+ }
173
+
174
+ /**
175
+ * class Skylight::Hello
176
+ */
177
+
178
+ static VALUE hello_new(VALUE klass, VALUE version, VALUE config) {
179
+ RustHello hello;
180
+
181
+ CHECK_TYPE(version, T_STRING);
182
+ CHECK_TYPE(config, T_FIXNUM);
183
+
184
+ CHECK_FFI(skylight_hello_new(STR2SLICE(version), FIX2INT(config), &hello), "could not create new Hello");
185
+
186
+ return Data_Wrap_Struct(rb_cHello, NULL, skylight_hello_free, hello);
187
+ }
188
+
189
+ static VALUE hello_load(VALUE self, VALUE protobuf) {
190
+ CHECK_TYPE(protobuf, T_STRING);
191
+
192
+ RustHello hello;
193
+
194
+ CHECK_FFI(skylight_hello_load(STR2SLICE(protobuf), &hello), "Could not load Hello");
195
+
196
+ return Data_Wrap_Struct(rb_cHello, NULL, skylight_hello_free, hello);
197
+ }
198
+
199
+ static const char* freedHello = "You can't do anything with a Hello once it's been serialized";
200
+
201
+ static VALUE hello_get_version(VALUE self) {
202
+ RustSlice slice;
203
+
204
+ My_Struct(hello, RustHello, freedHello);
205
+
206
+ CHECK_FFI(skylight_hello_get_version(hello, &slice), "could not get version from Hello");
207
+
208
+ return SLICE2STR(slice);
209
+ }
210
+
211
+ static VALUE hello_cmd_length(VALUE self) {
212
+ My_Struct(hello, RustHello, freedHello);
213
+
214
+ uint32_t length;
215
+
216
+ CHECK_FFI(skylight_hello_cmd_length(hello, &length), "Could not get length of Hello commands");
217
+
218
+ return UINT2NUM(length);
219
+ }
220
+
221
+ static VALUE hello_add_cmd_part(VALUE self, VALUE rb_string) {
222
+ My_Struct(hello, RustHello, freedHello);
223
+
224
+ CHECK_TYPE(rb_string, T_STRING);
225
+
226
+ CHECK_FFI(skylight_hello_cmd_add(hello, STR2SLICE(rb_string)), "Could not add command part to Hello");
227
+
228
+ return Qnil;
229
+ }
230
+
231
+ static VALUE hello_cmd_get(VALUE self, VALUE rb_off) {
232
+ int off;
233
+ RustSlice slice;
234
+ My_Struct(hello, RustHello, freedHello);
235
+
236
+ CHECK_TYPE(rb_off, T_FIXNUM);
237
+ off = FIX2INT(rb_off);
238
+
239
+ CHECK_FFI(skylight_hello_get_cmd(hello, off, &slice), "Could not get command part from Hello");
240
+
241
+ return SLICE2STR(slice);
242
+ }
243
+
244
+ static VALUE hello_serialize(VALUE self) {
245
+ RustString serialized;
246
+ Transfer_My_Struct(hello, RustHello, freedHello);
247
+
248
+ CHECK_FFI(skylight_hello_serialize_into_new_buffer(hello, &serialized), "Could not serialize Hello");
249
+ skylight_hello_free(hello);
250
+
251
+ VALUE string = VEC2STR(serialized);
252
+ skylight_free_buf(serialized);
253
+ return string;
254
+ }
255
+
256
+ /**
257
+ * class Skylight::Error
258
+ */
259
+
260
+ static VALUE error_new(VALUE klass, VALUE group, VALUE description) {
261
+ RustError error;
262
+
263
+ CHECK_TYPE(group, T_STRING);
264
+ CHECK_TYPE(description, T_STRING);
265
+
266
+ CHECK_FFI(skylight_error_new(STR2SLICE(group), STR2SLICE(description), &error), "could not create new Error");
267
+
268
+ return Data_Wrap_Struct(rb_cError, NULL, skylight_error_free, error);
269
+ }
270
+
271
+ static VALUE error_load(VALUE self, VALUE protobuf) {
272
+ CHECK_TYPE(protobuf, T_STRING);
273
+
274
+ RustError error;
275
+
276
+ CHECK_FFI(skylight_error_load(STR2SLICE(protobuf), &error), "Could not load Error");
277
+
278
+ return Data_Wrap_Struct(rb_cError, NULL, skylight_error_free, error);
279
+ }
280
+
281
+ static const char* freedError = "You can't do anything with a Error once it's been serialized";
282
+
283
+ static VALUE error_get_group(VALUE self) {
284
+ RustSlice slice;
285
+
286
+ My_Struct(error, RustError, freedError);
287
+
288
+ CHECK_FFI(skylight_error_get_group(error, &slice), "could not get group from Error");
289
+
290
+ return SLICE2STR(slice);
291
+ }
292
+
293
+ static VALUE error_get_description(VALUE self) {
294
+ RustSlice slice;
295
+
296
+ My_Struct(error, RustError, freedError);
297
+
298
+ CHECK_FFI(skylight_error_get_description(error, &slice), "could not get description from Error");
299
+
300
+ return SLICE2STR(slice);
301
+ }
302
+
303
+ static VALUE error_get_details(VALUE self) {
304
+ RustSlice slice;
305
+
306
+ My_Struct(error, RustError, freedError);
307
+
308
+ CHECK_FFI(skylight_error_get_details(error, &slice), "could not get details from Error");
309
+
310
+ return SLICE2STR(slice);
311
+ }
312
+
313
+ static VALUE error_set_details(VALUE self, VALUE details) {
314
+ CHECK_TYPE(details, T_STRING);
315
+
316
+ My_Struct(error, RustError, freedError);
317
+
318
+ CHECK_FFI(skylight_error_set_details(error, STR2SLICE(details)), "could not set Error details");
319
+
320
+ return Qnil;
321
+ }
322
+
323
+ static VALUE error_serialize(VALUE self) {
324
+ RustString serialized;
325
+ Transfer_My_Struct(error, RustError, freedError);
326
+
327
+ CHECK_FFI(skylight_error_serialize_into_new_buffer(error, &serialized), "Could not serialize Error");
328
+ skylight_error_free(error);
329
+
330
+ VALUE string = VEC2STR(serialized);
331
+ skylight_free_buf(serialized);
332
+ return string;
333
+ }
334
+
335
+ /**
336
+ * Skylight::Trace
337
+ */
338
+
339
+ static const char* freedTrace = "You can't do anything with a Trace once it's been serialized or moved into a Batch";
340
+
341
+ static VALUE trace_new(VALUE self, VALUE started_at, VALUE uuid) {
342
+ CHECK_TYPE(started_at, T_FIXNUM);
343
+ CHECK_TYPE(uuid, T_STRING);
344
+
345
+ RustTrace trace;
346
+
347
+ CHECK_FFI(skylight_trace_new(NUM2ULL(started_at), STR2SLICE(uuid), &trace), "Could not created Trace");
348
+
349
+ return Data_Wrap_Struct(rb_cTrace, NULL, skylight_trace_free, trace);
350
+ }
351
+
352
+ static VALUE trace_load(VALUE self, VALUE protobuf) {
353
+ CHECK_TYPE(protobuf, T_STRING);
354
+
355
+ RustTrace trace;
356
+
357
+ CHECK_FFI(skylight_trace_load(STR2SLICE(protobuf), &trace), "Could not load Trace");
358
+
359
+ return Data_Wrap_Struct(rb_cTrace, NULL, skylight_trace_free, trace);
360
+ }
361
+
362
+ static VALUE trace_name_from_serialized(VALUE self, VALUE protobuf) {
363
+ CHECK_TYPE(protobuf, T_STRING);
364
+
365
+ RustSlice trace_name;
366
+
367
+ CHECK_FFI(skylight_trace_name_from_serialized_into_new_buffer(STR2SLICE(protobuf), &trace_name), "Could not read name from serialized Trace");
368
+
369
+ return SLICE2STR(trace_name);
370
+ }
371
+
372
+ static VALUE trace_get_started_at(VALUE self) {
373
+ My_Struct(trace, RustTrace, freedTrace);
374
+
375
+ uint64_t started_at;
376
+
377
+ CHECK_FFI(skylight_trace_get_started_at(trace, &started_at), "Could not get Trace started_at");
378
+
379
+ return ULL2NUM(started_at);
380
+ }
381
+
382
+ static VALUE trace_set_name(VALUE self, VALUE name) {
383
+ CHECK_TYPE(name, T_STRING);
384
+
385
+ My_Struct(trace, RustTrace, freedTrace);
386
+ CHECK_FFI(skylight_trace_set_name(trace, STR2SLICE(name)), "Could not set Trace name");
387
+ return Qnil;
388
+ }
389
+
390
+ static VALUE trace_get_name(VALUE self) {
391
+ My_Struct(trace, RustTrace, freedTrace);
392
+
393
+ RustSlice string;
394
+ if (skylight_trace_get_name(trace, &string)) {
395
+ return SLICE2STR(string);
396
+ } else {
397
+ return Qnil;
398
+ }
399
+
400
+ //return UnwrapOption(RustSlice, skylight_trace_get_name(trace), SLICE2STR);
401
+ }
402
+
403
+ static VALUE trace_get_uuid(VALUE self) {
404
+ My_Struct(trace, RustTrace, freedTrace);
405
+
406
+ RustSlice slice;
407
+
408
+ CHECK_FFI(skylight_trace_get_uuid(trace, &slice), "Could not get uuid from Trace");
409
+
410
+ return SLICE2STR(slice);
411
+ }
412
+
413
+ static VALUE trace_start_span(VALUE self, VALUE time, VALUE category) {
414
+ uint32_t span;
415
+ My_Struct(trace, RustTrace, freedTrace);
416
+
417
+ CHECK_NUMERIC(time);
418
+ CHECK_TYPE(category, T_STRING);
419
+
420
+ CHECK_FFI(skylight_trace_start_span(trace, NUM2ULL(time), STR2SLICE(category), &span), "Could not start Span");
421
+
422
+ return UINT2NUM(span);
423
+ }
424
+
425
+ static VALUE trace_stop_span(VALUE self, VALUE span_index, VALUE time) {
426
+ My_Struct(trace, RustTrace, freedTrace);
427
+
428
+ CHECK_NUMERIC(time);
429
+ CHECK_TYPE(span_index, T_FIXNUM);
430
+
431
+ CHECK_FFI(skylight_trace_stop_span(trace, FIX2UINT(span_index), NUM2ULL(time)), "Could not stop Span");
432
+
433
+ return Qnil;
434
+ }
435
+
436
+ static VALUE trace_span_set_title(VALUE self, VALUE index, VALUE title) {
437
+ My_Struct(trace, RustTrace, freedTrace);
438
+
439
+ CHECK_TYPE(index, T_FIXNUM);
440
+ CHECK_TYPE(title, T_STRING);
441
+
442
+ CHECK_FFI(skylight_trace_span_set_title(trace, NUM2LL(index), STR2SLICE(title)), "Could not set Span title");
443
+
444
+ return Qnil;
445
+ }
446
+
447
+ static VALUE trace_span_set_description(VALUE self, VALUE index, VALUE description) {
448
+ My_Struct(trace, RustTrace, freedTrace);
449
+
450
+ CHECK_TYPE(index, T_FIXNUM);
451
+ CHECK_TYPE(description, T_STRING);
452
+
453
+ CHECK_FFI(skylight_trace_span_set_description(trace, NUM2LL(index), STR2SLICE(description)), "Could not set Span description");
454
+ return Qnil;
455
+ }
456
+
457
+ static VALUE trace_serialize(VALUE self) {
458
+ Transfer_My_Struct(trace, RustTrace, freedTrace);
459
+
460
+ RustString string;
461
+
462
+ CHECK_FFI(skylight_trace_serialize_into_new_buffer(trace, &string), "Could not serialize Trace");
463
+ skylight_trace_free(trace);
464
+
465
+ VALUE rb_string = VEC2STR(string);
466
+ skylight_free_buf(string);
467
+ return rb_string;
468
+ }
469
+
470
+ static VALUE trace_span_add_annotation(VALUE self, VALUE rb_span_id, VALUE parent, VALUE rb_key, VALUE value) {
471
+ uint32_t *parent_id = NULL;
472
+ RustSlice rs_key;
473
+ RustSlice *key = NULL;
474
+ uint32_t new_id, parent_int;
475
+
476
+ My_Struct(trace, RustTrace, freedTrace);
477
+
478
+ CHECK_TYPE(rb_span_id, T_FIXNUM);
479
+ uint32_t span_id = FIX2UINT(rb_span_id);
480
+
481
+ if (parent != Qnil) {
482
+ CHECK_TYPE(parent, T_FIXNUM);
483
+ parent_int = FIX2UINT(parent);
484
+ parent_id = &parent_int;
485
+ }
486
+
487
+ if (rb_key != Qnil) {
488
+ CHECK_TYPE(rb_key, T_STRING);
489
+
490
+ rs_key = STR2SLICE(rb_key);
491
+ key = &rs_key;
492
+ }
493
+
494
+ if (TYPE(value) == T_FIXNUM) {
495
+ CHECK_FFI(skylight_trace_add_annotation_int(trace, span_id, parent_id, key, NUM2LL(value)), "Could not add int annotation");
496
+ } else if (TYPE(value) == T_FLOAT) {
497
+ CHECK_FFI(skylight_trace_add_annotation_double(trace, span_id, parent_id, key, NUM2DBL(value)), "Could not add double annotation");
498
+ } else if (TYPE(value) == T_STRING) {
499
+ CHECK_FFI(skylight_trace_add_annotation_string(trace, span_id, parent_id, key, STR2SLICE(value)), "Could not add string annotation");
500
+ } else if (TYPE(value) == T_SYMBOL && value == ID2SYM(rb_intern("nested"))) {
501
+ CHECK_FFI(skylight_trace_add_annotation_nested(trace, span_id, parent_id, key, &new_id), "Could not add nested annotation");
502
+ return ULL2NUM(new_id);
503
+ } else {
504
+ rb_raise(rb_eArgError, "You must pass an integer, string or :nested to native_span_add_annotation");
505
+ }
506
+
507
+ return Qnil;
508
+ }
509
+
510
+ /**
511
+ * class Skylight::Batch
512
+ */
513
+
514
+ static const char* freedBatch = "You can't do anything with a Batch once it's been serialized";
515
+
516
+ VALUE batch_new(VALUE klass, VALUE rb_timestamp, VALUE rb_hostname) {
517
+ CHECK_NUMERIC(rb_timestamp);
518
+
519
+ RustString hostname = NULL;
520
+ uint32_t timestamp = NUM2ULONG(rb_timestamp);
521
+
522
+ if (rb_hostname != Qnil) {
523
+ CHECK_TYPE(rb_hostname, T_STRING);
524
+ hostname = STR2RUST(rb_hostname);
525
+ }
526
+
527
+ RustBatch batch;
528
+
529
+ CHECK_FFI(skylight_batch_new(timestamp, hostname, &batch), "Could not create Batch");
530
+
531
+ return Data_Wrap_Struct(rb_cBatch, NULL, skylight_batch_free, batch);
532
+ }
533
+
534
+ VALUE batch_set_endpoint_count(VALUE self, VALUE rb_endpoint_name, VALUE rb_count) {
535
+ CHECK_TYPE(rb_endpoint_name, T_STRING);
536
+ CHECK_NUMERIC(rb_count);
537
+
538
+ My_Struct(batch, RustBatch, freedBatch);
539
+
540
+ CHECK_FFI(skylight_batch_set_endpoint_count(batch, STR2SLICE(rb_endpoint_name), NUM2ULL(rb_count)), "Could not set count for Endpoint in Batch");
541
+
542
+ return Qnil;
543
+ }
544
+
545
+ VALUE batch_move_in(VALUE self, VALUE rb_string) {
546
+ CHECK_TYPE(rb_string, T_STRING);
547
+
548
+ My_Struct(batch, RustBatch, freedBatch);
549
+
550
+ CHECK_FFI(skylight_batch_move_in(batch, STR2RUST(rb_string)), "Could not add serialized Trace to Batch");
551
+
552
+ return Qnil;
553
+ }
554
+
555
+ VALUE batch_serialize(VALUE self) {
556
+ Transfer_My_Struct(batch, RustBatch, freedBatch);
557
+
558
+ RustString string;
559
+
560
+ CHECK_FFI(skylight_batch_serialize_into_new_buffer(batch, &string), "Could not serialize Batch");
561
+ skylight_batch_free(batch);
562
+
563
+ VALUE rb_string = VEC2STR(string);
564
+ skylight_free_buf(string);
565
+ return rb_string;
566
+ }
567
+
568
+ void Init_skylight_native() {
569
+ rb_mSkylight = rb_define_module("Skylight");
570
+ rb_mUtil = rb_define_module_under(rb_mSkylight, "Util");
571
+
572
+ rb_cClock = rb_define_class_under(rb_mUtil, "Clock", rb_cObject);
573
+ rb_define_method(rb_cClock, "native_hrtime", clock_high_res_time, 0);
574
+
575
+ rb_cHello = rb_define_class_under(rb_mSkylight, "Hello", rb_cObject);
576
+ rb_define_singleton_method(rb_cHello, "native_new", hello_new, 2);
577
+ rb_define_singleton_method(rb_cHello, "native_load", hello_load, 1);
578
+ rb_define_method(rb_cHello, "native_get_version", hello_get_version, 0);
579
+ rb_define_method(rb_cHello, "native_cmd_length", hello_cmd_length, 0);
580
+ rb_define_method(rb_cHello, "native_add_cmd_part", hello_add_cmd_part, 1);
581
+ rb_define_method(rb_cHello, "native_cmd_get", hello_cmd_get, 1);
582
+ rb_define_method(rb_cHello, "native_serialize", hello_serialize, 0);
583
+
584
+ rb_cError = rb_define_class_under(rb_mSkylight, "Error", rb_cObject);
585
+ rb_define_singleton_method(rb_cError, "native_new", error_new, 2);
586
+ rb_define_singleton_method(rb_cError, "native_load", error_load, 1);
587
+ rb_define_method(rb_cError, "native_get_group", error_get_group, 0);
588
+ rb_define_method(rb_cError, "native_get_description", error_get_description, 0);
589
+ rb_define_method(rb_cError, "native_get_details", error_get_details, 0);
590
+ rb_define_method(rb_cError, "native_set_details", error_set_details, 1);
591
+ rb_define_method(rb_cError, "native_serialize", error_serialize, 0);
592
+
593
+ rb_cTrace = rb_define_class_under(rb_mSkylight, "Trace", rb_cObject);
594
+ rb_define_singleton_method(rb_cTrace, "native_new", trace_new, 2);
595
+ rb_define_singleton_method(rb_cTrace, "native_load", trace_load, 1);
596
+ rb_define_singleton_method(rb_cTrace, "native_name_from_serialized", trace_name_from_serialized, 1);
597
+ rb_define_method(rb_cTrace, "native_get_started_at", trace_get_started_at, 0);
598
+ rb_define_method(rb_cTrace, "native_get_name", trace_get_name, 0);
599
+ rb_define_method(rb_cTrace, "native_set_name", trace_set_name, 1);
600
+ rb_define_method(rb_cTrace, "native_get_uuid", trace_get_uuid, 0);
601
+ rb_define_method(rb_cTrace, "native_serialize", trace_serialize, 0);
602
+ rb_define_method(rb_cTrace, "native_start_span", trace_start_span, 2);
603
+ rb_define_method(rb_cTrace, "native_stop_span", trace_stop_span, 2);
604
+ rb_define_method(rb_cTrace, "native_span_set_title", trace_span_set_title, 2);
605
+ rb_define_method(rb_cTrace, "native_span_set_description", trace_span_set_description, 2);
606
+ rb_define_method(rb_cTrace, "native_span_add_annotation", trace_span_add_annotation, 4);
607
+
608
+ rb_cBatch = rb_define_class_under(rb_mSkylight, "Batch", rb_cObject);
609
+ rb_define_singleton_method(rb_cBatch, "native_new", batch_new, 2);
610
+ rb_define_method(rb_cBatch, "native_move_in", batch_move_in, 1);
611
+ rb_define_method(rb_cBatch, "native_set_endpoint_count", batch_set_endpoint_count, 2);
612
+ rb_define_method(rb_cBatch, "native_serialize", batch_serialize, 0);
613
+ }