skylight 4.3.2 → 5.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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -5
  3. data/CONTRIBUTING.md +1 -7
  4. data/ext/extconf.rb +4 -3
  5. data/ext/libskylight.yml +5 -6
  6. data/ext/skylight_native.c +22 -99
  7. data/lib/skylight.rb +204 -14
  8. data/lib/skylight/api.rb +7 -3
  9. data/lib/skylight/cli.rb +4 -3
  10. data/lib/skylight/cli/doctor.rb +3 -2
  11. data/lib/skylight/cli/merger.rb +6 -4
  12. data/lib/skylight/config.rb +603 -126
  13. data/lib/skylight/deprecation.rb +15 -0
  14. data/lib/skylight/errors.rb +17 -2
  15. data/lib/skylight/extensions.rb +99 -0
  16. data/lib/skylight/extensions/source_location.rb +249 -0
  17. data/lib/skylight/fanout.rb +0 -0
  18. data/lib/skylight/formatters/http.rb +19 -0
  19. data/lib/skylight/gc.rb +109 -0
  20. data/lib/skylight/helpers.rb +18 -2
  21. data/lib/skylight/instrumenter.rb +325 -15
  22. data/lib/skylight/middleware.rb +138 -1
  23. data/lib/skylight/native.rb +51 -1
  24. data/lib/skylight/native_ext_fetcher.rb +2 -1
  25. data/lib/skylight/normalizers.rb +151 -0
  26. data/lib/skylight/normalizers/action_controller/process_action.rb +69 -0
  27. data/lib/skylight/normalizers/action_controller/send_file.rb +50 -0
  28. data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
  29. data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
  30. data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
  31. data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
  32. data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
  33. data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
  34. data/lib/skylight/normalizers/active_job/perform.rb +81 -0
  35. data/lib/skylight/normalizers/active_model_serializers/render.rb +28 -0
  36. data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
  37. data/lib/skylight/normalizers/active_record/sql.rb +12 -0
  38. data/lib/skylight/normalizers/active_storage.rb +30 -0
  39. data/lib/skylight/normalizers/active_support/cache.rb +22 -0
  40. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  41. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  42. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  43. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  44. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  45. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  46. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  47. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  48. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  49. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  50. data/lib/skylight/normalizers/coach/handler_finish.rb +46 -0
  51. data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
  52. data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
  53. data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
  54. data/lib/skylight/normalizers/default.rb +32 -0
  55. data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
  56. data/lib/skylight/normalizers/faraday/request.rb +40 -0
  57. data/lib/skylight/normalizers/grape/endpoint.rb +34 -0
  58. data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
  59. data/lib/skylight/normalizers/grape/endpoint_run.rb +41 -0
  60. data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +22 -0
  61. data/lib/skylight/normalizers/grape/format_response.rb +20 -0
  62. data/lib/skylight/normalizers/graphiti/render.rb +22 -0
  63. data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
  64. data/lib/skylight/normalizers/graphql/base.rb +131 -0
  65. data/lib/skylight/normalizers/render.rb +81 -0
  66. data/lib/skylight/normalizers/sequel/sql.rb +12 -0
  67. data/lib/skylight/normalizers/sql.rb +44 -0
  68. data/lib/skylight/probes.rb +153 -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 +29 -0
  75. data/lib/skylight/probes/active_job_enqueue.rb +37 -0
  76. data/lib/skylight/probes/active_model_serializers.rb +54 -0
  77. data/lib/skylight/probes/delayed_job.rb +62 -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 +125 -0
  85. data/lib/skylight/probes/mongo.rb +163 -0
  86. data/lib/skylight/probes/mongoid.rb +13 -0
  87. data/lib/skylight/probes/net_http.rb +55 -0
  88. data/lib/skylight/probes/redis.rb +60 -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 +43 -0
  95. data/lib/skylight/subscriber.rb +110 -0
  96. data/lib/skylight/test.rb +146 -0
  97. data/lib/skylight/trace.rb +301 -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 +4 -4
  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 +42 -0
  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 +110 -11
@@ -0,0 +1,23 @@
1
+ require "skylight/normalizers/render"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionView
6
+ # Normalizer for Rails partial rendering
7
+ class RenderPartial < RenderNormalizer
8
+ register "render_partial.action_view"
9
+
10
+ CAT = "view.render.template".freeze
11
+
12
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
13
+ # @param name [String] ignored, only present to match API
14
+ # @param payload (see RenderNormalizer#normalize_render)
15
+ # @option payload (see RenderNormalizer#normalize_render)
16
+ # @return (see RenderNormalizer#normalize_render)
17
+ def normalize(_trace, _name, payload)
18
+ normalize_render(CAT, payload)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require "skylight/normalizers/render"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActionView
6
+ # Normalizer for Rails template rendering
7
+ class RenderTemplate < RenderNormalizer
8
+ register "render_template.action_view"
9
+
10
+ CAT = "view.render.template".freeze
11
+
12
+ # @param trace [Skylight::Messages::Trace::Builder] ignored, only present to match API
13
+ # @param name [String] ignored, only present to match API
14
+ # @param payload (see RenderNormalizer#normalize_render)
15
+ # @option payload (see RenderNormalizer#normalize_render)
16
+ # @return (see RenderNormalizer#normalize_render)
17
+ def normalize(_trace, _name, payload)
18
+ normalize_render(CAT, payload)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,81 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveJob
4
+ class Perform < Normalizer
5
+ register "perform.active_job"
6
+
7
+ DELIVERY_JOB = /\AActionMailer::(Mail)?DeliveryJob\Z/.freeze
8
+ DELAYED_JOB_WRAPPER = "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper".freeze
9
+
10
+ def self.normalize_title(job_instance)
11
+ job_instance.class.name.to_s.tap do |str|
12
+ if str.match(DELIVERY_JOB)
13
+ mailer_class, mailer_method, * = job_instance.arguments
14
+ return ["#{mailer_class}##{mailer_method}", str]
15
+ end
16
+ end
17
+ end
18
+
19
+ CAT = "app.job.perform".freeze
20
+
21
+ def normalize(trace, _name, payload)
22
+ title = payload[:job].class.to_s
23
+ adapter_name = normalize_adapter_name(payload[:adapter])
24
+ desc = "{ adapter: '#{adapter_name}', queue: '#{payload[:job].queue_name}' }"
25
+
26
+ maybe_set_endpoint(trace, payload)
27
+
28
+ [CAT, title, desc]
29
+ end
30
+
31
+ def normalize_after(trace, _span, _name, payload)
32
+ return unless config.enable_segments? && assign_endpoint?(trace, payload)
33
+
34
+ trace.segment = payload[:job].queue_name
35
+ end
36
+
37
+ private
38
+
39
+ def normalize_adapter_name(adapter)
40
+ adapter_string = adapter.is_a?(Class) ? adapter.to_s : adapter.class.to_s
41
+ adapter_string[/ActiveJob::QueueAdapters::(\w+)Adapter/, 1].underscore
42
+ rescue
43
+ "active_job"
44
+ end
45
+
46
+ def maybe_set_endpoint(trace, payload)
47
+ if assign_endpoint?(trace, payload)
48
+ trace.endpoint = normalize_title(payload[:job])
49
+ end
50
+ end
51
+
52
+ def assign_endpoint?(trace, payload)
53
+ # Always assign the endpoint if it has not yet been assigned by the ActiveJob probe.
54
+ return true unless trace.endpoint
55
+ return true if defined?(Skylight::Probes::ActiveJob::TITLE) &&
56
+ trace.endpoint == Skylight::Probes::ActiveJob::TITLE
57
+ return true if defined?(SKylight::Probes::DelayedJob::Probe::UNKNOWN) &&
58
+ trace.endpoint == Skylight::Probes::DelayedJob::Probe::UNKNOWN
59
+
60
+ # If a job is called using #perform_now inside a controller action
61
+ # or within another job's #perform method, we do not want this to
62
+ # overwrite the existing endpoint name (unless it is the default from ActiveJob).
63
+ #
64
+ # If the current endpoint name matches this payload, return true to allow the
65
+ # segment to be assigned by normalize_after.
66
+ trace.endpoint == DELIVERY_JOB ||
67
+ trace.endpoint == normalize_title(payload[:job]) ||
68
+ # This adapter wrapper needs to be handled specifically due to interactions with the
69
+ # standalone Delayed::Job probe, as there is no consistent way to get the wrapped
70
+ # job name among all Delayed::Job backends.
71
+ trace.endpoint == DELAYED_JOB_WRAPPER
72
+ end
73
+
74
+ def normalize_title(job_instance)
75
+ title, * = self.class.normalize_title(job_instance)
76
+ title
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,28 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveModelSerializers
4
+ class Render < Normalizer
5
+ register "render.active_model_serializers"
6
+
7
+ CAT = "view.render.active_model_serializers".freeze
8
+ ANONYMOUS = "<Anonymous Serializer>".freeze
9
+
10
+ def normalize(_trace, _name, payload)
11
+ serializer_class = payload[:serializer]
12
+
13
+ title = serializer_class.name || ANONYMOUS
14
+ title = title.sub(/^ActiveModel::(Serializer::)?/, "")
15
+
16
+ if (adapter_instance = payload[:adapter])
17
+ adapter_name = adapter_instance.class.name.to_s.
18
+ sub(/^ActiveModel::Serializer::Adapter::/, "").
19
+ sub(/^ActiveModelSerializers::Adapter::/, "")
20
+ desc = "Adapter: #{adapter_name}"
21
+ end
22
+
23
+ [CAT, title, desc]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveRecord
4
+ class Instantiation < Normalizer
5
+ register "instantiation.active_record"
6
+
7
+ CAT = "db.active_record.instantiation".freeze
8
+
9
+ def normalize(_trace, _name, payload)
10
+ # Payload also includes `:record_count` but this will be variable
11
+ [CAT, "#{payload[:class_name]} Instantiation", nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require "skylight/normalizers/sql"
2
+
3
+ module Skylight
4
+ module Normalizers
5
+ module ActiveRecord
6
+ # Normalizer for SQL requests
7
+ class SQL < Skylight::Normalizers::SQL
8
+ register "sql.active_record"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,30 @@
1
+ module Skylight
2
+ module Normalizers
3
+ class ActiveStorage < Normalizer
4
+ TITLES = {
5
+ "preview.active_storage" => "Preview",
6
+ "transform.active_storage" => "Transform",
7
+ "service_download.active_storage" => "Download",
8
+ "service_upload.active_storage" => "Upload",
9
+ "service_streaming_download.active_storage" => "Streaming Download",
10
+ "service_download_chunk.active_storage" => "Download Chunk",
11
+ "service_delete.active_storage" => "Delete",
12
+ "service_delete_prefixed.active_storage" => "Delete Prefixed",
13
+ "service_exist.active_storage" => "Exist",
14
+ "service_url.active_storage" => "Url"
15
+ }.freeze
16
+
17
+ TITLES.each_key do |key|
18
+ register key
19
+ end
20
+
21
+ def normalize(_trace, name, _payload)
22
+ title = ["ActiveStorage", TITLES[name]].join(" ")
23
+
24
+ cat = "app.#{name.split('.').reverse.join('.')}"
25
+
26
+ [cat, title, nil]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class Cache < Normalizer
5
+ %w[
6
+ clear
7
+ decrement
8
+ delete
9
+ exist
10
+ fetch_hit
11
+ generate
12
+ increment
13
+ read
14
+ read_multi
15
+ write
16
+ ].each do |type|
17
+ require "skylight/normalizers/active_support/cache_#{type}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheClear < Cache
5
+ register "cache_clear.active_support"
6
+
7
+ CAT = "app.cache.clear".freeze
8
+ TITLE = "cache clear".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheDecrement < Cache
5
+ register "cache_decrement.active_support"
6
+
7
+ CAT = "app.cache.decrement".freeze
8
+ TITLE = "cache decrement".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheDelete < Cache
5
+ register "cache_delete.active_support"
6
+
7
+ CAT = "app.cache.delete".freeze
8
+ TITLE = "cache delete".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheExist < Cache
5
+ register "cache_exist?.active_support"
6
+
7
+ CAT = "app.cache.exist".freeze
8
+ TITLE = "cache exist?".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheFetchHit < Cache
5
+ register "cache_fetch_hit.active_support"
6
+
7
+ CAT = "app.cache.fetch_hit".freeze
8
+ TITLE = "cache fetch hit".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheGenerate < Cache
5
+ register "cache_generate.active_support"
6
+
7
+ CAT = "app.cache.generate".freeze
8
+ TITLE = "cache generate".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheIncrement < Cache
5
+ register "cache_increment.active_support"
6
+
7
+ CAT = "app.cache.increment".freeze
8
+ TITLE = "cache increment".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheRead < Cache
5
+ register "cache_read.active_support"
6
+
7
+ CAT = "app.cache.read".freeze
8
+ TITLE = "cache read".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheReadMulti < Cache
5
+ register "cache_read_multi.active_support"
6
+
7
+ CAT = "app.cache.read_multi".freeze
8
+ TITLE = "cache read multi".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module ActiveSupport
4
+ class CacheWrite < Cache
5
+ register "cache_write.active_support"
6
+
7
+ CAT = "app.cache.write".freeze
8
+ TITLE = "cache write".freeze
9
+
10
+ def normalize(_trace, _name, _payload)
11
+ [CAT, TITLE, nil]
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ module Skylight
2
+ module Normalizers
3
+ module Coach
4
+ class HandlerFinish < Normalizer
5
+ begin
6
+ require "coach/version"
7
+ version = Gem::Version.new(::Coach::VERSION)
8
+ rescue LoadError # rubocop:disable Lint/SuppressedException
9
+ end
10
+
11
+ if version && version < Gem::Version.new("1.0")
12
+ register "coach.handler.finish"
13
+ else
14
+ register "finish_handler.coach"
15
+ end
16
+
17
+ CAT = "app.coach.handler".freeze
18
+
19
+ # See information on the events Coach emits here:
20
+ # https://github.com/gocardless/coach#instrumentation
21
+
22
+ # Run when the handler first starts, we need to set the trace endpoint to be the
23
+ # handler name.
24
+ #
25
+ # We can expect the payload to have the :middleware key.
26
+ def normalize(trace, _name, payload)
27
+ trace.endpoint = payload[:middleware]
28
+ [CAT, payload[:middleware], nil]
29
+ end
30
+
31
+ def normalize_after(trace, _span, _name, payload)
32
+ return unless config.enable_segments?
33
+
34
+ segments = []
35
+
36
+ response_status = payload.fetch(:response, {}).fetch(:status, "").to_s
37
+ segments << "error" if response_status.start_with?("4", "5")
38
+
39
+ if segments.any?
40
+ trace.segment = segments.join("+")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end