skylight 0.3.21 → 0.4.0.alpha1

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -4
  3. data/ext/extconf.rb +92 -47
  4. data/ext/libskylight.yml +4 -4
  5. data/ext/skylight_native.c +248 -286
  6. data/lib/skylight.rb +19 -114
  7. data/lib/skylight/api.rb +1 -1
  8. data/lib/skylight/config.rb +176 -146
  9. data/lib/skylight/data/cacert.pem +717 -719
  10. data/lib/skylight/formatters/http.rb +1 -1
  11. data/lib/skylight/instrumenter.rb +28 -35
  12. data/lib/skylight/native.rb +58 -72
  13. data/lib/skylight/normalizers.rb +0 -1
  14. data/lib/skylight/normalizers/active_record/sql.rb +0 -4
  15. data/lib/skylight/probes/excon/middleware.rb +3 -1
  16. data/lib/skylight/probes/net_http.rb +3 -1
  17. data/lib/skylight/subscriber.rb +0 -4
  18. data/lib/skylight/trace.rb +189 -0
  19. data/lib/skylight/util.rb +10 -12
  20. data/lib/skylight/util/hostname.rb +17 -0
  21. data/lib/skylight/util/http.rb +33 -36
  22. data/lib/skylight/util/logging.rb +20 -1
  23. data/lib/skylight/util/multi_io.rb +21 -0
  24. data/lib/skylight/util/native_ext_fetcher.rb +83 -69
  25. data/lib/skylight/util/platform.rb +67 -0
  26. data/lib/skylight/util/ssl.rb +50 -0
  27. data/lib/skylight/version.rb +1 -1
  28. metadata +9 -34
  29. data/ext/rust_support/ruby.h +0 -93
  30. data/ext/skylight.h +0 -85
  31. data/ext/skylight.map +0 -4
  32. data/ext/test/extconf.rb +0 -18
  33. data/ext/test/skylight_native_test.c +0 -82
  34. data/ext/test/skylight_test.h +0 -20
  35. data/lib/skylight/formatters.rb +0 -6
  36. data/lib/skylight/messages.rb +0 -21
  37. data/lib/skylight/messages/error.rb +0 -15
  38. data/lib/skylight/messages/hello.rb +0 -13
  39. data/lib/skylight/messages/trace.rb +0 -179
  40. data/lib/skylight/messages/trace_envelope.rb +0 -19
  41. data/lib/skylight/metrics.rb +0 -9
  42. data/lib/skylight/metrics/ewma.rb +0 -69
  43. data/lib/skylight/metrics/meter.rb +0 -58
  44. data/lib/skylight/metrics/process_cpu_gauge.rb +0 -65
  45. data/lib/skylight/metrics/process_mem_gauge.rb +0 -34
  46. data/lib/skylight/util/conversions.rb +0 -9
  47. data/lib/skylight/util/queue.rb +0 -96
  48. data/lib/skylight/util/task.rb +0 -172
  49. data/lib/skylight/util/uniform_sample.rb +0 -63
  50. data/lib/skylight/worker.rb +0 -19
  51. data/lib/skylight/worker/builder.rb +0 -73
  52. data/lib/skylight/worker/collector.rb +0 -274
  53. data/lib/skylight/worker/connection.rb +0 -87
  54. data/lib/skylight/worker/connection_set.rb +0 -56
  55. data/lib/skylight/worker/embedded.rb +0 -24
  56. data/lib/skylight/worker/metrics_reporter.rb +0 -104
  57. data/lib/skylight/worker/server.rb +0 -336
  58. data/lib/skylight/worker/standalone.rb +0 -421
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1cf63055157626891e0d09101b21221a4d18406f
4
- data.tar.gz: df489cf0c01303baf4ea5636c4fbcf40f30fa690
3
+ metadata.gz: c87ab5e9bed0411324b945f3d9b922cd432df9af
4
+ data.tar.gz: 3855aa5a3a8021f15f685d79926588656f1417db
5
5
  SHA512:
6
- metadata.gz: 7537c8005076587637aad255183d13755ea45b746ce331635990bb18f6e12a52b73394720b62370f34eb1e8f361284ab29e6dce13ba552c820110fa2e84584e8
7
- data.tar.gz: 29e0bfbd08c39ad41c426afafb717dd84483ea1beda96710ee9bcc7abc1694a4f20ab3544d3cf26dfe7f028eca174d4ad8ffa6381ffabe3343477190fa3d6e72
6
+ metadata.gz: 1077014bd4ef7b5f9b522a20d2a85cc7f9b7025a4537214e9b341514fd35c5a2db7eb93b1527fbefb334fe5eed1bbdaec566c7986407ef70a380cc6bab0a1d7b
7
+ data.tar.gz: 22addeda25ebf8ea1e250a65e68b026c93cf0ea26a4016db54cd3f1387c67c4941b71cadfb461fef4b10b6680a1e86f61ccbad65ee18747107b84e1c81fc26a1
@@ -1,7 +1,3 @@
1
- ## 0.3.21 (October 8, 2014)
2
-
3
- * [BUGFIX] Skylight crashing on start won't crash entire app
4
-
5
1
  ## 0.3.20 (September 3, 2014)
6
2
 
7
3
  * [BUGFIX] Fix app name fetching on Windows for `skylight setup`
@@ -1,34 +1,27 @@
1
+ require 'rbconfig'
1
2
  require 'mkmf'
2
3
  require 'yaml'
3
4
  require 'logger'
5
+ require 'fileutils'
4
6
 
5
- # Must require 'rubygems/platform' vs. just requiring 'rubygems' to avoid a
6
- # stack overflow bug on ruby 1.9.2.
7
- require 'rubygems/platform'
7
+ $:.unshift File.expand_path("../../lib", __FILE__)
8
+ require 'skylight/version'
9
+ require 'skylight/util/multi_io'
10
+ require 'skylight/util/native_ext_fetcher'
11
+ require 'skylight/util/platform'
8
12
 
9
- class MultiIO
10
- def initialize(*targets)
11
- @targets = targets
12
- end
13
-
14
- def write(*args)
15
- @targets.each {|t| t.write(*args)}
16
- end
17
-
18
- def close
19
- @targets.each(&:close)
20
- end
21
- end
22
-
23
- log_file = File.open(File.expand_path("../install.log", __FILE__), "a")
24
- LOG = Logger.new(MultiIO.new(STDOUT, log_file))
13
+ include Skylight::Util
25
14
 
26
- SKYLIGHT_REQUIRED = ENV.key?("SKYLIGHT_REQUIRED") && ENV['SKYLIGHT_REQUIRED'] !~ /^false$/i
15
+ SKYLIGHT_INSTALL_LOG = File.expand_path("../install.log", __FILE__)
16
+ SKYLIGHT_REQUIRED = ENV.key?("SKYLIGHT_REQUIRED") && ENV['SKYLIGHT_REQUIRED'] !~ /^false$/i
17
+ SKYLIGHT_FETCH_LIB = !ENV.key?('SKYLIGHT_FETCH_LIB') || ENV['SKYLIGHT_FETCH_LIB'] !~ /^false$/i
27
18
 
28
- require_relative '../lib/skylight/version'
29
- require_relative '../lib/skylight/util/native_ext_fetcher'
19
+ # Directory where skylight.h exists
20
+ SKYLIGHT_HDR_PATH = ENV['SKYLIGHT_HDR_PATH'] || ENV['SKYLIGHT_LIB_PATH'] || '.'
21
+ SKYLIGHT_LIB_PATH = ENV['SKYLIGHT_LIB_PATH'] || File.expand_path("../../lib/skylight/native/#{Platform.tuple}", __FILE__)
30
22
 
31
- include Skylight::Util
23
+ # Setup logger
24
+ LOG = Logger.new(MultiIO.new(STDOUT, File.open(SKYLIGHT_INSTALL_LOG, 'a')))
32
25
 
33
26
  # Handles terminating in the case of a failure. If we have a bug, we do not
34
27
  # want to break our customer's deploy, but extconf.rb requires a Makefile to be
@@ -49,10 +42,29 @@ def fail(msg, type=:error)
49
42
  end
50
43
  end
51
44
 
52
- libskylight_a = File.expand_path('../libskylight.a', __FILE__)
53
- libskylight_yml = File.expand_path('../libskylight.yml', __FILE__)
45
+ #
46
+ # === Setup paths
47
+ #
48
+ root = File.expand_path('../', __FILE__)
49
+ hdrpath = File.expand_path(SKYLIGHT_HDR_PATH)
50
+ libpath = File.expand_path(SKYLIGHT_LIB_PATH)
51
+ libskylight = File.expand_path("libskylight.#{Platform.libext}", libpath)
52
+ libskylight_yml = File.expand_path('libskylight.yml', root)
53
+ skylight_dlopen_h = File.expand_path("skylight_dlopen.h", hdrpath)
54
+ skylight_dlopen_c = File.expand_path("skylight_dlopen.c", hdrpath)
55
+
56
+ LOG.info "SKYLIGHT_HDR_PATH=#{hdrpath}; SKYLIGHT_LIB_PATH=#{libpath}"
57
+
58
+ LOG.info "file exists; path=#{libskylight}" if File.exists?(libskylight)
59
+ LOG.info "file exists; path=#{skylight_dlopen_c}" if File.exists?(skylight_dlopen_c)
60
+ LOG.info "file exists; path=#{skylight_dlopen_h}" if File.exists?(skylight_dlopen_h)
61
+
62
+ # If libskylight is not present, fetch it
63
+ if !File.exist?(libskylight) && !File.exist?(skylight_dlopen_c) && !File.exist?(skylight_dlopen_h)
64
+ if !SKYLIGHT_FETCH_LIB
65
+ fail "libskylight.#{LIBEXT} not found -- remote download disabled; aborting install"
66
+ end
54
67
 
55
- unless File.exist?(libskylight_a)
56
68
  # Ensure that libskylight.yml is present and load it
57
69
  unless File.exist?(libskylight_yml)
58
70
  fail "`#{libskylight_yml}` does not exist"
@@ -70,27 +82,40 @@ unless File.exist?(libskylight_a)
70
82
  fail "libskylight checksums missing from `#{libskylight_yml}`"
71
83
  end
72
84
 
73
- platform = Gem::Platform.local
74
- arch = "#{platform.os}-#{platform.cpu}"
75
-
76
- unless checksum = checksums[arch]
85
+ unless checksum = checksums[Platform.tuple]
77
86
  fail "no checksum entry for requested architecture -- " \
78
87
  "this probably means the requested architecture is not supported; " \
79
- "arch=#{arch}; available=#{checksums.keys}", :info
88
+ "platform=#{Platform.tuple}; available=#{checksums.keys}", :info
80
89
  end
81
90
 
82
91
  begin
83
92
  res = NativeExtFetcher.fetch(
84
- version: version,
85
- target: libskylight_a,
93
+ version: version,
94
+ target: hdrpath,
86
95
  checksum: checksum,
87
- arch: arch,
96
+ arch: Platform.tuple,
88
97
  required: SKYLIGHT_REQUIRED,
89
- logger: LOG)
98
+ platform: Platform.tuple,
99
+ logger: LOG)
90
100
 
91
101
  unless res
92
102
  fail "could not fetch archive -- aborting skylight native extension build"
93
103
  end
104
+
105
+ # Move skylightd & libskylight to appropriate directory
106
+ if hdrpath != libpath
107
+ # Ensure the directory is present
108
+ FileUtils.mkdir_p libpath
109
+
110
+ # Move
111
+ FileUtils.mv "#{hdrpath}/libskylight.#{Platform.libext}",
112
+ "#{libpath}/libskylight.#{Platform.libext}",
113
+ :force => true
114
+
115
+ FileUtils.mv "#{hdrpath}/skylightd",
116
+ "#{libpath}/skylightd",
117
+ :force => true
118
+ end
94
119
  rescue => e
95
120
  fail "unable to fetch native extension; msg=#{e.message}\n#{e.backtrace.join("\n")}"
96
121
  end
@@ -98,23 +123,43 @@ end
98
123
 
99
124
  #
100
125
  #
101
- # ===== By this point, libskylight.a is present =====
126
+ # ===== By this point, libskylight is present =====
102
127
  #
103
128
  #
104
129
 
105
- have_header 'dlfcn.h'
130
+ def find_file(file, root = nil)
131
+ path = File.expand_path(file, root || '.')
132
+
133
+ unless File.exist?(path)
134
+ fail "#{file} missing; path=#{root}"
135
+ end
136
+ end
137
+
138
+ # Flag -std=c99 required for older build systems
139
+ $CFLAGS << " -std=c99 -pedantic" # -Wall
140
+ $VPATH << libpath
106
141
 
107
- find_header("rust_support/ruby.h", ".") or fail "could not find rust support header"
108
- find_library("skylight", "factory", ".") or fail "could not find skylight library"
142
+ # Where the ruby binding src is
143
+ SRC_PATH = File.expand_path('..', __FILE__)
109
144
 
110
- $CFLAGS << " -Werror"
111
- if RbConfig::CONFIG["arch"] =~ /darwin(\d+)?/
112
- $LDFLAGS << " -lpthread"
113
- else
114
- $LDFLAGS << " -Wl,--version-script=skylight.map"
115
- $LDFLAGS << " -lrt -ldl -lm -lpthread"
145
+ $srcs = Dir[File.expand_path("*.c", SRC_PATH)].map { |f| File.basename(f) }
146
+
147
+ # If the native agent support files were downloaded to a different directory,
148
+ # explicitly the file to the list of sources.
149
+ unless $srcs.include?('skylight_dlopen.c')
150
+ $srcs << "skylight_dlopen.c" # From libskylight dist
116
151
  end
117
152
 
118
- CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
153
+ # Make sure that the files are present
154
+ find_file 'skylight_dlopen.h', hdrpath
155
+ find_file 'skylight_dlopen.c', hdrpath
156
+ find_header 'skylight_dlopen.h', hdrpath
157
+ have_header 'dlfcn.h' or fail "could not create Makefile; dlfcn.h missing"
158
+
159
+ # For escaping the GVL
160
+ unless have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
161
+ have_func('rb_thread_blocking_region') or abort "Ruby is unexpectedly missing rb_thread_blocking_region. This should not happen."
162
+ end
119
163
 
120
- create_makefile 'skylight_native', '.' or fail "could not create makefile"
164
+ # TODO: Compute the relative path to the location
165
+ create_makefile 'skylight_native', File.expand_path('..', __FILE__) # or fail "could not create makefile"
@@ -1,6 +1,6 @@
1
1
  ---
2
- version: "dfa09f3"
2
+ version: "0.4.0-278b96b"
3
3
  checksums:
4
- linux-x86_64: "be6c610564c66e2a098e7c22226ac879cc970bac252b2534a11b556197f2efca"
5
- linux-x86: "2113e80b8afddf5f00c81590c8cbcfbb6ecaf9dbdec950eca06bb11ed1456351"
6
-
4
+ x86-linux: "00845099a2e69fc67fcd6d23bcdcc55ff7c724b1a9c0ffb00dcdca9f6190eb09"
5
+ x86_64-linux: "07dd625358a195ff2851c7aa58626d491809e48845792eb0811a1dc4a875b62d"
6
+ x86_64-darwin: "e8a3217bd4c5b6c5ad0193815e31a31d7632c59e27db4cf293ceccf8e12f39bb"
@@ -1,415 +1,377 @@
1
- #include <skylight.h>
1
+ #include <dlfcn.h>
2
2
  #include <ruby.h>
3
+ #include <skylight_dlopen.h>
3
4
 
4
5
  #ifdef HAVE_RUBY_ENCODING_H
5
6
  #include <ruby/encoding.h>
6
7
  #endif
7
8
 
8
- /**
9
- * Ruby helpers
10
- */
11
-
12
- #define SERIALIZE(MSG) \
13
- ({ \
14
- VALUE ret; \
15
- size_t size; \
16
- RustSerializer serializer; \
17
- \
18
- if (!MSG) { \
19
- rb_raise(rb_eRuntimeError, "No "#MSG" message to serialize"); \
20
- } \
21
- else { \
22
- CHECK_FFI(skylight_ ## MSG ## _get_serializer(MSG, &serializer), "could not get serializer for "#MSG); \
23
- \
24
- CHECK_FFI(skylight_serializer_get_serialized_size(serializer, &size), "could not get serialized size for "#MSG); \
25
- ret = rb_str_new(NULL, size); \
26
- \
27
- CHECK_FFI(skylight_ ## MSG ## _serialize(MSG, serializer, STR2SLICE(ret)), "could not serialize "#MSG); \
28
- skylight_serializer_free(serializer); \
29
- } \
30
- \
31
- skylight_ ## MSG ## _free(MSG); \
32
- ret; \
9
+ #define TO_S(VAL) \
10
+ RSTRING_PTR(rb_funcall(VAL, rb_intern("to_s"), 0))
11
+
12
+ #define CHECK_TYPE(VAL, T) \
13
+ do { \
14
+ if (TYPE(VAL) != T) { \
15
+ rb_raise(rb_eArgError, "expected " #VAL " to be " #T " but was '%s' (%s [%i])", \
16
+ TO_S(VAL), rb_obj_classname(VAL), TYPE(VAL)); \
17
+ return Qnil; \
18
+ } \
19
+ } while(0)
20
+
21
+ #define CHECK_NUMERIC(VAL) \
22
+ do { \
23
+ if (TYPE(VAL) != T_BIGNUM && \
24
+ TYPE(VAL) != T_FIXNUM) { \
25
+ rb_raise(rb_eArgError, "expected " #VAL " to be numeric but was '%s' (%s [%i])", \
26
+ TO_S(VAL), rb_obj_classname(VAL), TYPE(VAL)); \
27
+ return Qnil; \
28
+ } \
29
+ } while(0) \
30
+
31
+ #define BUF2STR(buf) \
32
+ ({ \
33
+ sky_buf_t b = (buf); \
34
+ VALUE str = rb_str_new(b.data, b.len); \
35
+ rb_enc_associate(str, rb_utf8_encoding()); \
36
+ str; \
33
37
  })
34
38
 
35
- /**
36
- * Ruby types defined here
37
- */
38
-
39
- VALUE rb_mSkylight;
40
- VALUE rb_mUtil;
41
- VALUE rb_cClock;
42
- VALUE rb_cHello;
43
- VALUE rb_cError;
44
- VALUE rb_cTrace;
45
- VALUE rb_cBatch;
46
-
47
- /**
48
- * class Skylight::Util::Clock
49
- */
39
+ #define STR2BUF(str) \
40
+ ({ \
41
+ sky_buf_t buf; \
42
+ VALUE s = (str); \
43
+ buf.data = RSTRING_PTR(s); \
44
+ buf.len = RSTRING_LEN(s); \
45
+ buf; \
46
+ })
50
47
 
51
- static VALUE clock_high_res_time(VALUE self) {
52
- uint64_t time;
53
- CHECK_FFI(skylight_high_res_time(&time), "Could not get high-res time");
54
- return ULL2NUM(time);
55
- }
48
+ #define CHECK_FFI(success, message) \
49
+ do { \
50
+ if ((success) < 0 ) { \
51
+ rb_raise(rb_eRuntimeError, message); \
52
+ return Qnil; \
53
+ } \
54
+ } while(0)
55
+
56
+ #define My_Struct(name, Type, msg) \
57
+ Get_Struct(name, self, Type, msg); \
58
+
59
+ #define Transfer_My_Struct(name, Type, msg) \
60
+ My_Struct(name, Type, msg); \
61
+ DATA_PTR(self) = NULL; \
62
+
63
+ #define Transfer_Struct(name, obj, Type, msg) \
64
+ Get_Struct(name, obj, Type, msg); \
65
+ DATA_PTR(obj) = NULL; \
66
+
67
+ #define Get_Struct(name, obj, Type, msg) \
68
+ Type name; \
69
+ Data_Get_Struct(obj, Type, name); \
70
+ if (name == NULL) { \
71
+ rb_raise(rb_eRuntimeError, "%s", msg); \
72
+ }
56
73
 
57
74
  /**
58
- * class Skylight::Hello
75
+ * Ruby GVL helpers
59
76
  */
60
77
 
61
- static VALUE hello_new(VALUE klass, VALUE version, VALUE config) {
62
- RustHello hello;
63
-
64
- CHECK_TYPE(version, T_STRING);
65
- CHECK_TYPE(config, T_FIXNUM);
78
+ #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
79
+ defined(HAVE_RUBY_THREAD_H)
66
80
 
67
- CHECK_FFI(skylight_hello_new(STR2SLICE(version), FIX2INT(config), &hello), "could not create new Hello");
81
+ // Ruby 2.0+
82
+ #include <ruby/thread.h>
83
+ typedef void* (*blocking_fn_t)(void*);
84
+ #define WITHOUT_GVL(fn, a) \
85
+ rb_thread_call_without_gvl((blocking_fn_t)(fn), (a), 0, 0)
68
86
 
69
- return Data_Wrap_Struct(rb_cHello, NULL, skylight_hello_free, hello);
70
- }
87
+ // Ruby 1.9
88
+ #elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
71
89
 
72
- static VALUE hello_load(VALUE self, VALUE protobuf) {
73
- CHECK_TYPE(protobuf, T_STRING);
90
+ typedef VALUE (*blocking_fn_t)(void*);
91
+ #define WITHOUT_GVL(fn, a) \
92
+ rb_thread_blocking_region((blocking_fn_t)(fn), (a), 0, 0)
74
93
 
75
- RustHello hello;
76
94
 
77
- CHECK_FFI(skylight_hello_load(STR2SLICE(protobuf), &hello), "Could not load Hello");
78
-
79
- return Data_Wrap_Struct(rb_cHello, NULL, skylight_hello_free, hello);
80
- }
81
-
82
- static const char* freedHello = "You can't do anything with a Hello once it's been serialized";
83
-
84
- static VALUE hello_get_version(VALUE self) {
85
- RustSlice slice;
95
+ #endif
86
96
 
87
- My_Struct(hello, RustHello, freedHello);
88
97
 
89
- CHECK_FFI(skylight_hello_get_version(hello, &slice), "could not get version from Hello");
98
+ /**
99
+ * Ruby types defined here
100
+ */
90
101
 
91
- return SLICE2STR(slice);
92
- }
102
+ VALUE rb_mSkylight;
103
+ VALUE rb_mUtil;
104
+ VALUE rb_cClock;
105
+ VALUE rb_cTrace;
106
+ VALUE rb_cInstrumenter;
93
107
 
94
- static VALUE hello_cmd_length(VALUE self) {
95
- My_Struct(hello, RustHello, freedHello);
108
+ static const char* no_instrumenter_msg =
109
+ "Instrumenter not currently running";
96
110
 
97
- uint32_t length;
111
+ static const char* consumed_trace_msg =
112
+ "Trace objects cannot be used once it has been submitted to the instrumenter";
98
113
 
99
- CHECK_FFI(skylight_hello_cmd_length(hello, &length), "Could not get length of Hello commands");
114
+ static VALUE
115
+ load_libskylight(VALUE klass, VALUE path) {
116
+ int res;
100
117
 
101
- return UINT2NUM(length);
102
- }
118
+ CHECK_TYPE(path, T_STRING);
103
119
 
104
- static VALUE hello_add_cmd_part(VALUE self, VALUE rb_string) {
105
- My_Struct(hello, RustHello, freedHello);
120
+ // Already loaded
121
+ if (sky_hrtime != 0) {
122
+ return Qnil;
123
+ }
106
124
 
107
- CHECK_TYPE(rb_string, T_STRING);
125
+ res = sky_load_libskylight(StringValueCStr(path));
108
126
 
109
- CHECK_FFI(skylight_hello_cmd_add(hello, STR2SLICE(rb_string)), "Could not add command part to Hello");
127
+ if (res < 0) {
128
+ rb_raise(rb_eRuntimeError, "[SKYLIGHT] dlerror; msg=%s", dlerror());
129
+ return Qnil;
130
+ }
110
131
 
111
132
  return Qnil;
112
133
  }
113
134
 
114
- static VALUE hello_cmd_get(VALUE self, VALUE rb_off) {
115
- uint32_t off;
116
- RustSlice slice;
117
- My_Struct(hello, RustHello, freedHello);
118
-
119
- CHECK_TYPE(rb_off, T_FIXNUM);
120
- off = FIX2INT(rb_off);
121
-
122
- CHECK_FFI(skylight_hello_get_cmd(hello, off, &slice), "Could not get command part from Hello");
123
-
124
- return SLICE2STR(slice);
125
- }
135
+ /*
136
+ *
137
+ * class Skylight::Util::Clock
138
+ *
139
+ */
126
140
 
127
- static VALUE hello_serialize(VALUE self) {
128
- Transfer_My_Struct(hello, RustHello, freedHello);
129
- return SERIALIZE(hello);
141
+ static VALUE
142
+ clock_high_res_time(VALUE self) {
143
+ return ULL2NUM(sky_hrtime());
130
144
  }
131
145
 
132
- /**
133
- * class Skylight::Error
146
+ /*
147
+ *
148
+ * class Skylight::Instrumenter
149
+ *
134
150
  */
135
151
 
136
- static VALUE error_new(VALUE klass, VALUE group, VALUE description) {
137
- RustError error;
138
-
139
- CHECK_TYPE(group, T_STRING);
140
- CHECK_TYPE(description, T_STRING);
152
+ static VALUE
153
+ instrumenter_new(VALUE klass, VALUE rb_env) {
154
+ sky_instrumenter_t* instrumenter;
155
+ sky_buf_t env[256];
141
156
 
142
- CHECK_FFI(skylight_error_new(STR2SLICE(group), STR2SLICE(description), &error), "could not create new Error");
157
+ CHECK_TYPE(rb_env, T_ARRAY);
143
158
 
144
- return Data_Wrap_Struct(rb_cError, NULL, skylight_error_free, error);
145
- }
146
-
147
- static VALUE error_load(VALUE self, VALUE protobuf) {
148
- CHECK_TYPE(protobuf, T_STRING);
149
-
150
- RustError error;
151
-
152
- CHECK_FFI(skylight_error_load(STR2SLICE(protobuf), &error), "Could not load Error");
159
+ if (RARRAY_LEN(rb_env) >= 256) {
160
+ rb_raise(rb_eArgError, "environment array too long");
161
+ return Qnil;
162
+ }
153
163
 
154
- return Data_Wrap_Struct(rb_cError, NULL, skylight_error_free, error);
155
- }
164
+ int i;
165
+ int envc = (int) RARRAY_LEN(rb_env);
156
166
 
157
- static const char* freedError = "You can't do anything with a Error once it's been serialized";
167
+ for (i = 0; i < envc; ++i) {
168
+ VALUE val = rb_ary_entry(rb_env, i);
158
169
 
159
- static VALUE error_get_group(VALUE self) {
160
- RustSlice slice;
170
+ // Make sure it is a string
171
+ CHECK_TYPE(val, T_STRING);
161
172
 
162
- My_Struct(error, RustError, freedError);
173
+ env[i] = STR2BUF(val);
174
+ }
163
175
 
164
- CHECK_FFI(skylight_error_get_group(error, &slice), "could not get group from Error");
176
+ CHECK_FFI(
177
+ sky_instrumenter_new(env, envc, &instrumenter),
178
+ "failed to initialize instrumenter");
165
179
 
166
- return SLICE2STR(slice);
180
+ return Data_Wrap_Struct(rb_cInstrumenter, NULL, sky_instrumenter_free, instrumenter);
167
181
  }
168
182
 
169
- static VALUE error_get_description(VALUE self) {
170
- RustSlice slice;
183
+ static void*
184
+ instrumenter_start_nogvl(sky_instrumenter_t* instrumenter) {
185
+ /*
186
+ * Cannot use CHECK_FFI in here
187
+ */
171
188
 
172
- My_Struct(error, RustError, freedError);
189
+ if (sky_instrumenter_start(instrumenter) == 0) {
190
+ return (void*) Qtrue;
191
+ }
192
+ else {
193
+ return (void*) Qfalse;
194
+ }
195
+ }
173
196
 
174
- CHECK_FFI(skylight_error_get_description(error, &slice), "could not get description from Error");
197
+ static VALUE
198
+ instrumenter_start(VALUE self) {
199
+ My_Struct(instrumenter, sky_instrumenter_t*, no_instrumenter_msg);
175
200
 
176
- return SLICE2STR(slice);
201
+ return (VALUE) WITHOUT_GVL(instrumenter_start_nogvl, instrumenter);
177
202
  }
178
203
 
179
- static VALUE error_get_details(VALUE self) {
180
- RustSlice slice;
181
-
182
- My_Struct(error, RustError, freedError);
204
+ static VALUE
205
+ instrumenter_stop(VALUE self) {
206
+ My_Struct(instrumenter, sky_instrumenter_t*, no_instrumenter_msg);
183
207
 
184
- CHECK_FFI(skylight_error_get_details(error, &slice), "could not get details from Error");
208
+ CHECK_FFI(
209
+ sky_instrumenter_stop(instrumenter),
210
+ "native Instrumenter#stop failed");
185
211
 
186
- return SLICE2STR(slice);
212
+ return Qnil;
187
213
  }
188
214
 
189
- static VALUE error_set_details(VALUE self, VALUE details) {
190
- CHECK_TYPE(details, T_STRING);
215
+ static VALUE
216
+ instrumenter_submit_trace(VALUE self, VALUE rb_trace) {
217
+ My_Struct(instrumenter, sky_instrumenter_t*, no_instrumenter_msg);
218
+ Transfer_Struct(trace, rb_trace, sky_trace_t*, consumed_trace_msg);
191
219
 
192
- My_Struct(error, RustError, freedError);
193
-
194
- CHECK_FFI(skylight_error_set_details(error, STR2SLICE(details)), "could not set Error details");
220
+ CHECK_FFI(
221
+ sky_instrumenter_submit_trace(instrumenter, trace),
222
+ "native Instrumenter#submit_trace failed");
195
223
 
196
224
  return Qnil;
197
225
  }
198
226
 
199
- static VALUE error_serialize(VALUE self) {
200
- Transfer_My_Struct(error, RustError, freedError);
201
- return SERIALIZE(error);
202
- }
203
-
204
- /**
205
- * Skylight::Trace
227
+ /*
228
+ *
229
+ * class Skylight::Trace
230
+ *
206
231
  */
207
232
 
208
- static const char* freedTrace = "You can't do anything with a Trace once it's been serialized or moved into a Batch";
209
-
210
- static VALUE trace_new(VALUE self, VALUE started_at, VALUE uuid) {
211
- CHECK_NUMERIC(started_at);
233
+ static VALUE
234
+ trace_new(VALUE klass, VALUE start, VALUE uuid, VALUE endpoint) {
235
+ CHECK_NUMERIC(start);
212
236
  CHECK_TYPE(uuid, T_STRING);
237
+ CHECK_TYPE(endpoint, T_STRING);
213
238
 
214
- RustTrace trace;
239
+ sky_trace_t* trace;
215
240
 
216
- CHECK_FFI(skylight_trace_new(NUM2ULL(started_at), STR2SLICE(uuid), &trace), "Could not created Trace");
241
+ CHECK_FFI(
242
+ sky_trace_new(NUM2ULL(start), STR2BUF(uuid), STR2BUF(endpoint), &trace),
243
+ "native Trace#new failed");
217
244
 
218
- return Data_Wrap_Struct(rb_cTrace, NULL, skylight_trace_free, trace);
245
+ return Data_Wrap_Struct(rb_cTrace, NULL, sky_trace_free, trace);
219
246
  }
220
247
 
221
- static VALUE trace_name_from_serialized(VALUE self, VALUE protobuf) {
222
- CHECK_TYPE(protobuf, T_STRING);
223
-
224
- RustString trace_name;
248
+ static VALUE
249
+ trace_get_started_at(VALUE self) {
250
+ uint64_t start;
251
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
225
252
 
226
- CHECK_FFI(skylight_trace_name_from_serialized_into_new_buffer(STR2SLICE(protobuf), &trace_name), "Could not read name from serialized Trace");
253
+ CHECK_FFI(
254
+ sky_trace_start(trace, &start),
255
+ "native Trace#started_at failed");
227
256
 
228
- return SKYLIGHT_RUSTSTR2STR(trace_name);
257
+ return ULL2NUM(start);
229
258
  }
230
259
 
231
- static VALUE trace_get_started_at(VALUE self) {
232
- My_Struct(trace, RustTrace, freedTrace);
260
+ static VALUE
261
+ trace_get_endpoint(VALUE self) {
262
+ sky_buf_t endpoint;
263
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
233
264
 
234
- uint64_t started_at;
265
+ CHECK_FFI(
266
+ sky_trace_endpoint(trace, &endpoint),
267
+ "native Trace#endpoint failed");
235
268
 
236
- CHECK_FFI(skylight_trace_get_started_at(trace, &started_at), "Could not get Trace started_at");
237
-
238
- return ULL2NUM(started_at);
269
+ return BUF2STR(endpoint);
239
270
  }
240
271
 
241
- static VALUE trace_set_name(VALUE self, VALUE name) {
242
- CHECK_TYPE(name, T_STRING);
243
-
244
- My_Struct(trace, RustTrace, freedTrace);
245
- CHECK_FFI(skylight_trace_set_name(trace, STR2SLICE(name)), "Could not set Trace name");
246
- return Qnil;
247
- }
272
+ static VALUE
273
+ trace_set_endpoint(VALUE self, VALUE endpoint) {
274
+ CHECK_TYPE(endpoint, T_STRING);
275
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
248
276
 
249
- static VALUE trace_get_name(VALUE self) {
250
- My_Struct(trace, RustTrace, freedTrace);
277
+ CHECK_FFI(
278
+ sky_trace_set_endpoint(trace, STR2BUF(endpoint)),
279
+ "native Trace#set_endpoint failed");
251
280
 
252
- RustSlice string;
253
- if (skylight_trace_get_name(trace, &string)) {
254
- return SLICE2STR(string);
255
- } else {
256
- return Qnil;
257
- }
281
+ return Qnil;
258
282
  }
259
283
 
260
- static VALUE trace_get_uuid(VALUE self) {
261
- My_Struct(trace, RustTrace, freedTrace);
284
+ static VALUE
285
+ trace_get_uuid(VALUE self) {
286
+ sky_buf_t uuid;
287
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
262
288
 
263
- RustSlice slice;
289
+ CHECK_FFI(
290
+ sky_trace_uuid(trace, &uuid),
291
+ "native Trace#uuid failed");
264
292
 
265
- CHECK_FFI(skylight_trace_get_uuid(trace, &slice), "Could not get uuid from Trace");
266
-
267
- return SLICE2STR(slice);
293
+ return BUF2STR(uuid);
268
294
  }
269
295
 
270
- static VALUE trace_start_span(VALUE self, VALUE time, VALUE category) {
296
+ static VALUE
297
+ trace_start_span(VALUE self, VALUE time, VALUE category) {
271
298
  uint32_t span;
272
- My_Struct(trace, RustTrace, freedTrace);
299
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
273
300
 
274
301
  CHECK_NUMERIC(time);
275
302
  CHECK_TYPE(category, T_STRING);
276
303
 
277
- CHECK_FFI(skylight_trace_start_span(trace, NUM2ULL(time), STR2SLICE(category), &span), "Could not start Span");
304
+ CHECK_FFI(
305
+ sky_trace_instrument(trace, NUM2ULL(time), STR2BUF(category), &span),
306
+ "native Trace#start_span failed");
278
307
 
279
308
  return UINT2NUM(span);
280
309
  }
281
310
 
282
- static VALUE trace_stop_span(VALUE self, VALUE span_index, VALUE time) {
283
- My_Struct(trace, RustTrace, freedTrace);
311
+ static VALUE
312
+ trace_stop_span(VALUE self, VALUE span, VALUE time) {
313
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
284
314
 
285
315
  CHECK_NUMERIC(time);
286
- CHECK_TYPE(span_index, T_FIXNUM);
316
+ CHECK_TYPE(span, T_FIXNUM);
287
317
 
288
- CHECK_FFI(skylight_trace_stop_span(trace, FIX2UINT(span_index), NUM2ULL(time)), "Could not stop Span");
318
+ CHECK_FFI(
319
+ sky_trace_span_done(trace, FIX2UINT(span), NUM2ULL(time)),
320
+ "native Trace#stop_span failed");
289
321
 
290
322
  return Qnil;
291
323
  }
292
324
 
293
- static VALUE trace_span_set_title(VALUE self, VALUE index, VALUE title) {
294
- My_Struct(trace, RustTrace, freedTrace);
325
+ static VALUE
326
+ trace_span_set_title(VALUE self, VALUE span, VALUE title) {
327
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
295
328
 
296
- CHECK_TYPE(index, T_FIXNUM);
329
+ CHECK_TYPE(span, T_FIXNUM);
297
330
  CHECK_TYPE(title, T_STRING);
298
331
 
299
- CHECK_FFI(skylight_trace_span_set_title(trace, NUM2LL(index), STR2SLICE(title)), "Could not set Span title");
300
-
301
- return Qnil;
302
- }
303
-
304
- static VALUE trace_span_set_description(VALUE self, VALUE index, VALUE description) {
305
- My_Struct(trace, RustTrace, freedTrace);
306
-
307
- CHECK_TYPE(index, T_FIXNUM);
308
- CHECK_TYPE(description, T_STRING);
332
+ CHECK_FFI(
333
+ sky_trace_span_set_title(trace, FIX2UINT(span), STR2BUF(title)),
334
+ "native Trace#span_set_title failed");
309
335
 
310
- CHECK_FFI(skylight_trace_span_set_description(trace, NUM2LL(index), STR2SLICE(description)), "Could not set Span description");
311
336
  return Qnil;
312
337
  }
313
338
 
314
- static VALUE trace_serialize(VALUE self) {
315
- Transfer_My_Struct(trace, RustTrace, freedTrace);
316
- return SERIALIZE(trace);
317
- }
318
-
319
- /**
320
- * class Skylight::Batch
321
- */
322
-
323
- static const char* freedBatch = "You can't do anything with a Batch once it's been serialized";
324
-
325
- VALUE batch_new(VALUE klass, VALUE rb_timestamp, VALUE rb_hostname) {
326
- CHECK_NUMERIC(rb_timestamp);
327
-
328
- RustSlice* hostname = NULL;
329
- RustSlice tmp;
330
-
331
- uint32_t timestamp = (uint32_t) NUM2ULONG(rb_timestamp);
332
-
333
- if (rb_hostname != Qnil) {
334
- CHECK_TYPE(rb_hostname, T_STRING);
335
- tmp = STR2SLICE(rb_hostname);
336
- hostname = &tmp;
337
- }
338
-
339
- RustBatch batch;
340
-
341
- CHECK_FFI(skylight_batch_new(timestamp, hostname, &batch), "Could not create Batch");
342
-
343
- return Data_Wrap_Struct(rb_cBatch, NULL, skylight_batch_free, batch);
344
- }
345
-
346
- VALUE batch_set_endpoint_count(VALUE self, VALUE rb_endpoint_name, VALUE rb_count) {
347
- CHECK_TYPE(rb_endpoint_name, T_STRING);
348
- CHECK_NUMERIC(rb_count);
339
+ static VALUE
340
+ trace_span_set_description(VALUE self, VALUE span, VALUE desc) {
341
+ My_Struct(trace, sky_trace_t*, consumed_trace_msg);
349
342
 
350
- My_Struct(batch, RustBatch, freedBatch);
343
+ CHECK_TYPE(span, T_FIXNUM);
344
+ CHECK_TYPE(desc, T_STRING);
351
345
 
352
- CHECK_FFI(skylight_batch_set_endpoint_count(batch, STR2SLICE(rb_endpoint_name), NUM2ULL(rb_count)), "Could not set count for Endpoint in Batch");
346
+ CHECK_FFI(
347
+ sky_trace_span_set_desc(trace, FIX2UINT(span), STR2BUF(desc)),
348
+ "native Trace#span_set_description failed");
353
349
 
354
350
  return Qnil;
355
351
  }
356
352
 
357
- VALUE batch_move_in(VALUE self, VALUE rb_string) {
358
- CHECK_TYPE(rb_string, T_STRING);
359
-
360
- My_Struct(batch, RustBatch, freedBatch);
361
-
362
- CHECK_FFI(skylight_batch_move_in(batch, STR2SLICE(rb_string)), "Could not add serialized Trace to Batch");
363
-
364
- return Qnil;
365
- }
366
-
367
- VALUE batch_serialize(VALUE self) {
368
- Transfer_My_Struct(batch, RustBatch, freedBatch);
369
- return SERIALIZE(batch);
370
- }
371
-
372
353
  void Init_skylight_native() {
373
354
  rb_mSkylight = rb_define_module("Skylight");
374
- rb_mUtil = rb_define_module_under(rb_mSkylight, "Util");
355
+ rb_define_singleton_method(rb_mSkylight, "load_libskylight", load_libskylight, 1);
375
356
 
357
+ rb_mUtil = rb_define_module_under(rb_mSkylight, "Util");
376
358
  rb_cClock = rb_define_class_under(rb_mUtil, "Clock", rb_cObject);
377
359
  rb_define_method(rb_cClock, "native_hrtime", clock_high_res_time, 0);
378
360
 
379
- rb_cHello = rb_define_class_under(rb_mSkylight, "Hello", rb_cObject);
380
- rb_define_singleton_method(rb_cHello, "native_new", hello_new, 2);
381
- rb_define_singleton_method(rb_cHello, "native_load", hello_load, 1);
382
- rb_define_method(rb_cHello, "native_get_version", hello_get_version, 0);
383
- rb_define_method(rb_cHello, "native_cmd_length", hello_cmd_length, 0);
384
- rb_define_method(rb_cHello, "native_add_cmd_part", hello_add_cmd_part, 1);
385
- rb_define_method(rb_cHello, "native_cmd_get", hello_cmd_get, 1);
386
- rb_define_method(rb_cHello, "native_serialize", hello_serialize, 0);
387
-
388
- rb_cError = rb_define_class_under(rb_mSkylight, "Error", rb_cObject);
389
- rb_define_singleton_method(rb_cError, "native_new", error_new, 2);
390
- rb_define_singleton_method(rb_cError, "native_load", error_load, 1);
391
- rb_define_method(rb_cError, "native_get_group", error_get_group, 0);
392
- rb_define_method(rb_cError, "native_get_description", error_get_description, 0);
393
- rb_define_method(rb_cError, "native_get_details", error_get_details, 0);
394
- rb_define_method(rb_cError, "native_set_details", error_set_details, 1);
395
- rb_define_method(rb_cError, "native_serialize", error_serialize, 0);
396
-
397
361
  rb_cTrace = rb_define_class_under(rb_mSkylight, "Trace", rb_cObject);
398
- rb_define_singleton_method(rb_cTrace, "native_new", trace_new, 2);
399
- rb_define_singleton_method(rb_cTrace, "native_name_from_serialized", trace_name_from_serialized, 1);
362
+ rb_define_singleton_method(rb_cTrace, "native_new", trace_new, 3);
400
363
  rb_define_method(rb_cTrace, "native_get_started_at", trace_get_started_at, 0);
401
- rb_define_method(rb_cTrace, "native_get_name", trace_get_name, 0);
402
- rb_define_method(rb_cTrace, "native_set_name", trace_set_name, 1);
364
+ rb_define_method(rb_cTrace, "native_get_endpoint", trace_get_endpoint, 0);
365
+ rb_define_method(rb_cTrace, "native_set_endpoint", trace_set_endpoint, 1);
403
366
  rb_define_method(rb_cTrace, "native_get_uuid", trace_get_uuid, 0);
404
- rb_define_method(rb_cTrace, "native_serialize", trace_serialize, 0);
405
367
  rb_define_method(rb_cTrace, "native_start_span", trace_start_span, 2);
406
368
  rb_define_method(rb_cTrace, "native_stop_span", trace_stop_span, 2);
407
369
  rb_define_method(rb_cTrace, "native_span_set_title", trace_span_set_title, 2);
408
370
  rb_define_method(rb_cTrace, "native_span_set_description", trace_span_set_description, 2);
409
371
 
410
- rb_cBatch = rb_define_class_under(rb_mSkylight, "Batch", rb_cObject);
411
- rb_define_singleton_method(rb_cBatch, "native_new", batch_new, 2);
412
- rb_define_method(rb_cBatch, "native_move_in", batch_move_in, 1);
413
- rb_define_method(rb_cBatch, "native_set_endpoint_count", batch_set_endpoint_count, 2);
414
- rb_define_method(rb_cBatch, "native_serialize", batch_serialize, 0);
372
+ rb_cInstrumenter = rb_define_class_under(rb_mSkylight, "Instrumenter", rb_cObject);
373
+ rb_define_singleton_method(rb_cInstrumenter, "native_new", instrumenter_new, 1);
374
+ rb_define_method(rb_cInstrumenter, "native_start", instrumenter_start, 0);
375
+ rb_define_method(rb_cInstrumenter, "native_stop", instrumenter_stop, 0);
376
+ rb_define_method(rb_cInstrumenter, "native_submit_trace", instrumenter_submit_trace, 1);
415
377
  }