skylight 0.3.21 → 0.4.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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
  }