skylight 4.2.3 → 5.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -2
  3. data/CONTRIBUTING.md +1 -7
  4. data/ext/extconf.rb +6 -5
  5. data/ext/libskylight.yml +5 -6
  6. data/ext/skylight_native.c +24 -100
  7. data/lib/skylight.rb +211 -14
  8. data/lib/skylight/api.rb +7 -3
  9. data/lib/skylight/cli.rb +4 -3
  10. data/lib/skylight/cli/doctor.rb +13 -14
  11. data/lib/skylight/cli/merger.rb +6 -4
  12. data/lib/skylight/config.rb +605 -127
  13. data/lib/skylight/deprecation.rb +17 -0
  14. data/lib/skylight/errors.rb +21 -6
  15. data/lib/skylight/extensions.rb +107 -0
  16. data/lib/skylight/extensions/source_location.rb +291 -0
  17. data/lib/skylight/formatters/http.rb +20 -0
  18. data/lib/skylight/gc.rb +109 -0
  19. data/lib/skylight/helpers.rb +36 -18
  20. data/lib/skylight/instrumenter.rb +326 -15
  21. data/lib/skylight/middleware.rb +138 -1
  22. data/lib/skylight/native.rb +52 -2
  23. data/lib/skylight/native_ext_fetcher.rb +4 -3
  24. data/lib/skylight/normalizers.rb +152 -0
  25. data/lib/skylight/normalizers/action_controller/process_action.rb +69 -0
  26. data/lib/skylight/normalizers/action_controller/send_file.rb +50 -0
  27. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  28. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  29. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  30. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  31. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  32. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  33. data/lib/skylight/normalizers/active_job/perform.rb +86 -0
  34. data/lib/skylight/normalizers/active_model_serializers/render.rb +28 -0
  35. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  36. data/lib/skylight/normalizers/active_record/sql.rb +12 -0
  37. data/lib/skylight/normalizers/active_storage.rb +30 -0
  38. data/lib/skylight/normalizers/active_support/cache.rb +22 -0
  39. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  40. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  41. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  42. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  43. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  44. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  49. data/lib/skylight/normalizers/coach/handler_finish.rb +46 -0
  50. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  51. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  52. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  53. data/lib/skylight/normalizers/default.rb +32 -0
  54. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  55. data/lib/skylight/normalizers/faraday/request.rb +40 -0
  56. data/lib/skylight/normalizers/grape/endpoint.rb +34 -0
  57. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  58. data/lib/skylight/normalizers/grape/endpoint_run.rb +41 -0
  59. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +22 -0
  60. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  61. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  62. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  63. data/lib/skylight/normalizers/graphql/base.rb +132 -0
  64. data/lib/skylight/normalizers/render.rb +81 -0
  65. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  66. data/lib/skylight/normalizers/sql.rb +45 -0
  67. data/lib/skylight/probes.rb +181 -0
  68. data/lib/skylight/probes/action_controller.rb +48 -0
  69. data/lib/skylight/probes/action_dispatch.rb +2 -0
  70. data/lib/skylight/probes/action_dispatch/request_id.rb +29 -0
  71. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +28 -0
  72. data/lib/skylight/probes/action_view.rb +43 -0
  73. data/lib/skylight/probes/active_job.rb +27 -0
  74. data/lib/skylight/probes/active_job_enqueue.rb +41 -0
  75. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  76. data/lib/skylight/probes/delayed_job.rb +149 -0
  77. data/lib/skylight/probes/elasticsearch.rb +38 -0
  78. data/lib/skylight/probes/excon.rb +25 -0
  79. data/lib/skylight/probes/excon/middleware.rb +66 -0
  80. data/lib/skylight/probes/faraday.rb +23 -0
  81. data/lib/skylight/probes/graphql.rb +43 -0
  82. data/lib/skylight/probes/httpclient.rb +44 -0
  83. data/lib/skylight/probes/middleware.rb +126 -0
  84. data/lib/skylight/probes/mongo.rb +164 -0
  85. data/lib/skylight/probes/mongoid.rb +13 -0
  86. data/lib/skylight/probes/net_http.rb +54 -0
  87. data/lib/skylight/probes/redis.rb +63 -0
  88. data/lib/skylight/probes/sequel.rb +33 -0
  89. data/lib/skylight/probes/sinatra.rb +63 -0
  90. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  91. data/lib/skylight/probes/tilt.rb +27 -0
  92. data/lib/skylight/railtie.rb +162 -18
  93. data/lib/skylight/sidekiq.rb +48 -0
  94. data/lib/skylight/subscriber.rb +110 -0
  95. data/lib/skylight/test.rb +146 -0
  96. data/lib/skylight/trace.rb +307 -10
  97. data/lib/skylight/user_config.rb +61 -0
  98. data/lib/skylight/util.rb +12 -0
  99. data/lib/skylight/util/allocation_free.rb +26 -0
  100. data/lib/skylight/util/clock.rb +56 -0
  101. data/lib/skylight/util/component.rb +5 -2
  102. data/lib/skylight/util/deploy.rb +7 -10
  103. data/lib/skylight/util/gzip.rb +20 -0
  104. data/lib/skylight/util/http.rb +4 -10
  105. data/lib/skylight/util/instrumenter_method.rb +26 -0
  106. data/lib/skylight/util/logging.rb +138 -0
  107. data/lib/skylight/util/lru_cache.rb +40 -0
  108. data/lib/skylight/util/platform.rb +1 -1
  109. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  110. data/lib/skylight/version.rb +5 -1
  111. data/lib/skylight/vm/gc.rb +68 -0
  112. metadata +117 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4cafddf94ef05049d8240fe3b44c1c35d66505ca6e8f4913b7ebe4ddf1ef10c6
4
- data.tar.gz: 6648e03d56f0a5216a57804fa44cdfd63155e2665fb49e534535f065702c2620
3
+ metadata.gz: c951c13914411fa23c37504ba022bd55229c2c4c59dc4dcf0a751b24b9dad33c
4
+ data.tar.gz: 93734aa403e74cbcc5c7afda5473800b962a1fe4a0b06fff0cbfab2a23d7d316
5
5
  SHA512:
6
- metadata.gz: 7eb897a9c5984eb831de3af1681fb5ac47ff2314291594f342605c8ff0295eb0dd25d7c0a66965aea8506f5df41af5ca2bf7788a251caa58d871571f08205f95
7
- data.tar.gz: ef2fbfc2446f76df58f94fabcb9fe39bf255d05df5b30fce042d44b71360b0052c0b18741250cd32ce967dd4eb0019396d61ae1589448e9fa062be60ebae7fb0
6
+ metadata.gz: 7901ffd7e863387424ab384d8276472a6d2c3dfabef2075cb859db8e1ff8f81643cce80f2ac9ffba1f3cb1c27d06338a6b6477347f7e7db58745d9ede000a78b
7
+ data.tar.gz: a404ebc97ac20f763f21df54e444e0abf72b4ad442bb39efca1c6b19a408f0d8edab2021032237aac044cb39c333815ed101ad6015fdd4246d3a66932cd9b7e9
@@ -1,5 +1,37 @@
1
- ## 4.2.3 (March 10, 2020)
2
- * [BUGFIX] Fix an issue where the GraphQL probe may not always be installed
1
+ ## 5.0.0.beta3
2
+ * [IMPROVEMENT] Optimizations for the Source Locations extension
3
+ * [FEATURE] Configuration for the Source Locations caches via `SYLIGHT_SOURCE_LOCATION_CACHE_SIZE`
4
+ * [BUGFIX] Fix issue with missing metadata in MongoDB probe
5
+ * [BUGFIX] Resolve an inability to parse certain SQL queries containing arrays
6
+
7
+ ## 5.0.0.beta2
8
+ * [FEATURE] Source Locations detection and reporting is now enabled by default (can be disabled with `SKYLIGHT_ENABLE_SOURCE_LOCATIONS=false`)
9
+ * [BREAKING] Rename `environment` keyword argument to `priority_key`. Note `env` has not changed.
10
+ * [BREAKING] Drop support for Ruby 2.4
11
+ * [IMPROVEMENT] Improved Delayed::Job probe
12
+
13
+ ## 5.0.0.beta
14
+ * [BREAKING] Merge skylight-core into skylight. All classes previously namespaced under `Skylight::Core` have been moved to `Skylight`.
15
+ * [BREAKING] Remove `Skylight::Util::Inflector`
16
+ * [BREAKING] Drop support for Rails 4
17
+ * [BREAKING] Drop support for Ruby 2.3
18
+ * [IMPROVEMENT] Maintain method visibility when instrumenting with `instrument_method`
19
+ * [IMPROVEMENT] Update probes to use `Module#prepend` where possible
20
+ * [IMPROVEMENT] New tokio-based skylightd
21
+ * [IMPROVEMENT] Support `render_layout` notifications in Rails 6.1
22
+ * [IMPROVEMENT] Support `ActionMailer::MailDeliveryJob` in Rails 6.1
23
+ * [IMPROVEMENT] Better logging config
24
+ * [BUGFIX] Allow multiple probes to be registered under the same key
25
+ * [BUGFIX] Do not refer to Redis constant until the probe is installed
26
+ * [BUGFIX] Fix nested calls to `Normalizers::Faraday::Request.disable`
27
+
28
+ ## 4.3.1 (June 24, 2020)
29
+ * [BUGFIX] Fix an issue in which `Mime::NullType` would result in an exception
30
+
31
+ ## 4.3.0 (March 18, 2020)
32
+ * [IMPROVEMENT] Fix Ruby 2.7 warnings
33
+ * [IMPROVEMENT] Update Grape normalizer for version 1.3.1
34
+ * [BUGFIX] Fix an issue where GraphQL normalizers could fail to load in non-Rails contexts
3
35
 
4
36
  ## 4.2.2 (February 25, 2020)
5
37
  * Support graphql-ruby version 1.10
@@ -18,12 +18,6 @@ If you prefer to run tests in your own environment, you may do so as follows:
18
18
  # Select a gemfile and bundle install
19
19
  export BUNDLE_GEMFILE=$PWD/gemfiles/Gemfile.rails-5.2.x
20
20
  bundle install
21
-
22
- # Run the skylight-core test suite (takes a few seconds)
23
- pushd skylight-core
24
- bundle exec rspec
25
- popd
26
-
27
- # Run the main test suite (takes 5-10 minutes)
21
+ # Run the test suite (takes 5-10 minutes)
28
22
  bundle exec rspec
29
23
  ```
@@ -32,7 +32,8 @@ SKYLIGHT_FETCH_LIB = !ENV.key?("SKYLIGHT_FETCH_LIB") || ENV["SKYLIGHT_FETCH_LIB
32
32
 
33
33
  # Directory where skylight.h exists
34
34
  SKYLIGHT_HDR_PATH = ENV["SKYLIGHT_HDR_PATH"] || ENV["SKYLIGHT_LIB_PATH"] || "."
35
- SKYLIGHT_LIB_PATH = ENV["SKYLIGHT_LIB_PATH"] || File.expand_path("../../lib/skylight/native/#{Platform.tuple}", __FILE__)
35
+ SKYLIGHT_LIB_PATH = ENV["SKYLIGHT_LIB_PATH"] ||
36
+ File.expand_path("../../lib/skylight/native/#{Platform.tuple}", __FILE__)
36
37
 
37
38
  SKYLIGHT_SOURCE_URL = ENV["SKYLIGHT_SOURCE_URL"]
38
39
  SKYLIGHT_VERSION = ENV["SKYLIGHT_VERSION"]
@@ -41,7 +42,7 @@ SKYLIGHT_CHECKSUM = ENV["SKYLIGHT_CHECKSUM"]
41
42
  SKYLIGHT_EXT_STRICT = ENV.key?("SKYLIGHT_EXT_STRICT") && ENV["SKYLIGHT_EXT_STRICT"] =~ /^true$/i
42
43
 
43
44
  # Setup logger
44
- LOG = Logger.new(MultiIO.new(STDOUT, File.open(SKYLIGHT_INSTALL_LOG, "a")))
45
+ LOG = Logger.new(MultiIO.new($stdout, File.open(SKYLIGHT_INSTALL_LOG, "a")))
45
46
 
46
47
  # Handles terminating in the case of a failure. If we have a bug, we do not
47
48
  # want to break our customer's deploy, but extconf.rb requires a Makefile to be
@@ -68,7 +69,7 @@ end
68
69
  if Platform::OS == "darwin"
69
70
  # If the user installs Xcode-only, they have to approve the
70
71
  # license or no "xc*" tool will work.
71
- if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?
72
+ if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success? # rubocop:disable Style/SoleNestedConditional
72
73
  fail <<~MESSAGE
73
74
  You have not agreed to the Xcode license and so we are unable to build the native agent.
74
75
  To resolve this, you can agree to the license by opening Xcode.app or running:
@@ -206,8 +207,8 @@ find_header "skylight_dlopen.h", hdrpath
206
207
  fail "could not create Makefile; dlfcn.h missing" unless have_header "dlfcn.h"
207
208
 
208
209
  # For escaping the GVL
209
- unless have_func("rb_thread_call_without_gvl", "ruby/thread.h") || have_func("rb_thread_blocking_region")
210
- abort "Ruby is unexpectedly missing rb_thread_blocking_region. This should not happen."
210
+ unless have_func("rb_thread_call_without_gvl", "ruby/thread.h")
211
+ abort "Ruby is unexpectedly missing rb_thread_call_without_gvl. This should not happen."
211
212
  end
212
213
 
213
214
  # Previous comment stated:
@@ -1,7 +1,6 @@
1
- version: "4.1.0-46806f5"
1
+ version: "5.0.0-7111415"
2
2
  checksums:
3
- x86-linux: "4054632757516aa44e812860601fcb7f21c8c5d412b2d585868b46c7a8e3cae6"
4
- x86_64-linux: "4675694fba4448ba14787551237bd4e388443895d5c9e5d8a71c550eccd203db"
5
- x86_64-linux-musl: "7a81880830d0a409a6f0f39ff42f90a1422542b05384e2480ae05515f6b5f831"
6
- x86_64-darwin: "84eef6c330818c2bad1628ff189b9cb88275c9d72a28afac88a0d054d8002230"
7
- x86_64-freebsd: "a86a52203fab4f9a56ad91d5700e14823e6e997b4df1bcb3ae2d9e4296c50b1f"
3
+ x86-linux: "c304b73401b82adcbede23886168ca3487ca5901ebeddd6377d8ce758bf9d72d"
4
+ x86_64-linux: "4005f06b71295c77dccc7369f313452c7a26fe4c8de1108988e4d06d8f5fb36e"
5
+ x86_64-linux-musl: "0b8c582f99cc65ef466a506b9f589d634c8b502d4de5991c80c38e9efa812909"
6
+ x86_64-darwin: "efbd36e1cbea562ca9b76342cc3e938a6c0c506e7e7e1c0daaafff71da68364e"
@@ -86,14 +86,6 @@ typedef void* (*blocking_fn_t)(void*);
86
86
  #define WITHOUT_GVL(fn, a) \
87
87
  rb_thread_call_without_gvl((blocking_fn_t)(fn), (a), 0, 0)
88
88
 
89
- // Ruby 1.9
90
- #elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
91
-
92
- typedef VALUE (*blocking_fn_t)(void*);
93
- #define WITHOUT_GVL(fn, a) \
94
- rb_thread_blocking_region((blocking_fn_t)(fn), (a), 0, 0)
95
-
96
-
97
89
  #endif
98
90
 
99
91
 
@@ -103,7 +95,6 @@ typedef VALUE (*blocking_fn_t)(void*);
103
95
 
104
96
  VALUE rb_mSkylight;
105
97
  VALUE rb_eNativeError;
106
- VALUE rb_mCore;
107
98
  VALUE rb_mUtil;
108
99
  VALUE rb_cClock;
109
100
  VALUE rb_cTrace;
@@ -140,7 +131,7 @@ load_libskylight(VALUE klass, VALUE path) {
140
131
 
141
132
  /*
142
133
  *
143
- * class Skylight::Core::Util::Clock
134
+ * class Skylight::Util::Clock
144
135
  *
145
136
  */
146
137
 
@@ -152,7 +143,7 @@ clock_high_res_time(VALUE self) {
152
143
 
153
144
  /*
154
145
  *
155
- * class Skylight::Core::Instrumenter
146
+ * class Skylight::Instrumenter
156
147
  *
157
148
  */
158
149
 
@@ -243,33 +234,9 @@ instrumenter_submit_trace(VALUE self, VALUE rb_trace) {
243
234
  return Qnil;
244
235
  }
245
236
 
246
- static VALUE
247
- instrumenter_track_desc(VALUE self, VALUE rb_endpoint, VALUE rb_desc) {
248
- int tracked;
249
- sky_instrumenter_t* instrumenter;
250
-
251
- CHECK_TYPE(rb_endpoint, T_STRING);
252
- CHECK_TYPE(rb_desc, T_STRING);
253
-
254
- tracked = 0;
255
-
256
- My_Struct(instrumenter, sky_instrumenter_t, no_instrumenter_msg);
257
-
258
- CHECK_FFI(
259
- sky_instrumenter_track_desc(instrumenter, STR2BUF(rb_endpoint), STR2BUF(rb_desc), &tracked),
260
- "Instrumenter#native_track_desc");
261
-
262
- if (tracked) {
263
- return Qtrue;
264
- }
265
- else {
266
- return Qfalse;
267
- }
268
- }
269
-
270
237
  /*
271
238
  *
272
- * class Skylight::Core::Trace
239
+ * class Skylight::Trace
273
240
  *
274
241
  */
275
242
 
@@ -503,15 +470,31 @@ trace_span_set_description(VALUE self, VALUE span, VALUE desc) {
503
470
 
504
471
  static VALUE
505
472
  trace_span_set_meta(VALUE self, VALUE span, VALUE meta) {
506
- UNUSED(self);
507
- UNUSED(span);
508
- UNUSED(meta);
473
+ sky_trace_t* trace;
474
+ VALUE rb_source_location;
475
+
476
+ My_Struct(trace, sky_trace_t, consumed_trace_msg);
477
+
478
+ CHECK_TYPE(span, T_FIXNUM);
479
+ CHECK_TYPE(meta, T_HASH);
480
+
481
+ rb_source_location = rb_hash_lookup(meta, ID2SYM(rb_intern("source_location")));
482
+ if (rb_source_location != Qnil) {
483
+ sky_buf_t source_location;
484
+
485
+ CHECK_TYPE(rb_source_location, T_STRING);
486
+ source_location = STR2BUF(rb_source_location);
487
+
488
+ sky_trace_span_add_string_annotation(trace, FIX2UINT(span), 3, source_location);
489
+ }
490
+
509
491
  return Qnil;
510
492
  }
511
493
 
512
494
  static VALUE
513
- trace_span_started(VALUE self) {
495
+ trace_span_started(VALUE self, VALUE span) {
514
496
  UNUSED(self);
497
+ UNUSED(span);
515
498
  return Qnil;
516
499
  }
517
500
 
@@ -524,71 +507,14 @@ trace_span_set_exception(VALUE self, VALUE span, VALUE exception, VALUE exceptio
524
507
  return Qnil;
525
508
  }
526
509
 
527
- static VALUE
528
- trace_span_get_correlation_header(VALUE self, VALUE span_id) {
529
- UNUSED(self);
530
- UNUSED(span_id);
531
- return Qnil;
532
- }
533
-
534
- static VALUE
535
- lex_sql(VALUE klass, VALUE rb_sql) {
536
- sky_buf_t sql;
537
- sky_buf_t title;
538
- sky_buf_t statement;
539
- uint8_t title_store[128];
540
- VALUE rb_statement;
541
- VALUE ret;
542
-
543
- UNUSED(klass);
544
- CHECK_TYPE(rb_sql, T_STRING);
545
-
546
- sql = STR2BUF(rb_sql);
547
- title = (sky_buf_t) {
548
- .data = title_store,
549
- .len = sizeof(title_store),
550
- };
551
-
552
- // The statement cannot be longer than the original sql string
553
- rb_statement = rb_str_buf_new(RSTRING_LEN(rb_sql));
554
- statement = (sky_buf_t) {
555
- .data = RSTRING_PTR(rb_statement),
556
- .len = RSTRING_LEN(rb_sql),
557
- };
558
-
559
- CHECK_FFI(sky_lex_sql(sql, &title, &statement),
560
- "Skylight#lex_sql");
561
-
562
- // Set the statement return
563
- rb_str_set_len(rb_statement, statement.len);
564
- rb_enc_associate(rb_statement, rb_utf8_encoding());
565
-
566
- ret = rb_ary_new2(2);
567
-
568
- if (title.len > 0) {
569
- rb_ary_store(ret, 0, BUF2STR(title));
570
- }
571
- else {
572
- rb_ary_store(ret, 0, Qnil);
573
- }
574
-
575
- rb_ary_store(ret, 1, rb_statement);
576
-
577
- return ret;
578
- }
579
-
580
510
  void Init_skylight_native() {
581
511
  rb_mSkylight = rb_define_module("Skylight");
582
512
 
583
513
  rb_eNativeError = rb_const_get(rb_mSkylight, rb_intern("NativeError"));
584
514
 
585
515
  rb_define_singleton_method(rb_mSkylight, "load_libskylight", load_libskylight, 1);
586
- rb_define_singleton_method(rb_mSkylight, "lex_sql", lex_sql, 1);
587
-
588
- rb_mCore = rb_define_module_under(rb_mSkylight, "Core");
589
516
 
590
- // FIXME: Don't put these under Core
591
- rb_mUtil = rb_define_module_under(rb_mCore, "Util");
517
+ rb_mUtil = rb_define_module_under(rb_mSkylight, "Util");
592
518
  rb_cClock = rb_define_class_under(rb_mUtil, "Clock", rb_cObject);
593
519
  rb_define_method(rb_cClock, "native_hrtime", clock_high_res_time, 0);
594
520
 
@@ -611,12 +537,10 @@ void Init_skylight_native() {
611
537
  rb_define_method(rb_cTrace, "native_span_set_meta", trace_span_set_meta, 2);
612
538
  rb_define_method(rb_cTrace, "native_span_started", trace_span_started, 1);
613
539
  rb_define_method(rb_cTrace, "native_span_set_exception", trace_span_set_exception, 3);
614
- rb_define_method(rb_cTrace, "native_span_get_correlation_header", trace_span_get_correlation_header, 1);
615
540
 
616
541
  rb_cInstrumenter = rb_const_get(rb_mSkylight, rb_intern("Instrumenter"));
617
542
  rb_define_singleton_method(rb_cInstrumenter, "native_new", instrumenter_new, 2);
618
543
  rb_define_method(rb_cInstrumenter, "native_start", instrumenter_start, 0);
619
544
  rb_define_method(rb_cInstrumenter, "native_stop", instrumenter_stop, 0);
620
545
  rb_define_method(rb_cInstrumenter, "native_submit_trace", instrumenter_submit_trace, 1);
621
- rb_define_method(rb_cInstrumenter, "native_track_desc", instrumenter_track_desc, 2);
622
546
  }
@@ -1,36 +1,233 @@
1
1
  require "skylight/version"
2
- require "skylight/core"
3
2
  require "skylight/trace"
4
3
  require "skylight/instrumenter"
5
4
  require "skylight/middleware"
6
5
  require "skylight/api"
7
6
  require "skylight/helpers"
8
7
  require "skylight/config"
8
+ require "skylight/user_config"
9
9
  require "skylight/errors"
10
10
  require "skylight/native"
11
+ require "skylight/gc"
12
+ require "skylight/vm/gc"
13
+ require "skylight/util"
14
+ require "skylight/deprecation"
15
+ require "skylight/subscriber"
16
+ require "skylight/sidekiq"
17
+ require "skylight/probes"
11
18
 
12
19
  # For prettier global names
13
20
  require "English"
14
21
 
22
+ require "active_support/notifications"
23
+
24
+ # Specifically check for Railtie since we've had at least one case of a
25
+ # customer having Rails defined without having all of Rails loaded.
26
+ if defined?(Rails::Railtie)
27
+ require "skylight/railtie"
28
+ end
29
+
15
30
  module Skylight
16
31
  # Used from the CLI
17
32
  autoload :CLI, "skylight/cli"
33
+ # Is this autoload even useful?
34
+ autoload :Normalizers, "skylight/normalizers"
18
35
 
19
- # Specifically check for Railtie since we've had at least one case of a
20
- # customer having Rails defined without having all of Rails loaded.
21
- if defined?(Rails::Railtie)
22
- require "skylight/railtie"
23
- end
36
+ extend Util::Logging
24
37
 
25
- include Core::Instrumentable
38
+ LOCK = Mutex.new
26
39
 
27
- def self.instrumenter_class
28
- Instrumenter
29
- end
40
+ # @api private
41
+ TIERS = %w[
42
+ rack
43
+ api
44
+ app
45
+ view
46
+ db
47
+ noise
48
+ other
49
+ ].freeze
30
50
 
31
- def self.config_class
32
- Config
33
- end
51
+ # @api private
52
+ TIER_REGEX = /^(?:#{TIERS.join('|')})(?:\.|$)/u.freeze
53
+
54
+ # @api private
55
+ CATEGORY_REGEX = /^[a-z0-9_-]+(?:\.[a-z0-9_-]+)*$/iu.freeze
56
+
57
+ # @api private
58
+ DEFAULT_CATEGORY = "app.block".freeze
59
+
60
+ # @api private
61
+ DEFAULT_OPTIONS = { category: DEFAULT_CATEGORY }.freeze
62
+
63
+ at_exit { stop! }
64
+
65
+ class << self
66
+ extend Util::InstrumenterMethod
67
+
68
+ def instrumenter
69
+ defined?(@instrumenter) && @instrumenter
70
+ end
71
+
72
+ def probe(*args)
73
+ Probes.probe(*args)
74
+ end
75
+
76
+ def enable_normalizer(*names)
77
+ Normalizers.enable(*names)
78
+ end
79
+
80
+ # Start instrumenting
81
+ def start!(config = nil)
82
+ return instrumenter if instrumenter
83
+
84
+ const_get(:LOCK).synchronize do
85
+ return instrumenter if instrumenter
86
+
87
+ config ||= {}
88
+ config = Config.load(config) unless config.is_a?(Config)
89
+
90
+ Probes.install!
91
+
92
+ @instrumenter = Instrumenter.new(config).start!
93
+ end
94
+ rescue => e
95
+ level, message =
96
+ if e.is_a?(ConfigError)
97
+ [:warn, format("Unable to start Instrumenter due to a configuration error: %<message>s",
98
+ message: e.message)]
99
+ else
100
+ [:error, format("Unable to start Instrumenter; msg=%<message>s; class=%<klass>s",
101
+ message: e.message, klass: e.class)]
102
+ end
103
+
104
+ if config.respond_to?("log_#{level}") && config.respond_to?(:log_trace)
105
+ config.send("log_#{level}", message)
106
+ config.log_trace e.backtrace.join("\n")
107
+ else
108
+ warn "[#{name.upcase}] #{message}"
109
+ end
110
+ false
111
+ end
112
+
113
+ def started?
114
+ !!instrumenter
115
+ end
116
+
117
+ # Stop instrumenting
118
+ def stop!
119
+ t { "stop!" }
34
120
 
35
- Core::Probes.add_path(File.expand_path("skylight/probes", __dir__))
121
+ const_get(:LOCK).synchronize do
122
+ t { "stop! synchronized" }
123
+ return unless instrumenter
124
+
125
+ # This is only really helpful for getting specs to pass.
126
+ @instrumenter.current_trace = nil
127
+
128
+ @instrumenter.shutdown
129
+ @instrumenter = nil
130
+ end
131
+ end
132
+
133
+ # Check tracing
134
+ def tracing?
135
+ t { "checking tracing?; thread=#{Thread.current.object_id}" }
136
+ instrumenter&.current_trace
137
+ end
138
+
139
+ # Start a trace
140
+ def trace(endpoint = nil, cat = nil, title = nil, meta: nil, segment: nil, component: nil)
141
+ unless instrumenter
142
+ return yield if block_given?
143
+
144
+ return
145
+ end
146
+
147
+ if instrumenter.poisoned?
148
+ spawn_shutdown_thread!
149
+ return yield if block_given?
150
+
151
+ return
152
+ end
153
+
154
+ cat ||= DEFAULT_CATEGORY
155
+
156
+ if block_given?
157
+ instrumenter.trace(endpoint, cat, title, nil, meta: meta, segment: segment, component: component) do |tr|
158
+ yield tr
159
+ end
160
+ else
161
+ instrumenter.trace(endpoint, cat, title, nil, meta: meta, segment: segment, component: component)
162
+ end
163
+ end
164
+
165
+ # @overload instrument(opts)
166
+ # @param [Hash] opts the options for instrumentation.
167
+ # @option opts [String] :category (`DEFAULT_CATEGORY`) The category
168
+ # @option opts [String] :title The title
169
+ # @option opts [String] :description The description
170
+ # @option opts [Hash] :meta The meta
171
+ # @option opts [String] :source_location The source location
172
+ # @option opts [String] :source_file The source file. (Will be sanitized.)
173
+ # @option opts [String] :source_line The source line.
174
+ # @overload instrument(title)
175
+ # Instrument with the specified title and the default category
176
+ # @param [String] title The title
177
+ def instrument(opts = DEFAULT_OPTIONS, &block)
178
+ unless instrumenter
179
+ return yield if block_given?
180
+
181
+ return
182
+ end
183
+
184
+ if opts.is_a?(Hash)
185
+ category = opts[:category] || DEFAULT_CATEGORY
186
+ title = opts[:title]
187
+ desc = opts[:description]
188
+ meta = opts[:meta]
189
+ else
190
+ category = DEFAULT_CATEGORY
191
+ title = opts.to_s
192
+ desc = nil
193
+ meta = nil
194
+ opts = {}
195
+ end
196
+
197
+ # NOTE: unless we have `:internal` (indicating a built-in Skylight instrument block),
198
+ # or we already have a `source_file` or `source_line` (probably set by `instrument_method`),
199
+ # we set the caller location to the second item on the stack
200
+ # (immediate caller of the `instrument` method).
201
+ unless opts[:source_file] || opts[:source_line] || opts[:internal]
202
+ opts = opts.merge(sk_instrument_location: caller_locations(1..1).first)
203
+ end
204
+
205
+ meta ||= {}
206
+
207
+ instrumenter.extensions.process_instrument_options(opts, meta)
208
+ instrumenter.instrument(category, title, desc, meta, &block)
209
+ end
210
+
211
+ instrumenter_method :config
212
+
213
+ instrumenter_method :mute, block: true
214
+ instrumenter_method :unmute, block: true
215
+ instrumenter_method :muted?
216
+
217
+ # End a span
218
+ instrumenter_method :done
219
+
220
+ instrumenter_method :broken!
221
+
222
+ # Temporarily disable
223
+ instrumenter_method :disable, block: true
224
+
225
+ # Runs the shutdown procedure in the background.
226
+ # This should do little more than unsubscribe from all ActiveSupport::Notifications
227
+ def spawn_shutdown_thread!
228
+ @shutdown_thread || const_get(:LOCK).synchronize do
229
+ @shutdown_thread ||= Thread.new { @instrumenter&.shutdown }
230
+ end
231
+ end
232
+ end
36
233
  end