skylight 6.0.4 → 7.0.0.beta

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b0217b6b6828530f0fe344fbb3ca9ada78c96188e30ebe6556b74e9a152b1d2
4
- data.tar.gz: 2b50af0d2954293733319ae585480329431a6000df515ba28f45e8a7cf9946e7
3
+ metadata.gz: e85fc890c72f6fdd61b4ce526da796e93b881204cc3a23c3aa49b2af79b102e6
4
+ data.tar.gz: c1b04bcba22ae003689ba594e7c84c256c498426e3dc8a0b1e52e662e2df0505
5
5
  SHA512:
6
- metadata.gz: 3bee5a6d0dcff8bcd132209bc48e726a25a3ecce65f4130c74bde52c9a4187cfcfe13358efd3ec8f8f4bbbca017204384e73be1ed71efbbf00a18f94fca3affb
7
- data.tar.gz: 2d799ddf111d8bb4caae235b29010620aa90fa4618e3de7dc9fab2ff7a68e61b4a0f642d45f58761942df55effa1b8c6daf2bafc043259a6767395ed9c45d8f7
6
+ metadata.gz: 6cf4914170bc6741a6afbbceea055ad430d9d0bc536d2d241540615e48ffd986ad03473399d0b930b19d462059398d158e0e100b9e90860944c409ab47f4d75d
7
+ data.tar.gz: cbd977277cdae972fd6421986defe7250b1b5c73eed724ab72a8f47a72f72c7a69fff7a94c056607fc675e9b3d2442bb50b778b0ccca72b86221e81980e3073b
data/CHANGELOG.md CHANGED
@@ -1,7 +1,22 @@
1
+ ## 7.0.0.beta (September 3, 2025)
2
+
3
+ - IMPROVEMENT Initial support for AWS Lambda
4
+ - BREAKING end support for Ruby 2.7 and 3.0
5
+ - BREAKING end support for Rails < 7.1
6
+ - BUGFIX Fix an issue handling deserialization errors in Delayed::Job
7
+ - IMPROVEMENT Support GraphQL >= 2.5
8
+ - IMPROVEMENT Ignore `Rails::HealthController` by default
9
+
10
+ ## 6.1.0.beta (June 11, 2024)
11
+
12
+ - [IMPROVEMENT] Initial support for parsing queries from activerecord-sqlserver-adapter
13
+
1
14
  ## 6.0.4 (February 23, 2024)
15
+
2
16
  - [IMPROVEMENT] Set "turbo-frame" in the request segment when making a Turbo-Frame request
3
17
 
4
18
  ## 6.0.3 (January 18, 2024)
19
+
5
20
  - [IMPROVEMENT] Remove an outdated "abbrev" requirement
6
21
 
7
22
  ## 6.0.2 (January 9, 2024)
@@ -9,10 +24,12 @@
9
24
  - [IMPROVEMENT] When using certain versions of Rubygems (< 3.4.9), some users experienced a Rubygems bug in which the wrong version of Psych native extensions were loaded during Skylight's native extension building. We have inlined the data needed to download libskylight, so YAML is no longer required during installation. Note that for existing versions of Skylight, this issue may also be corrected by updating Rubygems to at least 3.4.9.
10
25
 
11
26
  ## 6.0.1 (September 12, 2023)
27
+
12
28
  - [BUGFIX] Fix a logger message that could raise an error when I18n is misconfigured or unconfigured.
13
29
  - [BUGFIX] Fix an issue with proxy config in skylightd.
14
30
 
15
31
  ## 6.0.0 (September 11, 2023)
32
+
16
33
  - [BREAKING] End support for Ruby 2.6
17
34
  - The following libraries are no longer tested and are not guaranteed to work with Skylight 6:
18
35
  - Sinatra 1.x
@@ -30,6 +47,7 @@
30
47
  - [IMPROVEMENT] Better support for GraphQL versions >= 2.0.18.
31
48
 
32
49
  ## 5.3.5 (January 18, 2024)
50
+
33
51
  - [IMPROVEMENT] Remove an outdated "abbrev" requirement
34
52
 
35
53
  ## 5.3.4 (October 17, 2022)
data/ext/extconf.rb CHANGED
@@ -10,18 +10,17 @@ require "skylight/util/platform"
10
10
 
11
11
  GLIBC_MIN = 2.23
12
12
  GLIBC_V4_MIN = 2.15
13
-
14
13
  LIBSKYLIGHT_INFO = {
15
- "version" => "5.2.0-15d2f2b",
14
+ "version" => "6.0.0-beta-ec1a887",
16
15
  "checksums" => {
17
- "x86-linux" => "ae972e44ac926411971c7c2161f7b63d885108818bcdb9b67a34aef72650a01e",
18
- "x86_64-linux" => "385369da7811b7ab9a71990c873858a21fd0c44b2b44c480c269a5632d886e5f",
19
- "x86_64-linux-musl" => "a3404b9d02fd82dfc20bfa06889da79122626099a1aca0e3c009fe3724ba94b1",
20
- "x86_64-darwin" => "779198627e376d4bf281f484a8b5ed818a500439ffe57f965b3797c4eac0c096",
21
- "x86_64-freebsd" => "40fd09224f2ccd8d49c87eb9f27f6c4aa3b5e7d982f6c1c87de9b1038188e7ff",
22
- "aarch64-linux" => "855e3ac01054b35a7eefbfd764ee87b07b54055a9397b969f7c25d442e514319",
23
- "aarch64-linux-musl" => "59295e2a8183258aabaa9af7dbab222d3cd3fd2b22c287c3adf85f0d1669cb83",
24
- "aarch64-darwin" => "adc070c71413520afb7186b6c6c04e1149120965c1609a60fa2b427615b51cf9"
16
+ "x86-linux" => "0690d63cb7e249e3d74ad66a86bd886d75fb98650e3e2b029345c9b69d0931b2",
17
+ "x86_64-linux" => "dc97213f8f2aa86278dd8d239db3253ecd95d5daaafa5e825d8dfffa52033177",
18
+ "x86_64-linux-musl" => "963fc2515e3d91b80e2066d28c60ceabf40b88eec976eefa9c57f6be02e75b82",
19
+ "x86_64-darwin" => "79c16cfe98a5c0088175df8936eeeb46ee13fec2c9ecb0294d2622cb3c838666",
20
+ "x86_64-freebsd" => "be2e6d29f343a4c3dc90fc7d4a945fca67eaa062d35bcbca32ce130b022a2ba1",
21
+ "aarch64-linux" => "a3e5c72bbed189138c4350884cb59420deb9b68d0337340b6c2a7e4154e8d41a",
22
+ "aarch64-linux-musl" => "58282d7a638c8144aaee9ad5cb96ae667ea6f981a8ddbef566c8a618d7b82f8c",
23
+ "aarch64-darwin" => "fc4135413cda6130610e7a9c72b2a7af3e9db37107839b0bce7929b2ba55264b"
25
24
  }.freeze
26
25
  }.freeze
27
26
 
@@ -55,22 +55,22 @@ STR2BUF(VALUE str) {
55
55
  } \
56
56
  } while(0)
57
57
 
58
- #define My_Struct(name, Type, msg) \
59
- Get_Struct(name, self, Type, msg); \
58
+ #define Get_Struct(name, obj, Type, data_type, msg) \
59
+ TypedData_Get_Struct((obj), Type, data_type, name); \
60
+ if (name == NULL) { \
61
+ rb_raise(rb_eRuntimeError, "%s", msg); \
62
+ } \
60
63
 
61
- #define Transfer_My_Struct(name, Type, msg) \
62
- My_Struct(name, Type, msg); \
63
- DATA_PTR(self) = NULL; \
64
+ #define My_Struct(name, Type, data_type, msg) \
65
+ Get_Struct(name, self, Type, data_type, msg); \
64
66
 
65
- #define Transfer_Struct(name, obj, Type, msg) \
66
- Get_Struct(name, obj, Type, msg); \
67
- DATA_PTR(obj) = NULL; \
67
+ #define Transfer_My_Struct(name, Type, data_type, msg) \
68
+ My_Struct(name, Type, data_type, msg); \
69
+ DATA_PTR(self) = NULL; \
68
70
 
69
- #define Get_Struct(name, obj, Type, msg) \
70
- Data_Get_Struct(obj, Type, name); \
71
- if (name == NULL) { \
72
- rb_raise(rb_eRuntimeError, "%s", msg); \
73
- }
71
+ #define Transfer_Struct(name, obj, Type, data_type, msg) \
72
+ Get_Struct(name, obj, Type, data_type, msg); \
73
+ DATA_PTR(obj) = NULL; \
74
74
 
75
75
  /**
76
76
  * Ruby GVL helpers
@@ -106,6 +106,40 @@ static const char* no_instrumenter_msg =
106
106
  static const char* consumed_trace_msg =
107
107
  "Trace objects cannot be used once it has been submitted to the instrumenter";
108
108
 
109
+ size_t sky_trace_dsize(const void *ptr) {
110
+ const sky_trace_t *trace = ptr;
111
+ return sizeof(trace);
112
+ }
113
+
114
+ size_t sky_instrumenter_dsize(const void *ptr) {
115
+ const sky_instrumenter_t *instrumenter = ptr;
116
+ return sizeof(instrumenter);
117
+ }
118
+
119
+ static void local_sky_trace_free(void *ptr) {
120
+ sky_trace_free(ptr);
121
+ }
122
+
123
+ static void local_sky_instrumenter_free(void *ptr) {
124
+ sky_instrumenter_free(ptr);
125
+ }
126
+
127
+ static const rb_data_type_t sky_rb_trace_t = {
128
+ .wrap_struct_name = "sk_rb_trace",
129
+ .function = {
130
+ .dfree = local_sky_trace_free, // free
131
+ .dsize = sky_trace_dsize, // memsize
132
+ },
133
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
134
+ };
135
+ static const rb_data_type_t sky_rb_instrumenter_t = {
136
+ .wrap_struct_name = "sk_rb_instrumenter",
137
+ .function = {
138
+ .dfree = local_sky_instrumenter_free,
139
+ .dsize = sky_instrumenter_dsize
140
+ },
141
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
142
+ };
109
143
 
110
144
  static VALUE
111
145
  load_libskylight(VALUE klass, VALUE path) {
@@ -176,7 +210,7 @@ instrumenter_new(VALUE klass, VALUE rb_uuid, VALUE rb_env) {
176
210
  sky_instrumenter_new(STR2BUF(rb_uuid), env, envc, &instrumenter),
177
211
  "Instrumenter#native_new");
178
212
 
179
- return Data_Wrap_Struct(klass, NULL, sky_instrumenter_free, instrumenter);
213
+ return TypedData_Wrap_Struct(klass, &sky_rb_instrumenter_t, instrumenter);
180
214
  }
181
215
 
182
216
  static void*
@@ -199,7 +233,7 @@ static VALUE
199
233
  instrumenter_start(VALUE self) {
200
234
  sky_instrumenter_t* instrumenter;
201
235
 
202
- My_Struct(instrumenter, sky_instrumenter_t, no_instrumenter_msg);
236
+ My_Struct(instrumenter, sky_instrumenter_t, &sky_rb_instrumenter_t, no_instrumenter_msg);
203
237
 
204
238
  return (VALUE) WITHOUT_GVL(instrumenter_start_nogvl, instrumenter);
205
239
  }
@@ -208,7 +242,7 @@ static VALUE
208
242
  instrumenter_stop(VALUE self) {
209
243
  sky_instrumenter_t* instrumenter;
210
244
 
211
- My_Struct(instrumenter, sky_instrumenter_t, no_instrumenter_msg);
245
+ My_Struct(instrumenter, sky_instrumenter_t, &sky_rb_instrumenter_t, no_instrumenter_msg);
212
246
 
213
247
  CHECK_FFI(
214
248
  sky_instrumenter_stop(instrumenter),
@@ -224,8 +258,8 @@ instrumenter_submit_trace(VALUE self, VALUE rb_trace) {
224
258
  sky_instrumenter_t* instrumenter;
225
259
  sky_trace_t* trace;
226
260
 
227
- My_Struct(instrumenter, sky_instrumenter_t, no_instrumenter_msg);
228
- Transfer_Struct(trace, rb_trace, sky_trace_t, consumed_trace_msg);
261
+ My_Struct(instrumenter, sky_instrumenter_t, &sky_rb_instrumenter_t, no_instrumenter_msg);
262
+ Transfer_Struct(trace, rb_trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
229
263
 
230
264
  CHECK_FFI(
231
265
  sky_instrumenter_submit_trace(instrumenter, trace),
@@ -234,6 +268,19 @@ instrumenter_submit_trace(VALUE self, VALUE rb_trace) {
234
268
  return Qnil;
235
269
  }
236
270
 
271
+ static VALUE
272
+ instrumenter_flush(VALUE self) {
273
+ sky_instrumenter_t* instrumenter;
274
+
275
+ My_Struct(instrumenter, sky_instrumenter_t, &sky_rb_instrumenter_t, no_instrumenter_msg);
276
+
277
+ CHECK_FFI(
278
+ sky_instrumenter_flush(instrumenter),
279
+ "native Instrumenter#flush failed");
280
+
281
+ return Qnil;
282
+ }
283
+
237
284
  /*
238
285
  *
239
286
  * class Skylight::Trace
@@ -256,7 +303,7 @@ trace_new(VALUE klass, VALUE start, VALUE uuid, VALUE endpoint, VALUE meta) {
256
303
 
257
304
  sky_clear_allocation_count();
258
305
 
259
- return Data_Wrap_Struct(klass, NULL, sky_trace_free, trace);
306
+ return TypedData_Wrap_Struct(klass, &sky_rb_trace_t, trace);
260
307
  }
261
308
 
262
309
  static VALUE
@@ -264,7 +311,7 @@ trace_get_started_at(VALUE self) {
264
311
  uint64_t start;
265
312
  sky_trace_t* trace;
266
313
 
267
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
314
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
268
315
 
269
316
  CHECK_FFI(
270
317
  sky_trace_start(trace, &start),
@@ -278,7 +325,7 @@ trace_get_endpoint(VALUE self) {
278
325
  sky_trace_t* trace;
279
326
  sky_buf_t endpoint;
280
327
 
281
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
328
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
282
329
 
283
330
  CHECK_FFI(
284
331
  sky_trace_endpoint(trace, &endpoint),
@@ -292,7 +339,7 @@ trace_set_endpoint(VALUE self, VALUE endpoint) {
292
339
  sky_trace_t* trace;
293
340
 
294
341
  CHECK_TYPE(endpoint, T_STRING);
295
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
342
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
296
343
 
297
344
  CHECK_FFI(
298
345
  sky_trace_set_endpoint(trace, STR2BUF(endpoint)),
@@ -306,7 +353,7 @@ trace_get_component(VALUE self) {
306
353
  sky_trace_t* trace;
307
354
  sky_buf_t component;
308
355
 
309
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
356
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
310
357
 
311
358
  CHECK_FFI(
312
359
  sky_trace_component(trace, &component),
@@ -320,7 +367,7 @@ trace_set_component(VALUE self, VALUE component) {
320
367
  sky_trace_t* trace;
321
368
 
322
369
  CHECK_TYPE(component, T_STRING);
323
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
370
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
324
371
 
325
372
  CHECK_FFI(
326
373
  sky_trace_set_component(trace, STR2BUF(component)),
@@ -333,7 +380,7 @@ static VALUE
333
380
  trace_use_pruning(VALUE self) {
334
381
  sky_trace_t* trace;
335
382
 
336
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
383
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
337
384
 
338
385
  CHECK_FFI(
339
386
  sky_trace_use_pruning(trace),
@@ -354,7 +401,7 @@ trace_get_uuid(VALUE self) {
354
401
  sky_trace_t* trace;
355
402
  sky_buf_t uuid;
356
403
 
357
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
404
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
358
405
 
359
406
  CHECK_FFI(
360
407
  sky_trace_uuid(trace, &uuid),
@@ -368,7 +415,7 @@ trace_start_span(VALUE self, VALUE time, VALUE category) {
368
415
  sky_trace_t* trace;
369
416
  uint32_t span;
370
417
 
371
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
418
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
372
419
 
373
420
  CHECK_NUMERIC(time);
374
421
  CHECK_TYPE(category, T_STRING);
@@ -388,7 +435,7 @@ static VALUE
388
435
  trace_stop_span(VALUE self, VALUE span, VALUE time) {
389
436
  sky_trace_t* trace;
390
437
 
391
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
438
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
392
439
 
393
440
  CHECK_NUMERIC(time);
394
441
  CHECK_TYPE(span, T_FIXNUM);
@@ -409,7 +456,7 @@ trace_span_get_category(VALUE self, VALUE span) {
409
456
  sky_trace_t* trace;
410
457
  sky_buf_t category;
411
458
 
412
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
459
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
413
460
 
414
461
  CHECK_TYPE(span, T_FIXNUM);
415
462
 
@@ -424,7 +471,7 @@ static VALUE
424
471
  trace_span_set_title(VALUE self, VALUE span, VALUE title) {
425
472
  sky_trace_t* trace;
426
473
 
427
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
474
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
428
475
 
429
476
  CHECK_TYPE(span, T_FIXNUM);
430
477
  CHECK_TYPE(title, T_STRING);
@@ -441,7 +488,7 @@ trace_span_get_title(VALUE self, VALUE span) {
441
488
  sky_trace_t* trace;
442
489
  sky_buf_t title;
443
490
 
444
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
491
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
445
492
 
446
493
  CHECK_TYPE(span, T_FIXNUM);
447
494
 
@@ -456,7 +503,7 @@ static VALUE
456
503
  trace_span_set_description(VALUE self, VALUE span, VALUE desc) {
457
504
  sky_trace_t* trace;
458
505
 
459
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
506
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
460
507
 
461
508
  CHECK_TYPE(span, T_FIXNUM);
462
509
  CHECK_TYPE(desc, T_STRING);
@@ -473,7 +520,7 @@ trace_span_set_meta(VALUE self, VALUE span, VALUE meta) {
473
520
  sky_trace_t* trace;
474
521
  VALUE rb_source_location;
475
522
 
476
- My_Struct(trace, sky_trace_t, consumed_trace_msg);
523
+ My_Struct(trace, sky_trace_t, &sky_rb_trace_t, consumed_trace_msg);
477
524
 
478
525
  CHECK_TYPE(span, T_FIXNUM);
479
526
  CHECK_TYPE(meta, T_HASH);
@@ -545,4 +592,5 @@ void Init_skylight_native() {
545
592
  rb_define_method(rb_cInstrumenter, "native_start", instrumenter_start, 0);
546
593
  rb_define_method(rb_cInstrumenter, "native_stop", instrumenter_stop, 0);
547
594
  rb_define_method(rb_cInstrumenter, "native_submit_trace", instrumenter_submit_trace, 1);
595
+ rb_define_method(rb_cInstrumenter, "native_flush", instrumenter_flush, 0);
548
596
  }
@@ -1,4 +1,3 @@
1
- require "ostruct"
2
1
  require "skylight/util/http"
3
2
  require "thor"
4
3
  require "highline"
@@ -51,7 +50,7 @@ module Skylight
51
50
  @parents ||=
52
51
  begin
53
52
  a = (@apps + [{ name: STRINGS[:unlisted], components: [], unlisted: true }])
54
- a.each_with_object({}).with_index { |(app, h), i| h[i + 1] = OpenStruct.new(app) }
53
+ a.each_with_object({}).with_index { |(app, h), i| h[i + 1] = wrap_hash(app) }
55
54
  end
56
55
 
57
56
  say "\nLet's begin!\n\n" \
@@ -175,6 +174,10 @@ module Skylight
175
174
 
176
175
  private
177
176
 
177
+ def wrap_hash(hash)
178
+ hash.each_with_object(ActiveSupport::OrderedOptions.new) { |(key, value), result| result[key] = value }
179
+ end
180
+
178
181
  def do_merge
179
182
  say "Merging..."
180
183
 
@@ -274,10 +277,10 @@ module Skylight
274
277
  @parents.each do |_, app|
275
278
  next if app == @parent_app
276
279
 
277
- app.components.each { |component| yielder << OpenStruct.new({ app_name: app.name }.merge(component)) }
280
+ app.components.each { |component| yielder << wrap_hash({ app_name: app.name }.merge(component)) }
278
281
  end
279
282
 
280
- yielder << OpenStruct.new(app_name: STRINGS[:unlisted], unlisted: true)
283
+ yielder << wrap_hash(app_name: STRINGS[:unlisted], unlisted: true)
281
284
  end
282
285
 
283
286
  ret = ret.each_with_object({}).with_index { |(c, r), i| r[i + 1] = c }
@@ -19,6 +19,10 @@ module Skylight
19
19
  # @api private
20
20
  MUTEX = Mutex.new
21
21
 
22
+ DEFAULT_IGNORED_ENDPOINTS = %w[
23
+ Rails::HealthController#show
24
+ ].freeze
25
+
22
26
  # Map environment variable keys with Skylight configuration keys
23
27
  ENV_TO_KEY = {
24
28
  # == Authentication ==
@@ -102,7 +106,8 @@ module Skylight
102
106
  -"HEROKU_DYNO_INFO_PATH" => :"heroku.dyno_info_path",
103
107
  # == Source Location ==
104
108
  -"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems,
105
- -"SOURCE_LOCATION_CACHE_SIZE" => :source_location_cache_size
109
+ -"SOURCE_LOCATION_CACHE_SIZE" => :source_location_cache_size,
110
+ -"STANDALONE_DAEMON" => :standalone_daemon
106
111
  }.freeze
107
112
 
108
113
  KEY_TO_NATIVE_ENV = {
@@ -143,7 +148,8 @@ module Skylight
143
148
  "daemon.lazy_start": true,
144
149
  hostname: Util::Hostname.default_hostname,
145
150
  report_max_spans_exceeded: false,
146
- prune_large_traces: true
151
+ prune_large_traces: true,
152
+ standalone_daemon: false
147
153
  }
148
154
 
149
155
  ret[:"daemon.ssl_cert_path"] = Util::SSL.ca_cert_file_or_default unless Util::Platform::OS == -"darwin"
@@ -209,6 +215,7 @@ module Skylight
209
215
  daemon.ssl_cert_dir
210
216
  daemon.enable_tcp
211
217
  daemon.tcp_port
218
+ standalone_daemon
212
219
  ]
213
220
  end
214
221
 
@@ -490,7 +497,7 @@ module Skylight
490
497
 
491
498
  val = Array(get(:ignored_endpoint))
492
499
  val.concat(Array(ignored_endpoints))
493
- val
500
+ val | DEFAULT_IGNORED_ENDPOINTS
494
501
  end
495
502
  end
496
503
 
@@ -95,6 +95,10 @@ module Skylight
95
95
  raise "not implemented"
96
96
  end
97
97
 
98
+ def native_flush
99
+ raise "not implemented"
100
+ end
101
+
98
102
  def native_track_desc(_endpoint, _description)
99
103
  raise "not implemented"
100
104
  end
@@ -0,0 +1,4 @@
1
+ require "skylight"
2
+
3
+ Skylight.probe(:lambda)
4
+ Skylight.start!
@@ -59,10 +59,34 @@ module Skylight::Normalizers::GraphQL
59
59
  register_graphql
60
60
  end
61
61
 
62
- class ExecuteMultiplex < Base
62
+ class Execute < Base
63
63
  register_graphql
64
64
 
65
- def normalize_after(trace, _span, _name, payload)
65
+ # This is a new, combined normalizer for execute_query and execute_multiplex,
66
+ # to be used for graphql >= 2.5
67
+ #
68
+ def normalize(trace, name, payload)
69
+ payload[:query] ? _execute_query_normalize(trace, name, payload) : [CAT, "graphql.#{key}", nil]
70
+ end
71
+
72
+ def normalize_after(trace, span, name, payload)
73
+ _execute_multiplex_normalize_after(trace, span, name, payload) if payload[:multiplex]
74
+ end
75
+
76
+ private
77
+
78
+ def _execute_query_normalize(trace, _name, payload)
79
+ query_name = extract_query_name(payload[:query])
80
+
81
+ meta = { mute_children: true } if query_name == ANONYMOUS
82
+ # This is probably always overriden by execute_multiplex#normalize_after,
83
+ # but in the case of a single query, it will be the same value anyway.
84
+ trace.endpoint = "graphql:#{query_name}"
85
+
86
+ [CAT, "graphql.#{key}: #{query_name}", nil, meta]
87
+ end
88
+
89
+ def _execute_multiplex_normalize_after(trace, _span, _name, payload)
66
90
  # This is in normalize_after because the queries may not have
67
91
  # an assigned operation name before they are executed.
68
92
  # For example, if you send a single query with a defined operation name, e.g.:
@@ -93,24 +117,18 @@ module Skylight::Normalizers::GraphQL
93
117
  end
94
118
  end
95
119
 
96
- class AnalyzeQuery < Base
120
+ class ExecuteQuery < Execute
97
121
  register_graphql
98
122
  end
99
123
 
100
- class ExecuteQuery < Base
124
+ class ExecuteMultiplex < Execute
101
125
  register_graphql
102
126
 
103
- def normalize(trace, _name, payload)
104
- query_name = extract_query_name(payload[:query])
105
-
106
- meta = { mute_children: true } if query_name == ANONYMOUS
107
-
108
- # This is probably always overriden by execute_multiplex#normalize_after,
109
- # but in the case of a single query, it will be the same value anyway.
110
- trace.endpoint = "graphql:#{query_name}"
127
+ # see behavior in Execute#_multiplex_normalize_after
128
+ end
111
129
 
112
- [CAT, "graphql.#{key}: #{query_name}", nil, meta]
113
- end
130
+ class AnalyzeQuery < Base
131
+ register_graphql
114
132
  end
115
133
 
116
134
  class ExecuteQueryLazy < ExecuteQuery
@@ -8,21 +8,36 @@ module Skylight
8
8
  begin
9
9
  require "delayed/plugin"
10
10
 
11
+ UNKNOWN = "<Delayed::Job Unknown>"
12
+
11
13
  class Plugin < ::Delayed::Plugin
12
14
  callbacks do |lifecycle|
13
15
  lifecycle.around(:perform) { |worker, job, &block| sk_instrument(worker, job, &block) }
14
-
15
16
  lifecycle.after(:error) { |_worker, _job| Skylight.trace&.segment = "error" }
17
+ lifecycle.after(:failure) { |_worker, _job| Skylight.trace&.segment = "error" }
16
18
  end
17
19
 
18
20
  class << self
19
21
  include Skylight::Util::Logging
20
22
 
23
+ # This is called quite early in Delayed::Worker
24
+ #
25
+ # Typically, the `:perform` lifecycle hook is called before the
26
+ # `payload_object` has been deserialized, so we can't name the
27
+ # trace yet.
28
+ #
29
+ # If we call `payload_object` here, we would move the work of
30
+ # loading the object ahead of where it naturally happens, which
31
+ # means the database load time won't be instrumented. On the other
32
+ # hand, should the deserialization fail, we would have moved the
33
+ # timing of the error as well. Crucially – it would have moved it
34
+ # outside of the spot where these errors are normally caught and
35
+ # reported by the worker.
36
+ #
37
+ # See https://github.com/skylightio/skylight-ruby/issues/491
21
38
  def sk_instrument(_worker, job)
22
- endpoint = Skylight::Probes::DelayedJob.handler_name(job)
23
-
24
39
  Skylight.trace(
25
- endpoint,
40
+ UNKNOWN,
26
41
  "app.delayed_job.worker",
27
42
  "Delayed::Worker#run",
28
43
  component: :worker,
@@ -41,15 +56,6 @@ module Skylight
41
56
  $stderr.puts "[SKYLIGHT] The delayed_job probe was requested, but Delayed::Plugin was not defined."
42
57
  end
43
58
 
44
- UNKNOWN = "<Delayed::Job Unknown>"
45
-
46
- def self.handler_name(job)
47
- payload_object =
48
- job.respond_to?(:payload_object_without_sk) ? job.payload_object_without_sk : job.payload_object
49
-
50
- payload_object_name(payload_object)
51
- end
52
-
53
59
  def self.payload_object_name(payload_object)
54
60
  if payload_object.is_a?(::Delayed::PerformableMethod)
55
61
  payload_object.display_name
@@ -77,18 +83,27 @@ module Skylight
77
83
 
78
84
  class InstrumentationProxy < SimpleDelegator
79
85
  def perform
80
- source_meta = Skylight::Probes::DelayedJob.payload_object_source_meta(__getobj__)
81
-
82
- opts = {
83
- category: "app.delayed_job.job",
84
- title: format_source(*source_meta),
85
- meta: {
86
- source_location_hint: source_meta
87
- },
88
- internal: true
89
- }
90
-
91
- Skylight.instrument(opts) { __getobj__.perform }
86
+ if (trace = Skylight.instrumenter&.current_trace)
87
+ if trace.endpoint == UNKNOWN
88
+ # At this point, deserialization was, by definition, successful.
89
+ # So it'd be safe to set the endpoint name based on the payload
90
+ # object here.
91
+ trace.endpoint = Skylight::Probes::DelayedJob.payload_object_name(__getobj__)
92
+ end
93
+
94
+ source_meta = Skylight::Probes::DelayedJob.payload_object_source_meta(__getobj__)
95
+
96
+ opts = {
97
+ category: "app.delayed_job.job",
98
+ title: format_source(*source_meta),
99
+ meta: {
100
+ source_location_hint: source_meta
101
+ },
102
+ internal: true
103
+ }
104
+
105
+ Skylight.instrument(opts) { __getobj__.perform }
106
+ end
92
107
  end
93
108
 
94
109
  # Used by Delayed::Backend::Base to determine Job#name
@@ -35,6 +35,48 @@ module Skylight
35
35
  end
36
36
  end
37
37
 
38
+ # GraphQL versions >= 2.5 are missing this notification
39
+ module ExecuteQueryNotification
40
+ def execute_query(**metadata, &blk)
41
+ if @notifications_engine
42
+ @notifications_engine.instrument("execute_query.graphql", metadata, &blk)
43
+ elsif @notifications
44
+ @notifications.instrument("execute_query.graphql", metadata, &blk)
45
+ else
46
+ # safety fallback in case graphql's authors unexpectedly rename @notifications_engine or @notifications
47
+ super
48
+ end
49
+ end
50
+ end
51
+
52
+ # GraphQL versions >= 2.5 are missing this notification
53
+ module ExecuteQueryLazyNotification
54
+ def execute_query_lazy(**metadata, &blk)
55
+ if @notifications_engine
56
+ @notifications_engine.instrument("execute_query_lazy.graphql", metadata, &blk)
57
+ elsif @notifications
58
+ @notifications.instrument("execute_query_lazy.graphql", metadata, &blk)
59
+ else
60
+ # safety fallback in case graphql's authors unexpectedly rename @notifications_engine or @notifications
61
+ super
62
+ end
63
+ end
64
+ end
65
+
66
+ # GraphQL versions >= 2.5 are missing this notification
67
+ module AnalyzeQueryNotification
68
+ def analyze_query(**metadata, &blk)
69
+ if @notifications_engine
70
+ @notifications_engine.instrument("analyze_query.graphql", metadata, &blk)
71
+ elsif @notifications
72
+ @notifications.instrument("analyze_query.graphql", metadata, &blk)
73
+ else
74
+ # safety fallback in case graphql's authors unexpectedly rename @notifications_engine or @notifications
75
+ super
76
+ end
77
+ end
78
+ end
79
+
38
80
  module ClassMethods
39
81
  def new_trace(*, **)
40
82
  unless @__sk_instrumentation_installed
@@ -44,6 +86,18 @@ module Skylight
44
86
  trace_with(ExecuteMultiplexNotification)
45
87
  end
46
88
 
89
+ unless ::GraphQL::Tracing::ActiveSupportNotificationsTrace.instance_methods.include?(:execute_query)
90
+ trace_with(ExecuteQueryNotification)
91
+ end
92
+
93
+ unless ::GraphQL::Tracing::ActiveSupportNotificationsTrace.instance_methods.include?(:execute_query_lazy)
94
+ trace_with(ExecuteQueryLazyNotification)
95
+ end
96
+
97
+ unless ::GraphQL::Tracing::ActiveSupportNotificationsTrace.instance_methods.include?(:analyze_query)
98
+ trace_with(AnalyzeQueryNotification)
99
+ end
100
+
47
101
  @__sk_instrumentation_installed = true
48
102
  end
49
103
 
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skylight
4
+ module Probes
5
+ module Lambda
6
+ AWS_LAMBDA_FUNCTION_NAME = "AWS_LAMBDA_FUNCTION_NAME"
7
+
8
+ module Common
9
+ private
10
+
11
+ def sk_lambda_function_name
12
+ ENV.fetch(AWS_LAMBDA_FUNCTION_NAME, "<unknown>")
13
+ end
14
+ end
15
+
16
+ # NOTE: there are two modalities to probing the lambda wrappers:
17
+ # - The default runtime is implemented as a plain set of nested loops; LambdaHandler is a top-level constant
18
+ # in this context.
19
+ # - AWS also publishes the aws_lambda_ric gem as an alternate Dockerfile entrypoint; this runs largely
20
+ # the same code, but encapsulated in the LambdaRunner.
21
+ #
22
+ # The `run_user_code` is by all measures a better method to probe, as it includes the time spent to deliver
23
+ # the response back to the lambda server, and we can flush the internal buffer here without affecting response time.
24
+ module Runner
25
+ class Probe
26
+ def install
27
+ if defined?(::AwsLambdaRuntimeInterfaceClient::LambdaRunner)
28
+ ::AwsLambdaRuntimeInterfaceClient::LambdaRunner.prepend(Instrumentation)
29
+ end
30
+ end
31
+ end
32
+
33
+ module Instrumentation
34
+ def run_user_code(request)
35
+ Skylight.trace(sk_lambda_function_name, "other", "lambda handler") { super }
36
+ ensure
37
+ Skylight.instrumenter&.native_flush
38
+ end
39
+
40
+ include Common
41
+ end
42
+ end
43
+
44
+ module Handler
45
+ class Probe
46
+ def install
47
+ LambdaHandler.prepend(Instrumentation) if defined?(LambdaHandler)
48
+ end
49
+ end
50
+
51
+ module Instrumentation
52
+ def call_handler(request:, **)
53
+ if Skylight.trace
54
+ Skylight.instrument(sk_instrument_opts(request)) { super }
55
+ else
56
+ Skylight.trace(sk_lambda_function_name, "other", "lambda handler") do
57
+ Skylight.instrument(sk_instrument_opts(request)) { super }
58
+ end
59
+ end
60
+ end
61
+
62
+ include Common
63
+
64
+ private
65
+
66
+ def sk_instrument_opts(request)
67
+ {
68
+ category: "app.lambda.handler",
69
+ title: sk_handler_method_name,
70
+ description: sk_lambda_function_arn(request)
71
+ }
72
+ end
73
+
74
+ def sk_handler_method_name
75
+ [@handler_file_name, @handler_class, @handler_method_name].compact.join(".")
76
+ end
77
+
78
+ def sk_lambda_function_arn(request)
79
+ request["Lambda-Runtime-Invoked-Function-Arn"]
80
+ rescue StandardError
81
+ nil
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ register(
88
+ :lambda_runner,
89
+ "AwsLambdaRuntimeInterfaceClient::LambdaRunner",
90
+ "aws_lambda_ric",
91
+ Lambda::Runner::Probe.new
92
+ )
93
+
94
+ # NOTE: this require hook is unlikely to be invoked; the actual default lambda runtime loads this file
95
+ # via a require_relative.
96
+ register(:lambda_handler, "LambdaHandler", "lambda_handler", Lambda::Handler::Probe.new)
97
+ end
98
+ end
@@ -328,7 +328,7 @@ module Skylight
328
328
  end
329
329
 
330
330
  def resolve_component(component)
331
- config.components[component].to_encoded_s
331
+ config.components[component].to_s
332
332
  end
333
333
 
334
334
  def component=(component)
@@ -3,5 +3,5 @@ module Skylight
3
3
  # for compatibility with semver when it is parsed by the rust agent.
4
4
  # This string will be transformed in the gemspec to "5.0.0.alpha"
5
5
  # to conform with rubygems.
6
- VERSION = "6.0.4".freeze
6
+ VERSION = "7.0.0-beta".freeze
7
7
  end
data/lib/skylight.rb CHANGED
@@ -129,7 +129,7 @@ module Skylight
129
129
  end
130
130
 
131
131
  # Start a trace
132
- def trace(endpoint = nil, cat = nil, title = nil, meta: nil, segment: nil, component: nil)
132
+ def trace(endpoint = nil, cat = nil, title = nil, desc = nil, meta: nil, segment: nil, component: nil)
133
133
  unless instrumenter
134
134
  return yield if block_given?
135
135
 
@@ -146,11 +146,11 @@ module Skylight
146
146
  cat ||= DEFAULT_CATEGORY
147
147
 
148
148
  if block_given?
149
- instrumenter.trace(endpoint, cat, title, nil, meta: meta, segment: segment, component: component) do |tr|
149
+ instrumenter.trace(endpoint, cat, title, desc, meta: meta, segment: segment, component: component) do |tr|
150
150
  yield tr
151
151
  end
152
152
  else
153
- instrumenter.trace(endpoint, cat, title, nil, meta: meta, segment: segment, component: component)
153
+ instrumenter.trace(endpoint, cat, title, desc, meta: meta, segment: segment, component: component)
154
154
  end
155
155
  end
156
156
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skylight
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.4
4
+ version: 7.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tilde, Inc.
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-02-26 00:00:00.000000000 Z
10
+ date: 2025-09-03 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 5.2.0
18
+ version: 7.1.0
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 5.2.0
25
+ version: 7.1.0
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: beefcake
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +141,14 @@ dependencies:
142
141
  requirements:
143
142
  - - "~>"
144
143
  - !ruby/object:Gem::Version
145
- version: 1.31.0
144
+ version: 1.70.0
146
145
  type: :development
147
146
  prerelease: false
148
147
  version_requirements: !ruby/object:Gem::Requirement
149
148
  requirements:
150
149
  - - "~>"
151
150
  - !ruby/object:Gem::Version
152
- version: 1.31.0
151
+ version: 1.70.0
153
152
  - !ruby/object:Gem::Dependency
154
153
  name: simplecov
155
154
  requirement: !ruby/object:Gem::Requirement
@@ -206,7 +205,6 @@ dependencies:
206
205
  - - ">="
207
206
  - !ruby/object:Gem::Version
208
207
  version: '0'
209
- description:
210
208
  email:
211
209
  - engineering@tilde.io
212
210
  executables:
@@ -242,6 +240,7 @@ files:
242
240
  - lib/skylight/gc.rb
243
241
  - lib/skylight/helpers.rb
244
242
  - lib/skylight/instrumenter.rb
243
+ - lib/skylight/lambda.rb
245
244
  - lib/skylight/middleware.rb
246
245
  - lib/skylight/native.rb
247
246
  - lib/skylight/native_ext_fetcher.rb
@@ -307,6 +306,7 @@ files:
307
306
  - lib/skylight/probes/faraday.rb
308
307
  - lib/skylight/probes/graphql.rb
309
308
  - lib/skylight/probes/httpclient.rb
309
+ - lib/skylight/probes/lambda.rb
310
310
  - lib/skylight/probes/middleware.rb
311
311
  - lib/skylight/probes/mongo.rb
312
312
  - lib/skylight/probes/mongoid.rb
@@ -384,7 +384,6 @@ licenses:
384
384
  - Nonstandard
385
385
  metadata:
386
386
  rubygems_mfa_required: 'true'
387
- post_install_message:
388
387
  rdoc_options: []
389
388
  require_paths:
390
389
  - lib
@@ -392,15 +391,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
392
391
  requirements:
393
392
  - - ">="
394
393
  - !ruby/object:Gem::Version
395
- version: '2.7'
394
+ version: '3.1'
396
395
  required_rubygems_version: !ruby/object:Gem::Requirement
397
396
  requirements:
398
397
  - - ">="
399
398
  - !ruby/object:Gem::Version
400
399
  version: '0'
401
400
  requirements: []
402
- rubygems_version: 3.4.10
403
- signing_key:
401
+ rubygems_version: 3.6.2
404
402
  specification_version: 4
405
403
  summary: Skylight is a smart profiler for Rails, Sinatra, and other Ruby apps.
406
404
  test_files: []