skylight 0.2.7 → 0.3.0.rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }