skylight 4.3.2 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -3
  3. data/CONTRIBUTING.md +2 -8
  4. data/ext/extconf.rb +6 -5
  5. data/ext/libskylight.yml +7 -6
  6. data/ext/skylight_native.c +22 -99
  7. data/lib/skylight.rb +211 -14
  8. data/lib/skylight/api.rb +10 -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 +597 -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 +69 -26
  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 +153 -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/shrine.rb +34 -0
  67. data/lib/skylight/normalizers/sql.rb +45 -0
  68. data/lib/skylight/probes.rb +181 -0
  69. data/lib/skylight/probes/action_controller.rb +48 -0
  70. data/lib/skylight/probes/action_dispatch.rb +2 -0
  71. data/lib/skylight/probes/action_dispatch/request_id.rb +29 -0
  72. data/lib/skylight/probes/action_dispatch/routing/route_set.rb +28 -0
  73. data/lib/skylight/probes/action_view.rb +43 -0
  74. data/lib/skylight/probes/active_job.rb +27 -0
  75. data/lib/skylight/probes/active_job_enqueue.rb +41 -0
  76. data/lib/skylight/probes/active_model_serializers.rb +50 -0
  77. data/lib/skylight/probes/delayed_job.rb +149 -0
  78. data/lib/skylight/probes/elasticsearch.rb +38 -0
  79. data/lib/skylight/probes/excon.rb +25 -0
  80. data/lib/skylight/probes/excon/middleware.rb +66 -0
  81. data/lib/skylight/probes/faraday.rb +23 -0
  82. data/lib/skylight/probes/graphql.rb +43 -0
  83. data/lib/skylight/probes/httpclient.rb +44 -0
  84. data/lib/skylight/probes/middleware.rb +126 -0
  85. data/lib/skylight/probes/mongo.rb +164 -0
  86. data/lib/skylight/probes/mongoid.rb +13 -0
  87. data/lib/skylight/probes/net_http.rb +54 -0
  88. data/lib/skylight/probes/redis.rb +63 -0
  89. data/lib/skylight/probes/sequel.rb +33 -0
  90. data/lib/skylight/probes/sinatra.rb +63 -0
  91. data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
  92. data/lib/skylight/probes/tilt.rb +27 -0
  93. data/lib/skylight/railtie.rb +162 -18
  94. data/lib/skylight/sidekiq.rb +48 -0
  95. data/lib/skylight/subscriber.rb +110 -0
  96. data/lib/skylight/test.rb +146 -0
  97. data/lib/skylight/trace.rb +307 -10
  98. data/lib/skylight/user_config.rb +61 -0
  99. data/lib/skylight/util.rb +12 -0
  100. data/lib/skylight/util/allocation_free.rb +26 -0
  101. data/lib/skylight/util/clock.rb +56 -0
  102. data/lib/skylight/util/component.rb +5 -2
  103. data/lib/skylight/util/deploy.rb +7 -10
  104. data/lib/skylight/util/gzip.rb +20 -0
  105. data/lib/skylight/util/http.rb +4 -10
  106. data/lib/skylight/util/instrumenter_method.rb +26 -0
  107. data/lib/skylight/util/logging.rb +138 -0
  108. data/lib/skylight/util/lru_cache.rb +40 -0
  109. data/lib/skylight/util/platform.rb +1 -1
  110. data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
  111. data/lib/skylight/version.rb +5 -1
  112. data/lib/skylight/vm/gc.rb +68 -0
  113. metadata +126 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2bf022bf2ba25bb9f9769526a93435b154a91f313862d068fd7b976d50d1bbb
4
- data.tar.gz: b7e87b5ffd0f1ac492156103cb4c6dadb22e3b245b73ceaaa46ad2b3f1cce3a6
3
+ metadata.gz: 76c9ece1445d480897ecc306024fe939dacb94c14a02e68f7e33f5d722955284
4
+ data.tar.gz: 839b19ed8b3846003b3a54e5d0f3e327b0f969f2672b267dcaf4d1aa27df6254
5
5
  SHA512:
6
- metadata.gz: b8fb515ffaf327347fba911035032a1827d2f33f96b654da6be32a3296c97ca4a2f863e43215904e7bffa0c8c1addbfb2e20de78c78fab24d79f2d11856737af
7
- data.tar.gz: 0055467bc67cb145b1cbf2f30caa77d52a266e74fcc5f48b851ceffbb8736df2bfe7fd92a45f374547d06e3b4d5257e1738d1a7651374a19336a7b0ca7910377
6
+ metadata.gz: 2cbbcfd4a159b6abfa976f9d8ad4a87317973955d058408b681b1564d6d54bacadcb0e60c4bbac9ea03383dfed6d9355ac953a0b636c50a60ff99e52bcb3c5a2
7
+ data.tar.gz: b338f0d0a22d0b904600d050f217758d3b07c28e66c88c6f5eb961cd8701750b58a7175e3e9e31dad604c6c58c2d1b22197517c239192f41b9579c5c08a9ca5b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ ## 5.0.1 (March 11, 2021)
2
+ * [IMPROVEMENT] Use argument-forwarding (...) where available in custom instrumentation
3
+
4
+ ## 5.0.0 (March 5, 2021)
5
+
6
+ * [FEATURE] Add normalizer for Shrine events (thanks @janko!)
7
+ * [FEATURE] Source Locations detection and reporting is now enabled by default (can be disabled with `SKYLIGHT_ENABLE_SOURCE_LOCATIONS=false`)
8
+ * [FEATURE] Configuration for the Source Locations caches via `SYLIGHT_SOURCE_LOCATION_CACHE_SIZE`
9
+
10
+ * [IMPROVEMENT] Improve keyword argument handling in Skylight::Helpers (thanks @lukebooth!)
11
+ * [IMPROVEMENT] Replace a Kernel.puts with Skylight.log (thanks @johnnyshields!)
12
+ * [IMPROVEMENT] Various updates to the SQL lexer
13
+ * [IMPROVEMENT] Reduce volume of log messages sent to the native logger in debug level
14
+ * [IMPROVEMENT] Optimizations for the Source Locations extension
15
+ * [IMPROVEMENT] Improved Delayed::Job probe
16
+ * [IMPROVEMENT] Maintain method visibility when instrumenting with `instrument_method`
17
+ * [IMPROVEMENT] Update probes to use `Module#prepend` where possible
18
+ * [IMPROVEMENT] New tokio-based skylightd
19
+ * [IMPROVEMENT] Support `render_layout` notifications in Rails 6.1
20
+ * [IMPROVEMENT] Support `ActionMailer::MailDeliveryJob` in Rails 6.1
21
+ * [IMPROVEMENT] Better logging config. `SKYLIGHT_NATIVE_LOG_LEVEL` now defaults to `warn`.
22
+
23
+ * [BREAKING] Rename `environment` keyword argument to `priority_key`. Note `env` has not changed.
24
+ * [BREAKING] Drop support for Ruby 2.4
25
+ * [BREAKING] Merge skylight-core into skylight. All classes previously namespaced under `Skylight::Core` have been moved to `Skylight`.
26
+ * [BREAKING] Remove `Skylight::Util::Inflector`
27
+ * [BREAKING] Drop support for Rails 4
28
+ * [BREAKING] Drop support for Ruby 2.3
29
+
30
+ * [BUGFIX] Fix issue with missing metadata in MongoDB probe
31
+ * [BUGFIX] Resolve an inability to parse certain SQL queries containing arrays
32
+ * [BUGFIX] Allow multiple probes to be registered under the same key
33
+ * [BUGFIX] Do not refer to Redis constant until the probe is installed
34
+ * [BUGFIX] Fix nested calls to `Normalizers::Faraday::Request.disable`
35
+
1
36
  ## 4.3.2 (December 14, 2020)
2
37
  * [BUGFIX] Backport an ActionView fix from Skylight 5 (makes Skylight 4 compatible with Rails 6.1)
3
38
 
@@ -9,9 +44,6 @@
9
44
  * [IMPROVEMENT] Update Grape normalizer for version 1.3.1
10
45
  * [BUGFIX] Fix an issue where GraphQL normalizers could fail to load in non-Rails contexts
11
46
 
12
- ## 4.2.3 (March 10, 2020)
13
- * [BUGFIX] Fix an issue where the GraphQL probe may not always be installed
14
-
15
47
  ## 4.2.2 (February 25, 2020)
16
48
  * Support graphql-ruby version 1.10
17
49
 
data/CONTRIBUTING.md CHANGED
@@ -16,14 +16,8 @@ If you prefer to run tests in your own environment, you may do so as follows:
16
16
 
17
17
  ```shell
18
18
  # Select a gemfile and bundle install
19
- export BUNDLE_GEMFILE=$PWD/gemfiles/Gemfile.rails-5.2.x
19
+ export BUNDLE_GEMFILE=$PWD/gemfiles/rails-5.2.x/Gemfile
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
  ```
data/ext/extconf.rb CHANGED
@@ -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:
data/ext/libskylight.yml CHANGED
@@ -1,7 +1,8 @@
1
- version: "4.1.0-46806f5"
1
+ # commit: ea59cc7bdbbee0f69d1cf7e69827974a9ea67645
2
+ ---
3
+ version: "5.0.0-488d432"
2
4
  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"
5
+ x86-linux: "3c16b6db1508f35720258551783fbcd30fd231638bad316ea76748d659838399"
6
+ x86_64-linux: "94383aa3359c3f2e9c0e3c16ee263d46c5673dd255f8842e6acadf5ec3131c06"
7
+ x86_64-linux-musl: "d2e2e2e61c321315f9bcaa157426f33aef8ffc2330ba46b2cdcbd9442e65f728"
8
+ x86_64-darwin: "bcc925d0bcbae83a484f35dbc9729dcf262e1f3a8c29b8d387d0f58ad8f3afa3"
@@ -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,9 +470,24 @@ 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
 
@@ -525,71 +507,14 @@ trace_span_set_exception(VALUE self, VALUE span, VALUE exception, VALUE exceptio
525
507
  return Qnil;
526
508
  }
527
509
 
528
- static VALUE
529
- trace_span_get_correlation_header(VALUE self, VALUE span_id) {
530
- UNUSED(self);
531
- UNUSED(span_id);
532
- return Qnil;
533
- }
534
-
535
- static VALUE
536
- lex_sql(VALUE klass, VALUE rb_sql) {
537
- sky_buf_t sql;
538
- sky_buf_t title;
539
- sky_buf_t statement;
540
- uint8_t title_store[128];
541
- VALUE rb_statement;
542
- VALUE ret;
543
-
544
- UNUSED(klass);
545
- CHECK_TYPE(rb_sql, T_STRING);
546
-
547
- sql = STR2BUF(rb_sql);
548
- title = (sky_buf_t) {
549
- .data = title_store,
550
- .len = sizeof(title_store),
551
- };
552
-
553
- // The statement cannot be longer than the original sql string
554
- rb_statement = rb_str_buf_new(RSTRING_LEN(rb_sql));
555
- statement = (sky_buf_t) {
556
- .data = RSTRING_PTR(rb_statement),
557
- .len = RSTRING_LEN(rb_sql),
558
- };
559
-
560
- CHECK_FFI(sky_lex_sql(sql, &title, &statement),
561
- "Skylight#lex_sql");
562
-
563
- // Set the statement return
564
- rb_str_set_len(rb_statement, statement.len);
565
- rb_enc_associate(rb_statement, rb_utf8_encoding());
566
-
567
- ret = rb_ary_new2(2);
568
-
569
- if (title.len > 0) {
570
- rb_ary_store(ret, 0, BUF2STR(title));
571
- }
572
- else {
573
- rb_ary_store(ret, 0, Qnil);
574
- }
575
-
576
- rb_ary_store(ret, 1, rb_statement);
577
-
578
- return ret;
579
- }
580
-
581
510
  void Init_skylight_native() {
582
511
  rb_mSkylight = rb_define_module("Skylight");
583
512
 
584
513
  rb_eNativeError = rb_const_get(rb_mSkylight, rb_intern("NativeError"));
585
514
 
586
515
  rb_define_singleton_method(rb_mSkylight, "load_libskylight", load_libskylight, 1);
587
- rb_define_singleton_method(rb_mSkylight, "lex_sql", lex_sql, 1);
588
-
589
- rb_mCore = rb_define_module_under(rb_mSkylight, "Core");
590
516
 
591
- // FIXME: Don't put these under Core
592
- rb_mUtil = rb_define_module_under(rb_mCore, "Util");
517
+ rb_mUtil = rb_define_module_under(rb_mSkylight, "Util");
593
518
  rb_cClock = rb_define_class_under(rb_mUtil, "Clock", rb_cObject);
594
519
  rb_define_method(rb_cClock, "native_hrtime", clock_high_res_time, 0);
595
520
 
@@ -612,12 +537,10 @@ void Init_skylight_native() {
612
537
  rb_define_method(rb_cTrace, "native_span_set_meta", trace_span_set_meta, 2);
613
538
  rb_define_method(rb_cTrace, "native_span_started", trace_span_started, 1);
614
539
  rb_define_method(rb_cTrace, "native_span_set_exception", trace_span_set_exception, 3);
615
- rb_define_method(rb_cTrace, "native_span_get_correlation_header", trace_span_get_correlation_header, 1);
616
540
 
617
541
  rb_cInstrumenter = rb_const_get(rb_mSkylight, rb_intern("Instrumenter"));
618
542
  rb_define_singleton_method(rb_cInstrumenter, "native_new", instrumenter_new, 2);
619
543
  rb_define_method(rb_cInstrumenter, "native_start", instrumenter_start, 0);
620
544
  rb_define_method(rb_cInstrumenter, "native_stop", instrumenter_stop, 0);
621
545
  rb_define_method(rb_cInstrumenter, "native_submit_trace", instrumenter_submit_trace, 1);
622
- rb_define_method(rb_cInstrumenter, "native_track_desc", instrumenter_track_desc, 2);
623
546
  }
data/lib/skylight.rb CHANGED
@@ -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