skylight 6.1.0.beta → 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 +4 -4
- data/CHANGELOG.md +9 -0
- data/ext/extconf.rb +9 -10
- data/ext/skylight_native.c +81 -33
- data/lib/skylight/cli/merger.rb +7 -4
- data/lib/skylight/config.rb +10 -3
- data/lib/skylight/instrumenter.rb +4 -0
- data/lib/skylight/lambda.rb +4 -0
- data/lib/skylight/normalizers/graphql/base.rb +32 -14
- data/lib/skylight/probes/delayed_job.rb +40 -25
- data/lib/skylight/probes/graphql.rb +54 -0
- data/lib/skylight/probes/lambda.rb +98 -0
- data/lib/skylight/trace.rb +1 -1
- data/lib/skylight/version.rb +1 -1
- data/lib/skylight.rb +3 -3
- metadata +12 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e85fc890c72f6fdd61b4ce526da796e93b881204cc3a23c3aa49b2af79b102e6
|
4
|
+
data.tar.gz: c1b04bcba22ae003689ba594e7c84c256c498426e3dc8a0b1e52e662e2df0505
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cf4914170bc6741a6afbbceea055ad430d9d0bc536d2d241540615e48ffd986ad03473399d0b930b19d462059398d158e0e100b9e90860944c409ab47f4d75d
|
7
|
+
data.tar.gz: cbd977277cdae972fd6421986defe7250b1b5c73eed724ab72a8f47a72f72c7a69fff7a94c056607fc675e9b3d2442bb50b778b0ccca72b86221e81980e3073b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
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
|
+
|
1
10
|
## 6.1.0.beta (June 11, 2024)
|
2
11
|
|
3
12
|
- [IMPROVEMENT] Initial support for parsing queries from activerecord-sqlserver-adapter
|
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" => "
|
14
|
+
"version" => "6.0.0-beta-ec1a887",
|
16
15
|
"checksums" => {
|
17
|
-
"x86-linux" => "
|
18
|
-
"x86_64-linux" => "
|
19
|
-
"x86_64-linux-musl" => "
|
20
|
-
"x86_64-darwin" => "
|
21
|
-
"x86_64-freebsd" => "
|
22
|
-
"aarch64-linux" => "
|
23
|
-
"aarch64-linux-musl" => "
|
24
|
-
"aarch64-darwin" => "
|
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
|
|
data/ext/skylight_native.c
CHANGED
@@ -55,22 +55,22 @@ STR2BUF(VALUE str) {
|
|
55
55
|
} \
|
56
56
|
} while(0)
|
57
57
|
|
58
|
-
#define
|
59
|
-
|
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
|
62
|
-
|
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
|
66
|
-
|
67
|
-
DATA_PTR(
|
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
|
70
|
-
|
71
|
-
|
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
|
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
|
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
|
}
|
data/lib/skylight/cli/merger.rb
CHANGED
@@ -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] =
|
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 <<
|
280
|
+
app.components.each { |component| yielder << wrap_hash({ app_name: app.name }.merge(component)) }
|
278
281
|
end
|
279
282
|
|
280
|
-
yielder <<
|
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 }
|
data/lib/skylight/config.rb
CHANGED
@@ -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
|
|
@@ -59,10 +59,34 @@ module Skylight::Normalizers::GraphQL
|
|
59
59
|
register_graphql
|
60
60
|
end
|
61
61
|
|
62
|
-
class
|
62
|
+
class Execute < Base
|
63
63
|
register_graphql
|
64
64
|
|
65
|
-
|
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
|
120
|
+
class ExecuteQuery < Execute
|
97
121
|
register_graphql
|
98
122
|
end
|
99
123
|
|
100
|
-
class
|
124
|
+
class ExecuteMultiplex < Execute
|
101
125
|
register_graphql
|
102
126
|
|
103
|
-
|
104
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
data/lib/skylight/trace.rb
CHANGED
data/lib/skylight/version.rb
CHANGED
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,
|
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,
|
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:
|
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:
|
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:
|
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:
|
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.
|
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.
|
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: '
|
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
|
-
version:
|
399
|
+
version: '0'
|
401
400
|
requirements: []
|
402
|
-
rubygems_version: 3.
|
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: []
|